Excel ISTEXT alternative? - excel

I am currently building a numberplate checker on an excel spread sheet that will determine if the letters and numbers of the numberplate are in the correct places and are valid.
The 3 criteria I have are if the numberplates are in on of these formulas:
(I have represented a number as 1 and a letter as A)
AAA111A
A111AAA
AA11AAA
The ultimate objective is for the program to ask the question "Look at these number plates, do they follow a format as shown above."
So far I have only been able to check to see if I have numbers in certain places, however I cannot specify the characters A - Z when trying to do a search function from the left, right and centre.
=ISNUMBER(--MID(A3,1,3))
If I wanted to search within a cell for example, the first character, is it a letter a-z, return true or false? How would I go about doing this?
An example in this instance might be:
DJO148R
The formula
=ISNUMBER(--MID(A5,4,3))
This would turn back as true because the 4th character is a number and so are the next 2.
With the same numberplate, how do I change it to search for letters rather than numbers within the numberplate?

Here is a simpler RegEx implementation. Make sure you include references to Microsoft VBScript Regular Expressions 5.5. This will go in a new inserted module
Function PlateCheck(cell As Range) As Boolean
Dim rex As New RegExp
rex.Pattern = "[A-Z][0-9|A-Z][0-9|A-Z][0-9|A-Z][0-9|A-Z][0-9|A-Z][A-Z]"
If rex.Test(cell.Value) Then
PlateCheck = True
Else
PlateCheck = False
End If
End Function

As per the guys comments, here's how you do it with regex:
Make sure to include MS VB regular expressions 5.5 as a reference.
To do that, in your VBA IDE, go Tools, Reference and then look the regex reference.
Then Add this in a new module:
Function VerifyLicensePlate(ip As Range) As String
Dim regex As New RegExp
Dim inputstr As String: inputstr = ip.Value
With regex
.Global = True
.IgnoreCase = True
End With
Dim strpattern(2) As String
strpattern(0) = "[A-Z][A-Z][A-Z][0-9][0-9][0-9][A-Z]"
strpattern(1) = "[A-Z][A-Z][0-9][0-9][A-Z][A-Z][A-Z]"
strpattern(2) = "[A-Z][0-9][0-9][0-9][A-Z][A-Z][A-Z]"
For i = 0 To 2
regex.pattern = strpattern(i)
If regex.Test(inputstr) Then
VerifyLicensePlate = "Match"
Exit Function
Else
VerifyLicensePlate = "No match"
End If
Next
End Function
Output:

Occam's Razor would suggest,
=NOT(ISNUMBER(--MID(A5,4,3)))
... or,
=ISERROR(--MID(A5,4,3))

Here's a version that uses late-binding, so no need to set a reference. IT is case insensitive, as that seemed to be implied in your question, but that is easily changed.
Option Explicit
Function MatchPattern(S As String) As Boolean
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.Pattern = "\b(?:[A-Z]{3}\d{3}[A-Z]|[A-Z]{2}\d{2}[A-Z]{3}|[A-Z]\d{3}[A-Z]{3})\b"
.ignorecase = True
MatchPattern = .test(S)
End With
End Function
But, as pointed out by G Serg, you don't really need regex for this:
Option Explicit
Option Compare Text 'Case Insensitive
Function MatchPattern(S As String) As Boolean
Const S1 As String = "[A-Z][A-Z][A-Z]###[A-Z]"
Const S2 As String = "[A-Z]###[A-Z][A-Z][A-Z]"
Const S3 As String = "[A-Z][A-Z]##[A-Z][A-Z][A-Z]"
MatchPattern = False
If Len(S) = 7 Then
If S Like S1 Or _
S Like S2 Or _
S Like S3 Then _
MatchPattern = True
End If
End Function
Here is a rather complicated formula that seems to match your specifications:
=AND(LEN(A1)=7,
OR(MMULT(--(CODE(MID(A1,{1,2,3,4,5,6,7},1))>64),--(TRANSPOSE(CODE(MID(A1,{1,2,3,4,5,6,7},1))<91)))={4,5}),
CODE(LEFT(A1,1))>64,CODE(LEFT(A1,1))<91,
CODE(RIGHT(A1,1))>64,CODE(RIGHT(A1,1))<91,
ISNUMBER(-MID(A1,MIN(FIND({1,2,3,4,5,6,7,8,9,0},A1&"0123456789")),
7-MMULT(--(CODE(MID(A1,{1,2,3,4,5,6,7},1))>64),--(TRANSPOSE(CODE(MID(A1,{1,2,3,4,5,6,7},1))<91))))))
Ensure we have only seven characters
The OR(MMULT... function counts the number of letters and returns TRUE if four or five.
Check to make sure first and last character is a letter
There should remain a consecutive string of either two or three digits (seven less the number of letters)
If you want to make the formula case insensitive, replace the instances of A1 with UPPER(A1)
I think the UDF solution is better.

Related

Remove characters A-Z from string [duplicate]

This question already has answers here:
Extracting digits from a cell with varying char length
(4 answers)
Closed 2 years ago.
I need to be able to remove all alphabetical characters from a string, leaving just the numbers behind.
I don't need to worry about any other characters like ,.?# and so on, just the letters of the alphabet a-z, regardless of case.
The closest I could get to a solution was the exact opposite, the below VBA is able to remove the numbers from a string.
Function removenumbers(ByVal input1 As String) As String
Dim x
Dim tmp As String
tmp = input1
For x = a To Z
tmp = Replace(tmp, x, "")
Next
removenumbers = tmp
End Function
Is there any modification I can make to remove the letters rather than numbers to the above, or am I going at this completely wrong.
The letters could fall anywhere in the string, and there is no pattern to the strings.
Failing this I will use CTRL + H to remove all letters one by one, but may need to repeat this again each week so UDF would be much quicker.
I'm using Office 365 on Excel 16
Option Explicit
dim mystring as String
dim regex as new RegExp
Private Function rgclean(ByVal mystring As String) As String
'function that find and replace string if contains regex pattern
'returns str
With regex
.Global = True ' return all matches found in string
.Pattern = "[A-Z]" ' add [A-Za-z] if you want lower case as well the regex pattern will pick all letters from A-Z and
End With
rgclean = regex.Replace(mystring, "") '.. and replaces everything else with ""
End Function
Try using regular expression.
Make sure you enable regular expression on: Tools > References > checkbox: "Microsoft VBScript Regular Expressions 5.5"
The function will remove anything from [A-Z], if you want to include lower case add [A-Za-z] into the regex.pattern values. ( .Pattern = "[A-Za-z]")
You just pass the string into the function, and the function will use regular expression to remove any words from in a string
Thanks

Is there an easy way to check if the string starts with letters (any 4 letters)?

is there a way to check if the string begins with any 4 letters. I am looking for something like this:
If string like "####*" then
'DO STUFF
end if
"#" is for digits, I need the same thing but for letters only.
Can this be done without regEx?
I don't know a way to do this without using regular expressions. We can try using regex Test along with the pattern ^[A-Z]{4}.*$:
Dim input As String
Dim regex As Object
Set regex = New RegExp
regex.Pattern = "^[A-Z]{4}.*$"
input = "ABCD blah"
If regex.Test(input) Then
'DO STUFF
End If
You can do it with Like almost the same as with RegEx.
"{#}" - doesn't exist in Like operators, but "[A-Z]" absolutely valid
if string like "[A-Z][A-Z][A-Z][A-Z]*" then
'DO STUFF
end if
Can this be done without regEx?
Yes, there is no specific need for Regular Expressions since the Like operator is quite capable as some sort of last resort to handle the situation, just like the writer of this article explains. Also, RegEx is sort of slow on a larger database. Nonetheless, RegEX is a great tool to use!
The solution provided by #AlexandruHapco would tell you if the string starts with 4 capital letters. But to account for lower OR upper, you can extend this logic:
If str Like "[a-zA-Z][a-zA-Z][a-zA-Z][a-zA-Z]*" Then
However, to shorten this a bit we can use [!charlist] to tell the operator we are looking for something that is NOT in the provided range. In other words, we could use:
If str Like "[!0-9][!0-9][!0-9][!0-9]*" Then
This last solution won't work when your string has any other characters than alphanumeric ones.
Approach using the FilterXML function
The WorksheetFunction FilterXML() has been added in ►Excel 2013 and allows to specify any XPath search string for a given XML document, which hasn't to be a locally saved file (needing WebService() function), but can be a string within well formed opening and closing nodes, i.e. our test string with some easy node additions (partly comparable to a html structure).
Example call
Sub TextXML()
Dim myString As String
myString = "ABCD blah"
If check(myString) Then
'DO STUFF
Debug.Print "okay"
Else
Debug.Print "oh no"
End If
End Sub
Help function
Function check(ByVal teststring As String) As Boolean
Const s As String = Chr(185) ' unusual character, e.g. Chr(185): "¹"
On Error GoTo oops
If Len(WorksheetFunction.FilterXML("<all><i>" & teststring & "</i></all>", "//i[substring(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','" & _
String(26, s) & "'),1,4)='" & String(4, s) & "']")) > 0 Then check = True
Exit Function
oops:
Err.Clear
End Function
tl;tr - how to use VBA in Excel versions before 2013
For the sake of the art the classic way to use XPath via XMLDOM methods:
Example call
Sub TextXML2()
Dim myString As String
myString = "ABCD blah"
If check2(myString) Then
'DO STUFF
Debug.Print "okay"
Else
Debug.Print "oh no"
End If
End Sub
Help functions
Function check2(ByVal teststring As String) As Boolean
' Purpose: check if first 4 characters of a test string are upper case letters A-Z
' [0] late bind XML document
Dim xDoc As Object
Set xDoc = CreateObject("MSXML2.DOMDocument.6.0")
' [1] form XML string by adding opening and closing node names ("tags")
teststring = "<all><i>" & teststring & "</i></all>"
' [2] load XML
If xDoc.LoadXML(teststring) Then
' [3a] list matching item(s) via XPath
Dim myNodeList As Object
Set myNodeList = xDoc.SelectNodes(XPath())
'Debug.Print teststring, " found: " & myNodeList.Length
' [3b] return true if the item matches, i.e. the list length is greater than zero
If myNodeList.Length > 0 Then check2 = True
End If
End Function
Function XPath() As String
' Purpose: create XPath string to get nodes where the first 4 characters are upper case letters A-Z
' Result: //i[substring(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹'),1,4)="¹¹¹¹"]
' get UPPER case alphabet
Const ABC As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
' define replacement string consisting of an unusual character repeated 26 times
Const UNUSUAL As String = "¹" ' << replace by your preferenced character
Dim replacement As String: replacement = String(Len(ABC), UNUSUAL)
'return XPath string
XPath = "//i[substring(translate(.,'" & ABC & "','" & replacement & "'),1,4)=""" & String(4, UNUSUAL) & """]"
End Function
To test a few characters -- the first 4 letters in this case -- you can always do the following:
If Not (Mid(string, 1, 1) Like "#" And Mid(string, 2, 1) Like "#" _
And Mid(string, 3, 1) Like "#" And Mid(string, 4, 1) Like "#") Then
' DO STUFF
End If
It's a bit more to type then when using the Like operator, but so what? Also, you can use Select Case in a loop...
Another option is to use IsNumeric(Mid(string, i, 1)) instead of Mid(string, i, 1) Like "#", etc.
Granted, this approach is still quite practical with 4 characters, but is not as flexible and very much not scalable like RegEx is.

How to get string in between two characters in excel/spreadsheet

I have this string
Weiss,Emery/Ap #519-8997 Quam. Street/Hawaiian Gardens,IN - 79589|10/13/2010
how do I get the Hawaiian Gardens only?
I already tried Using some
=mid(left(A1,find("/",A1)-1),find(",",A1)+1,len(A1))
it gives me emery instead
If there are always two slashes before the string you want to extract, based onTyler M's answer you can use this
=MID(E1,
FIND("~",SUBSTITUTE(E1,"/","~",2))+1,
FIND(",",RIGHT(E1,LEN(E1)-FIND("~",SUBSTITUTE(E1,"/","~",2))))-1
)
This substitutes the second occurence of / with a character which normally would not occur in the address, thus making it findable.
Was your intention to also include Google Spreadsheets (looking at your title)? If so,you can use the REGEXEXTRACT() function. For example in B1
=REGEXEXTRACT(A1,"\/([\w\s]*)\,")
In Excel you could build a UDF using this regex rule like so (as an example):
Function REGEXEXTRACT(S As String, PTRN As String) As String
'We will get the last possible match in your string...
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
With regex
.Pattern = PTRN
.Global = True
End With
Set matches = regex.Execute(S)
For Each Match In matches
If Match.SubMatches.Count > 0 Then
For Each subMatch In Match.SubMatches
REGEXEXTRACT = subMatch
Next subMatch
End If
Next Match
End Function
Call the function in B1 like so:
=REGEXEXTRACT(A1,"\/([\w\s]*)\,")

excel formula find part number in file path text string

I have a extract of all the files on a network drive, and in the some file names is a part number, the part numbers format is 0000-000000-00. Now in the 600,000+ path names in this file I'm trying to figure out how to extract my part numbers out of the path names. I think a mid formula might work but I am at a loss on how to tell it to find anything with the part # format 0000-000000-00 and extract only those 14 characters from the path?
input looks like this
c:\users\stuff\folder_name\1234-000001-01_ baskets_1.pdf
c:\users\stuff\folder_name\1234-000001-02_ baskets_2.pdf
c:\users\stuff\folder_name\1234-000001-03_ baskets_3.pdf
c:\users\stuff\folder_name\1234-000030-01_ tree_30.pdf
c:\users\stuff\folder_name\random text_1234-000030-02_ tree_30.pdf
c:\users\stuff\folder_name\more random stuff_1234-000030-02_ tree_30.pdf
output I'm hoping for
1234-000001-01
1234-000001-02
1234-000001-03
1234-000030-01
Since you have a pattern we can exploit, use this:
=MID(A1,SEARCH("????-??????-??",A1),14)
Finds the start of the pattern and returns the 14 character after.
You wanted a formula but a UDF could also be used to apply a regex to get the pattern (a little overkill in this instance but worth being aware of):
Option Explicit
Public Sub GetCustomString()
Dim i As Long, tests()
tests = Array("c:\users\stuff\folder_name\1234-000001-01_ baskets_1.pdf", _
"c:\users\stuff\folder_name\1234-000001-02_ baskets_2.pdf", _
"c:\users\stuff\folder_name\1234-000001-03_ baskets_3.pdf", _
"c:\users\stuff\folder_name\1234-000030-01_ tree_30.pdf", _
"c:\users\stuff\folder_name\random text_1234-000030-02_ tree_30.pdf", _
"c:\users\stuff\folder_name\more random stuff_1234-000030-02_ tree_30.pdf")
For i = LBound(tests) To UBound(tests)
Debug.Print GetString(tests(i))
Next
End Sub
Public Function GetString(ByVal inputString As String) As String
Dim arr() As String, i As Long, matches As Object, re As Object
Set re = CreateObject("VBScript.RegExp")
With re
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "\d{4}-\d{6}-\d{2}"
If .test(inputString) Then
GetString = .Execute(inputString)(0)
Else
GetString = vbNullString
End If
End With
End Function
Using UDF in sheet:
Pattern: \d{4}-\d{6}-\d{2}
Explanation:
\d{4} matches a digit (equal to [0-9])
{4} Quantifier — Matches exactly 4 times
"-" matches the character - literally (case sensitive)
\d{6} matches a digit (equal to [0-9])
{6} Quantifier — Matches exactly 6 times
"-" matches the character - literally (case sensitive)
\d{2} matches a digit (equal to [0-9])
{2} Quantifier — Matches exactly 2 times
Global pattern flags:
g modifier: global. All matches (don't return after first match)
m modifier: multi line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)

Excel 2007 find the largest number in text string

I have Excel 2007. I am trying to find the largest number in a cell that contains something like the following:
[[ E:\DATA\SQL\SY0\ , 19198 ],[ E:\ , 18872 ],[ E:\DATA\SQL\ST0\ , 26211 ],[ E:\DATA\SQL\ST1\ , 26211 ],[ E:\DATA\SQL\SD0\ , 9861 ],[ E:\DATA\SQL\SD1\ , 11220 ],[ E:\DATA\SQL\SL0\ , 3377 ],[ E:\DATA\SQL\SL1\ , 1707 ],[ E:\DATA\SQL_Support\SS0\ , 14375 ],[ E:\DATA\SQL_Support\SS1\ , 30711 ]]
I am not a coder but I can get by with some basic instructions. If there is a formula that can do this, great! If the best way to do this is some sort of backend code, just let me know. Thank you for your time.
I do have the following formula that almost gets me there:
=SUMPRODUCT(MID(0&A2,LARGE(INDEX(ISNUMBER(--MID(A2,ROW(INDIRECT("1:"&LEN($A$2))),1))*ROW(INDIRECT("1:"&LEN($A$2))),0),ROW(INDIRECT("1:"&LEN($A$2))))+1,1)*10^ROW(INDIRECT("1:"&LEN($A$2)))/10)
With a cell that contains a string like above, it will work. However, with a string that contains something like:
[[ E:\DATA\SQL\SY0\ , 19198.934678 ],[ E:\ , 18872.2567 ]]
I would end up with the value of 19198934678 as the largest value.
You can use this UDF:
Function MaxInString(rng As String) As Double
Dim splt() As String
Dim i&
splt = Split(rng)
For i = LBound(splt) To UBound(splt)
If IsNumeric(splt(i)) Then
If splt(i) > MaxInString Then
MaxInString = splt(i)
End If
End If
Next i
End Function
Put this in a module attached to the workbook. NOT in the worksheet or ThisWorkbook code.
Then you can call it like any other formula:
=MaxInString(A1)
If there is always a space before and after, you can use this formula. The formula is an array formula and must be confirmed by holding down ctrl + shift while hitting enter
With your string in A1:
=MAX(IFERROR(--TRIM(MID(SUBSTITUTE(A1," ",REPT(" ",99)),IF(seq=1,1,(seq-1)*99),99)),0))
seq is a defined name that refers to:
=ROW(INDEX(Sheet1!$1:$65536,1,1):INDEX(Sheet1!$1:$65536,255,1))
If a VBA UDF is preferable, I suggest the following. The Regex will match anything that might be a number. The number is expected to be in the format of iiii.dddd The integer part and the decimal point are both optional.
Option Explicit
Function LargestNumberFromString(S As String) As Double
Dim RE As Object, MC As Object, M As Object
Dim D As Double
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.Pattern = "\b[0-9]*\.?[0-9]+\b"
If RE.test(S) = True Then
For Each M In MC
D = IIf(D > CDbl(M), D, CDbl(M))
Next M
End If
End With
End Function
This is going to be a rather complex answer for someone with no programming background, so be prepared to spend a lot of time covering and researching this topic if you really wish to achieve a function that finds the largest number in a string in excel.
The solution, requires the use of VBA and Regular expressions
VBA is used in excel when there is a need for more complex functionality that just can't be achieved with the use of built in spreadsheet functions.
Regular expressions are a language used to tell programs how to extract useful information from texts, in this case we can extract all the numbers in your text. with the following regular expression.
(\d+.?\d*)/g
Which roughly means: Match one or more digits with an optional period and subsequent optional digits.
The program that will interpret this will do the following: Look for digits, if you see one, then that's a match, grab all contiguous digits and add them to the match. Once you find a character that is not a digit, start looking for new matches. if at any point you find a dot, add it to the match, but just once, and keep on looking for digits. Rinse and repeat until the end of the text.
You can test it here. In this case, the regex matches 19 numbers.
http://www.regextester.com/
Once you have a collection with the 19 matches (See link to regular expressions), all you would need to do is to loop over each of the matches to find out which of the numbers is the highest:
for each number in matches
if number > highestNumber then
highestNumber = number
end if
next
And highestNumber will be the the result! In order to have this code run in a simple custom function, you can follow this microsoft tutorial ( https://support.office.com/en-us/article/Create-Custom-Functions-in-Excel-2007-2f06c10b-3622-40d6-a1b2-b6748ae8231f?ui=en-US&rs=en-US&ad=US&fromAR=1 )
Where c is your string to find max from
Dim qwe() As String
qwe = Split(c, ", ")
maxed = 0
For x = LBound(qwe) To UBound(qwe)
qwe(x) = Left(qwe(x), InStr(1, qwe(x), " ", vbBinaryCompare))
On Error Resume Next
If CLng(qwe(x)) > maxed Then maxed = CLng(qwe(x))
Next x
MsgBox maxed
The error line is there to ignore when qwe(x) cannot be converted to a LONG number.
I must say this is very specific to your string format, for a more comprehensive doodad you'd want to have the split delimiter as a variable and possibly use the "IsNumeric" function to scan the entire string.

Resources