VBA - Find certain strings in a worksheet - string

I want to create either a macro or a UDF that can find cells in an excel worksheet that contains the following:
POxxx
PO xxxxxxx
PO# xxxxx
PO#xxxx
(With x being numbers)
The string could be at the start or the middle of cells.
In addition, the function/macro should not find cells that contain entries like CORPORATE, where PO is part of a word.
All the cells that contains qualifying data, should be highlighted.

This small UDF will return 1 is the match is present, otherwise 0
Public Function IsItThere(r As Range) As Long
Dim st As String
st = "0,1,2,3,4,5,6,7,8,9"
ary = Split(st, ",")
st = r.Text
IsItThere = 1
For Each a In ary
If InStr(1, st, "PO" & a) > 1 Then Exit Function
If InStr(1, st, "PO " & a) > 1 Then Exit Function
If InStr(1, st, "PO#" & a) > 1 Then Exit Function
If InStr(1, st, "PO# " & a) > 1 Then Exit Function
Next a
IsItThere = 0
End Function
You could also use Regular Expressions to find the pattern.

Try this:
Sub Tester()
Dim c As Range
For Each c In Selection.Cells
c.Interior.Color = IIf(RegexpTest(c.Value), vbRed, vbGreen)
Next c
End Sub
Function RegexpTest(v As String)
Static re As Object 'note static: you must reset the VB environment
' (press the "stop" button) if you edit the
' Pattern below
If re Is Nothing Then
Set re = CreateObject("VBScript.RegExp")
'"PO" then optional #, optional space, then 2-5 digits
re.Pattern = "PO#?\s?\d{2,5}"
re.ignorecase = True
End If
RegexpTest = re.test(v)
End Function

Related

Excel VBA: "Change a Subroutine into a Function", for String Conversion

Through my work, and copying others, I have cobbled together a Excel VBA Sub that separates a long sting with groups of (text groups) and (number groups) into a replacement string with spaces in between each seperate group; as per this example:
• “123abc12aedsw2345der”
• …Apply selection Sub() then becomes:
• “123 abc 12 aedsw 2345 der”
It converts the string in its original cell as per the “selection”, so I am currently left with the altered data in is original cell
PROBLEM: I would like to change this into a FUNCTION where the transformed data would appear in the Function cell and leave the original cell intact. I have done hundreds of these but I cannot seem to get this to work as an independent FUNCTION. Below the finished and working Sub Routine I am trying to convert to an independent function to call from anywhere on the worksheet:
Sub SplitTextNumbersSelection()
Dim c As Range
'********** Inserts Space Before Number Groups ******************************
For n = 1 To 10
For Each c In Selection
c = InsertSpace(c.Text)
Next
Next n
'****************Inserts Space Before Letter Groups ***********************
For n = 1 To 10
For Each c In Selection
c = InsertSpace2(c.Text)
Next
Next n
'****************************************
End Sub
Function InsertSpace(str As String) As String
With CreateObject("vbscript.regexp")
.Pattern = "([a-z])(\d)"
'.Pattern = "(\d)([a-z])"
InsertSpace = .Replace(str, "$1 $2")
End With
End Function
Function InsertSpace2(str As String) As String
With CreateObject("vbscript.regexp")
'.Pattern = "([a-z])(\d)"
.Pattern = "(\d)([a-z])"
InsertSpace2 = .Replace(str, "$1 $2")
End With
End Function
Bit simpler:
Function PrepString(v As String)
Dim rv As String, i As Long, c1, c2
For i = 1 To Len(v) - 1
c1 = Mid(v, i, 1)
c2 = Mid(v, i + 1, 1)
If (c1 Like "[a-z]" And c2 Like "[0-9]") Or _
(c2 Like "[a-z]" And c1 Like "[0-9]") Then
rv = rv & c1 & " "
Else
rv = rv & c1
End If
Next i
PrepString = rv & Right(v, 1)
End Function

How to remove leading zeros from alphanumeric text in excel

One of my cell column in Excel looks like this:
00071331
000062KV
00008M01
00009R22
001N5350
12345678
00123456
I want to remove all the leading zeros. The output should look like this:
71331
62KV
8M01
9R22
1N5350
12345678
123456
I have tried using Flash fill in excel but it is not picking up the pattern.
Use MID,AGGREGATE:
=MID(A1,AGGREGATE(15,7,ROW($1:$8)/(MID(A1,ROW($1:$8),1)<>"0"),1),8)
Because you tagged VBA, try:
Sub NoZero()
Dim r As Range, v As String
For Each r In Range("A:A")
v = r.Text
If v = "" Then Exit Sub
While Left(v, 1) = "0"
v = Mid(v, 2, Len(v))
Wend
r.Value = v
Next r
End Sub
This will perform the conversion "in-place", without the need of a "helper column".
I think in your case you could use:
=MID(A1,FIND(LEFT(SUBSTITUTE(A1,"0",""),1),A1),8)
Or an array formula like:
=MID(A1,MATCH(TRUE,MID(A1,ROW($1:$8),1)<>"0",0),8)
Or if you don't want to enter it as array formula:
=MID(A1,MATCH(TRUE,INDEX(MID(A1,ROW($1:$8),1)<>"0",),0),8)
Same as #Gary's Student, but with minor changes: working not with column A, but with the current selection; in a string of the form 0000, not all zeros are removed, but only leading ones, etc.
Sub NoZeroAnywhere()
Dim r As Range, v As String
Rem Work with all selected cells
If TypeName(Selection) <> "Range" Then Exit Sub
For Each r In Selection.Cells
v = r.Text
If v <> "" Then ' Don't break loop on empty cell
Rem Condition Len(v)>1 prevent remove all zeros, 0000 will be 0, not empty string
While Len(v) > 1 And Left(v, 1) = "0"
v = Right(v, Len(v) - 1)
Wend
r.Value = v
End If
Next r
End Sub
You could also do it as UDF using regex:
Function RemoveLeadingZeroes(stringOne As String) As String
Dim regexOne As Object
Set regexOne = New RegExp
regexOne.Pattern = "^0*"
RemoveLeadingZeroes = regexOne.Replace(stringOne, "")
End Function
Note: Have to enable Tools>References>Microsoft VBScript Regular Expressions in VBA editor.

Excel Macro to add HTML Bold tags 'breaks' at 240 character mark [duplicate]

It is really impossible to append more than 255 chars into a single cell by VBA macro in MS Excel?
Sample code:
Option Explicit
Sub TestSub()
Dim L As Long
' Const str = "1" & vbLf
Dim i As Integer
Range("A1").ClearContents
Range("A1").WrapText = True
For i = 1 To 260 ' any number greatest than 255
L = Range("A1").Characters.Count
Debug.Print L
Range("A1").Characters(L + 1, 1).Insert ("A")
Next i
End Sub
Added:
It is important to save previous formatting of chars in cell.
The following code will write 500 A into cell A1. Afterwards, every other A will be formatted bold.
Public Sub tmpSO()
For i = 1 To 500
Range("A1").Value = Range("A1").Value & "A"
Next i
For i = 1 To 500
If i Mod 2 = 0 Then Range("A1").Characters(i, 1).Font.Bold = True
Next i
End Sub
I hope that solves your problem.
Note: your code won't work because you are trying to insert a character after L + 1. Yet, your string is currently only L long and not L + 1. Once you have inserted another A you will have L + 1 characters in that cell. But not yet. So, if you are using your code with Range("A1").Characters(L, 1).Insert ("A") then it will work.
Edit#1:
The following code has been tested and correctly inserts 500 A into cell A1. Furthermore, some of the A will be formatted bold.
Sub TestSub()
Dim i As Integer
Range("A1").ClearContents
Range("A1").WrapText = True
Range("A1").Font.Bold = False
For i = 1 To 500
Range("A1").Characters(i, 1).Insert ("A")
Next i
For i = 1 To 500 Step 10
Range("A1").Characters(i, 3).Font.Bold = True
Next i
End Sub
question changed with this additional comment
https://stackoverflow.com/users/4742533/stayathome
will return and update this
initial answer
You can format the partial string using characters.
Code below appends your sample string to test string (300 characters long), then makes the last three italic, the three before that bold.
Sub LikeThis()
Dim StrIn As String
StrIn = "aaaabbbccc"
[a1] = Application.Rept("xyz", 100)
[a1].Value2 = [a1].Value2 & StrIn
[a1].Characters(Len([a1]) - 5, 3).Font.Bold = True
[a1].Characters(Len([a1]) - 2, 3).Font.Italic = True
End Sub

Deleting everything after the second occurrence of a number

Quick question, if I want to delete everything after the second occurrence of a number:
i.e -
I have:
1105 Bracket Ave. Suite 531 Touche
5201 Used St. 1351 Bored Today
I want:
1105 Bracket Ave. Suite 531
5201 Used St. 1351
is there a simple formula or VBA I would use for this?
Here is a UDF using VBA's regular expression engine to remove all after the second integer.
Option Explicit
Function FirstTwoNumbers(S As String) As String
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Pattern = "(\d+\D+\d+).*"
FirstTwoNumbers = .Replace(S, "$1")
End With
End Function
If there is only a single integer, it will return the entire string.
If the numbers might be decimal numbers, will need to modify .Pattern
And here is another UDF using only native VBA methods:
Function FirstTwo(S As String) As String
Dim V
Dim tS As String
Dim I As Long, numNumbers As Long
V = Split(S)
Do Until numNumbers = 2
tS = tS & Space(1) & V(I)
I = I + 1
If IsNumeric(V(I - 1)) Then numNumbers = numNumbers + 1
Loop
FirstTwo = Mid(tS, 2)
End Function
and finally, a formula with no particular assumptions:
=LEFT(A1,FIND(CHAR(1),SUBSTITUTE(A1," ",CHAR(1),LOOKUP(2,1/ISNUMBER(-TRIM(MID(SUBSTITUTE(A1," ",REPT(" ",99)),seq_99,99))),seq))))
seq and seq99 are Named Formulas Formula ► Define Name
seq Refers to: =ROW(INDEX($1:$255,1,1):INDEX($1:$255,255,1))
seq_99 Refers to: =IF(ROW(INDEX($1:$255,1,1):INDEX($1:$255,255,1))=1,1,(ROW(INDEX($1:$255,1,1):INDEX($1:$255,255,1))-1)*99)
This solution is with these assumptions:-
First occurrence of a number will not have a length > 10
There will atleast a distance of 10 or 10 alphabets including spaces between first and second number
There will always be a 'space' existing after second number
There will always be a second number present in the string
Try this:-
=TRIM(MID(A1,1,FIND(" ",A1,MIN(FIND({0,1,2,3,4,5,6,7,8,9},A1&"0123456789",MIN(FIND({0,1,2,3,4,5,6,7,8,9},A1&"0123456789"))+10)))))
Here is a VBA approach, amend range to suit. It puts the answer in the adjacent column
Sub x()
Dim oMatches As Object, r As Range
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "\d+"
For Each r In Range("A1:A5")
If .Test(r) Then
Set oMatches = .Execute(r)
If oMatches.Count > 1 Then
r.Offset(, 1).Value = Left(r, oMatches(1).firstindex + oMatches(1).Length)
Else
r.Offset(, 1).Value = r.Value
End If
Else
r.Offset(, 1).Value = r.Value
End If
Next r
End With
End Sub
You can use the following formula,if A1 is your string,in B1 write:
=LEFT(A1,MAX(IFERROR(ISNUMBER(VALUE(MID(A1,ROW(INDIRECT("1:"&LEN(A1))),1)))*ROW(INDIRECT("1:"&LEN(A1))),0)))
press Ctrl+Shift+Enter at the same time Array Formula
This will read the length of the string and return the Maximum place of numbers (last number in the string) and return the Left() string till this number

excel macros checking for value and moving to cell below

so Ive got programming knowledge but i need help with excel
i need to create a macro that checks for a specific value in a cell (e.g. begins with "01A") and if it finds it to check the cell underneath it for the same value. It should keep doing that until the value changes. I would also like it to calculate how many times it found that specific value (counta())
here is an example i would use if i were to do something similar in c
if (value = 01a){
amount ++
value + 1
}
any help is greatly appreciated
If you need to search only the first occurrance in a range, use:
Public Function FoundRec(Str As String, x As Range) As Integer
Application.Volatile
Dim i As Integer
Set c = x.Find(Str, after:=x.Item(x.Rows.Count), LookIn:=xlValues)
If c Is Nothing Then
FoundRec = 0
Exit Function
End If
For i = 1 To 9999
If c.Offset(i, 0).Value <> c.Value Then Exit For
Next
FoundRec = i
End Function
This function search the string Str in the range x :
=FoundRec("01A";A2:A16)
Return 0 if don't found.
If you need to search in the other occurrance, you can use:
Public Function FoundRecR(Str As String, x As Range, StartR As Integer) As Single
Application.Volatile
Dim i, e As Integer
Dim xx As Range
Set xx = x.Item(1)
For e = 1 To StartR
If e = 1 Then
Set c = x.Find(Str, after:=x.Item(x.Rows.Count), LookIn:=xlValues)
Else
Set c = x.Find(Str, after:=xx, LookIn:=xlValues)
End If
If xx.Row > c.Row Then ' Restart to Find ...
FoundRecR = -1
Exit Function
End If
If c Is Nothing Then
FoundRecR = 0
Exit Function
End If
For i = 1 To 9999
If c.Offset(i, 0).Value <> c.Value Then Exit For
Next
Set xx = c.Offset(i - 1, 0)
Next
FoundRecR = i
End Function
The function search the occurrance StartR of the string Str in the range x:
=FoundRecR("01A";A2:A16;1)
Return 0 if don't found and -1 if the occurrance it's to high (no other occurrance).
The After parameter it's necessary to force Excel to start from the first cell of the range, otherwise Excel ignore...

Resources