VBA Splitting a String into multiple cells when it has variable Delimiters - excel

If I have the below info all contained in a single cell and I want to split it into separate cells. I understand how to use the space as a delimiter but in this case, the name also has spaces and I want the name to stay together in a single cell. To further complicate the matter, the name is not always just first and last, it can also include middle so is not always a standard two names.
2172571122 Jane Doe 3143332222 John Doe
2172242237 Mary Mixer 2223334444 Mike M Martin
Want it to end up looking like this:
Cell 1 = 2172242237
Cell 2 = Mary Mixer
Cell 3 = 2223334444
Cell 4 = Mike M Martin
Any suggestions?

This regex based function alternates each split between numbers and text (words).
Option Explicit
Function customSplit(str As String, _
Optional ndx As Integer = 1) As Variant
Static rgx As Object, cmat As Object
Set rgx = CreateObject("VBScript.RegExp")
With rgx
.Global = True
.MultiLine = True
.IgnoreCase = True
If CBool(ndx Mod 2) Then
.Pattern = "[0-9]{10}"
ndx = (ndx + 1) \ 2
Else
.Pattern = "[A-Z]{1,9}\s[A-Z]{1,9}[\s[A-Z]{1,9}]?"
ndx = ndx \ 2
End If
If .test(str) Then
Set cmat = .Execute(str)
If ndx <= cmat.Count Then
customSplit = cmat.Item(ndx - 1)
End If
End If
End With
End Function

You could try:
Option Explicit
Sub test()
Dim strToSplit As String, strImport As String
Dim arrwords As Variant
Dim i As Long, counter As Long
With ThisWorkbook.Worksheets("Sheet1")
strToSplit = .Range("A1").Value
arrwords = Split(strToSplit, " ")
counter = 1
For i = LBound(arrwords) To UBound(arrwords)
If IsNumeric(arrwords(i)) = True Then
strImport = arrwords(i)
.Cells(3, counter).Value = strImport
counter = counter + 1
ElseIf Not IsNumeric(arrwords(i)) = True Then
If Not IsNumeric(.Cells(3, counter - 1).Value) Then
strImport = .Cells(3, counter - 1) & " " & arrwords(i)
.Cells(3, counter - 1).Value = strImport
counter = counter
Else
strImport = arrwords(i)
.Cells(3, counter).Value = strImport
counter = counter + 1
End If
End If
Next
End With
End Sub
Results look like this:

I have a few ideas on what you could do.
1) Read a Line
Do a split(line, " ") and loop through the indecies while performing a isNumeric() on each split value. If not, then add to a string Array() and set a flag to true.
Then, if isnumeric then, expect another name and set flag to true.
2) Read a line.
Then, loop through each character performing an isnumeric and if not then add that character to a string Array() and set flag until isnumeric again, etc....
I hope that helps or at least gets you in the right direction.

Additional variant to posted already:
Sub ZZZ()
Dim dic As Object: Set dic = CreateObject("Scripting.Dictionary")
Dim num$, cl As Range, data As Range, key, x
Dim Result As Worksheet
Set data = Range([A1], Cells(Rows.Count, "A").End(xlUp))
For Each cl In data
x = "": num = "":
For Each x In Split(cl, " ")
If IsNumeric(x) Then
num = x
dic.Add x, ""
ElseIf x <> "" And num <> "" Then
dic(num) = Trim(dic(num) & " " & x)
End If
Next x
Next cl
Set Result = Worksheets.Add
With Result
.Name = "Result " & Replace(Now, ":", "-")
x = 1
For Each key In dic
.Cells(x, "A").Value2 = key
.Cells(x, "B").Value2 = dic(key)
x = x + 1
Next key
.Columns("A:B").AutoFit
End With
End Sub
test:

Related

use VBA to color specific words in a list

SO I have a list of words ( they are 250ish medications in my Settings sheet ) , and I want to use vba to find those specific words in Column D of another sheet and color them magenta. Column D has 105 cells that are full of text.
text I want to search:
list of meds:
what I want it to look like:
below is what iv gathered from other resources but I just cant get it to work! please let me know if you have any suggestions!
also it kinda has to work with mac and windows excel
Sub ColorWords3()
Dim Position As Long, Cell As Range, W As Variant, Words As Variant, Txt As String, druglastcol As Variant, drugs As Variant
druglastcol = Sheets("Settings").Range("A" & Rows.Count).End(xlUp).Row
'Words = Array("TEXT", "WORD", "THEN")
Words = Application.Transpose(Sheets("Settings").Range("A4:A" & druglastcol).Text)
For Each Cell In Columns("D").SpecialCells(xlConstants)
Txt = " " & UCase(Cell.Value) & " "
For Each W In Words
Position = InStr(Txt, W)
Do While Position > 0
If Mid(Txt, Position - 1, Len(W) + 2) Like "[!A-Z0-9]" & W & "[!A-Z0-9]" Then
With Cell.Characters(Position - 1, Len(W)).Font
.Bold = True
.Color = vbRed
End With
End If
Position = InStr(Position + 1, Txt, W)
Loop
Next
Next
End Sub
Like is case-sensitive, so you need to upper-case your drug names to match your upper-cased blocks of text.
If Mid(Txt, Position - 1, Len(W) + 2) Like "[!A-Z0-9]" & UCase(W) & "[!A-Z0-9]" Then
Using Like gets a bit clunky so here's a RegExp-based approach:
EDIT - added a working Like/InStr version...
Sub ColorWords()
Dim Cell As Range, W, Words, matches As Collection, m
With Sheets("Settings")
Words = Application.Transpose(.Range(.Range("A4"), _
.Cells(.Rows.Count, 1).End(xlUp)))
End With
For Each Cell In ActiveSheet.Columns("D").SpecialCells(xlConstants)
For Each W In Words
'Set matches = AllMatchesRegEx(Cell.Text, W) 'windows only
Set matches = AllMatchesInStr(Cell.Text, W) 'windows+mac
For Each m In matches
Debug.Print Cell.Address, W, m
With Cell.Characters(m, Len(W)).Font
.Bold = True
.Color = vbMagenta
End With
Next m
Next
Next
End Sub
Function AllMatchesInStr(ByVal textToSearch As String, searchTerm)
Const OUT As String = "[!A-Z0-9]"
Dim rv As New Collection, pos As Long, start As Long
Dim next2 As String, next1 As String
textToSearch = UCase(" " & textToSearch & " ")
start = 1
pos = InStr(start, textToSearch, searchTerm, vbTextCompare)
Do While pos > 0
If Mid(textToSearch, pos - 1, 1) Like OUT Then
next2 = Mid(textToSearch, pos + Len(searchTerm), 2)
next1 = Left(next2, 1)
'Handle possible s at end of search term
If next1 Like OUT Or (next2 Like "S" & OUT) Then
rv.Add pos - 1
End If
End If
start = pos + 1
pos = InStr(start, textToSearch, searchTerm, vbTextCompare)
Loop
Set AllMatchesInStr = rv
End Function
Function AllMatchesRegEx(textToSearch As String, searchTerm)
Dim rv As New Collection, matches, m
Static reg As Object
If reg Is Nothing Then
Set reg = CreateObject("VBScript.RegExp")
reg.Global = True
reg.IgnoreCase = True
End If
reg.Pattern = "\b" & searchTerm & "s?\b" 'Allow for simple plural form,
'flank with word boundaries
Set matches = reg.Execute(textToSearch)
For Each m In matches
rv.Add m.firstindex + 1 'firstindex is zero-based
Next m
Set AllMatchesRegEx = rv
End Function
There is a mistake in your code:
Words = Application.Transpose(Sheets("Settings").Range("A4:A" & Dr).Text)
what is Dr?
Also don't do this:
druglastcol = Sheets("Settings").Range("A4:A" & Rows.Count).End(xlDown).Row
Do this instead:
druglastcol = Sheets("Settings").Range("A" & Rows.Count).End(xlUp).Row
The reason we do it this way is the method you have used will stop if there is a blank row in the data, the method i have posted comes from the bottom up so will always grab the true last row.
Try
Sub test()
Dim Ws As Worksheet
Dim s As String
Dim vDB
Dim i As Long
'Application.ScreenUpdating = False
Set Ws = Sheets("Settings")
With Ws
vDB = .Range("a1", .Range("a" & Rows.Count).End(xlUp))
End With
For i = 1 To UBound(vDB, 1)
s = vDB(i, 1)
setCharacterColor s
Next i
'Application.ScreenUpdating = True
End Sub
Sub setCharacterColor(strPattern As String)
Dim mCol As Object 'MatchCollection
Dim Ws As Worksheet
Dim rngDB As Range, rng As Range
Dim s As String
Dim i As Integer, Ln As Integer
Set Ws = Sheets("Facts")
Set rngDB = Ws.Range("d1", Ws.Range("d" & Rows.Count).End(xlUp))
For Each rng In rngDB
s = rng.Value
Set mCol = GetRegEx(s, strPattern)
If Not mCol Is Nothing Then
For i = 0 To mCol.Count - 1
c = mCol.Item(i).FirstIndex + 1
Ln = mCol.Item(i).Length
With rng.Characters(c, Ln).Font
.Bold = True
.Color = vbMagenta
End With
Next i
End If
Next
End Sub
Function GetRegEx(StrInput As String, strPattern As String) As Object
Dim RegEx As Object 'New RegExp
Set RegEx = CreateObject("VBScript.RegExp") 'New RegExp
With RegEx
.Global = True
.IgnoreCase = False
.MultiLine = True
.Pattern = strPattern
End With
If RegEx.test(StrInput) Then
Set GetRegEx = RegEx.Execute(StrInput)
End If
End Function
If your use Mac then try below.
Sub test()
Dim Ws As Worksheet, WsColor As Worksheet
Dim rngDB As Range, rng As Range
Dim s As String
Dim vDB, vR
Dim i As Long, Ln As Integer
Dim j As Index
Dim st, et
Application.ScreenUpdating = False
st = Timer
Set Ws = Sheets("Settings")
Set WsColor = Sheets("Facts")
With Ws
vDB = .Range("a1", .Range("a" & Rows.Count).End(xlUp))
End With
With WsColor
Set rngDB = .Range("d1", .Range("d" & Rows.Count).End(xlUp))
End With
For Each rng In rngDB
For i = 1 To UBound(vDB, 1)
Ln = Len(vDB(i, 1)) 'String Length
vR = getItem(rng, vDB(i, 1)) 'string startedIndex
If IsArray(vR) And Not IsEmpty(vR) Then
For j = 1 To UBound(vR)
With rng.Characters(vR(j), Ln).Font
.Bold = True
.Color = vbMagenta
End With
Next j
End If
Next i
Next rng
Application.ScreenUpdating = True
et = Timer
Debug.Print et - st
End Sub
Function getItem(rng As Range, v As Variant) As Variant
Dim vR()
Dim k As Integer, s As Integer, n As Index
Dim str As String
str = rng.Text
s = 1
Do
n = InStr(s, str, v)
If n > 0 Then
k = k + 1
ReDim Preserve vR(1 To k)
vR(k) = n
End If
s = n + Len(v)
DoEvents
Loop While n > 0
If k Then
getItem = vR
Else
getItem = Empty
End If
End Function

superscript letters in vba string variable

I am looking for how to super/subscript a letter/digit in a VBA string variable. I am working in excel with charts that have axes, titles and chart titles that require s-scripting. Additionally, there is a formula to go in a textbox:
Cpt = Cp0 * e^(-ket) where all the p's, t's and 0 are subscripts. The entire expression, (-ket) is superscripted with embedded subscripting for the e (the e between the k & t). Finally, all the specially formatted string variables will be copied to PowerPoint variables via clipboard/gettext.
Any help / guidance is greatly appreciated.
Pat K.
It is workaround Idea only and the code may not be useful for your purpose depending on source and destination of the data and may be treated as demo only. i have only used excel cells and Text Boxes on a sheet as destination and used PowerPoint Text Boxes as target.
The simple approach is that while picking up String from formatted cells/Text Boxes from excel to a variable, Font Subscript, Superscript information is also to be picked up in a parallel variable (here in a 2D Array). The same font information may be used while writing in PowerPoint. The demo idea have to be Modified/Converted to suit your need.
Demo Screen shot
The demo code
Sub Sscript()
Dim CellStr() As Variant
Dim Rng As Range, Cell As Range
Dim shp As Shape
Dim VarNo As Long, i As Long, j As Long, Txt As String, FntInfo As String
Set Rng = Range("C3:C7") 'Range used for collecting input data and font information for the variable
VarNo = 0
'loop used for Trial may be directly assigned to CellStr by increasing Varno by one for each cell
For Each Cell In Rng.Cells
VarNo = VarNo + 1
ReDim Preserve CellStr(1 To 2, 1 To VarNo)
Txt = Cell.Value
CellStr(1, VarNo) = Txt
FntInfo = ""
For i = 1 To Len(Txt)
If Cell.Characters(i, 1).Font.Subscript = True Then
FntInfo = FntInfo & "A"
ElseIf Cell.Characters(i, 1).Font.Superscript = True Then
FntInfo = FntInfo & "B"
Else
FntInfo = FntInfo & "C"
End If
Next i
CellStr(2, VarNo) = FntInfo
Next Cell
'again loop used for Trial may be directly assigned to CellStr from Textboxes in the sheet
For Each shp In ActiveSheet.Shapes
If shp.Type = msoTextBox Then
VarNo = VarNo + 1
ReDim Preserve CellStr(1 To 2, 1 To VarNo)
Txt = shp.TextFrame2.TextRange.Text
CellStr(1, VarNo) = Txt
FntInfo = ""
For i = 1 To Len(Txt)
If shp.TextFrame2.TextRange.Characters(i, 1).Font.Subscript = msoTrue Then
FntInfo = FntInfo & "A"
ElseIf shp.TextFrame2.TextRange.Characters(i, 1).Font.Superscript = msoTrue Then
FntInfo = FntInfo & "B"
Else
FntInfo = FntInfo & "C"
End If
Next i
CellStr(2, VarNo) = FntInfo
End If
Next
'Start of Trial code in excel to be deleted
For i = 1 To UBound(CellStr, 2)
ActiveSheet.Cells(i, 10).Value = CellStr(1, i)
ActiveSheet.Cells(i, 11).Value = CellStr(2, i)
FntInfo = CellStr(2, i)
For j = 1 To Len(FntInfo)
ActiveSheet.Cells(i, 10).Characters(j, 1).Font.Subscript = False
ActiveSheet.Cells(i, 10).Characters(j, 1).Font.Superscript = False
If Mid(FntInfo, j, 1) = "A" Then ActiveSheet.Cells(i, 10).Characters(j, 1).Font.Subscript = True
If Mid(FntInfo, j, 1) = "B" Then ActiveSheet.Cells(i, 10).Characters(j, 1).Font.Superscript = True
Next j
Next
'End of Trial code in excel to be deleted
'Powerpoint placement of data in powerpoint
Dim Pp As PowerPoint.Application
Dim Prs As Presentation
Dim Sld As Slide
Dim Pshp As Shape
Set Pp = CreateObject("Powerpoint.application")
Pp.Visible = True
Set Prs = Pp.Presentations.Open("C:\users\user\desktop\test.pptx")
Set Sld = Prs.Slides(1)
For i = 1 To UBound(CellStr, 2)
Set Pshp = Sld.Shapes(i)
Pshp.TextFrame.TextRange.Text = CellStr(1, i)
FntInfo = CellStr(2, i)
For j = 1 To Len(FntInfo)
Pshp.TextFrame.TextRange.Characters(j, 1).Font.Subscript = False
Pshp.TextFrame.TextRange.Characters(j, 1).Font.Superscript = False
If Mid(FntInfo, j, 1) = "A" Then Pshp.TextFrame.TextRange.Characters(j, 1).Font.Subscript = True
If Mid(FntInfo, j, 1) = "B" Then Pshp.TextFrame.TextRange.Characters(j, 1).Font.Superscript = True
Next j
Next
End Sub
It is suggested to Add reference of Microsoft PowerPoint Object Library and thanks for asking a good question/challenge to achieve something seemingly not possible but logically possible.
Edit: another more simplistic approach (the 1st half of the String variable contains actual string and 2nd half of the variable contains Font Info) with generalized functions is also added below
Sub Sscript2()
Dim Txt As String, Var1 As String, Var2 As String
Dim Addr As String
Var1 = GetVarFont("C6") ' 1st half of the var contains actual string and 2nd half contain font Info
Var2 = GetVarFont("C7") ' 1st half of the var contains actual string and 2nd half contain font Info
'Powerpoint placement of data in powerpoint
Dim Pp As PowerPoint.Application
Dim Prs As Presentation
Dim Sld As Slide
Dim Pshp As Object
Set Pp = CreateObject("Powerpoint.application")
Pp.Visible = True
Set Prs = Pp.Presentations.Open("C:\users\user\desktop\test.pptx")
Set Sld = Prs.Slides(1)
WriteShp Sld.Shapes(8).TextFrame.TextRange, Var1
WriteShp Sld.Shapes(9).TextFrame.TextRange, Var2
End Sub
Sub WriteShp(Ptxt As TextRange, VarX As String)
Dim i As Long
Ptxt.Text = Left(VarX, Len(VarX) / 2)
For i = 1 To Len(VarX) / 2
Ptxt.Characters(i, 1).Font.Subscript = False
Ptxt.Characters(i, 1).Font.Superscript = False
If Mid(VarX, Len(VarX) / 2 + i, 1) = "A" Then Ptxt.Characters(i, 1).Font.Subscript = True
If Mid(VarX, Len(VarX) / 2 + i, 1) = "B" Then Ptxt.Characters(i, 1).Font.Superscript = True
Next
End Sub
Function GetVarFont(Addr As String) As String
Dim Txt As String, i As Long
Txt = Range(Addr).Value
GetVarFont = Txt
For i = 1 To Len(Txt)
If Range(Addr).Characters(i, 1).Font.Subscript = True Then
GetVarFont = GetVarFont & "A"
ElseIf Range(Addr).Characters(i, 1).Font.Superscript = True Then
GetVarFont = GetVarFont & "B"
Else
GetVarFont = GetVarFont & "C"
End If
Next i
End Function

Testing variants against each other

The goal is to get unused values in the textbox, currently i get all of them, se below
This is what I´m trying to get..
..and finally(don't know how to formulate the question yet) this..
My code so far..
It fails to recognize any matches on line 21 (If x = y Then match = True)
Option Explicit
Sub Resources()
Application.ScreenUpdating = False
Dim Arr As Variant
Arr = Range("A2:A10").Value
Dim varr As Variant
varr = Application.Transpose(ExtractNumbers(Range("C2:E10")))
ActiveSheet.TextBox1.Text = "Unused values"
Dim i As Integer
i = 1
Dim x As Variant, y As Variant, z As Variant
Dim match As Boolean
For Each x In Arr
match = False
For Each y In varr
If x = y Then match = True
Next y
If Not match And x > 0 Then
ActiveSheet.TextBox1.Text = ActiveSheet.TextBox1.Text & Chr(10) & x
End If
i = i + 1
Next
Application.ScreenUpdating = True
End Sub
Public Function ExtractNumbers(Target As Range) As Variant
Dim regEx As Object
Set regEx = CreateObject("vbscript.regexp")
Dim regExMatches As Object, regExMatch As Object
Dim Result As String
Dim Cell As Range
For Each Cell In Target
If Cell.Value <> vbNullString Then
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "[0-9]+"
End With
Set regExMatches = regEx.Execute(Cell.Value)
For Each regExMatch In regExMatches
Result = Result & regExMatch & ", "
Next regExMatch
End If
Next Cell
ExtractNumbers = Split(Left$(Result, Len(Result) - 1), ", ")
End Function
Collect the values into a vbLF delimited list before depositing them onto the worksheet.
Option Explicit
Sub resources()
Dim i As Long, str As String
With Worksheets("sheet6")
'collect the missing
For i = 2 To .Cells(.Rows.Count, "A").End(xlUp).Row
If Not CBool(Application.CountIf(.Range("C:E"), .Cells(i, "A").Value)) Then
str = Chr(10) & .Cells(i, "A").Value & Space(1) & .Cells(i, "B").Value & str
End If
Next i
'put results in merged cell
If CBool(Len(str)) Then
str = "unused values" & str
.Range("F:F").UnMerge
.Cells(1, "F").Resize(UBound(Split(str, Chr(10))) + 1, 1).Merge
.Cells(1, "F").WrapText = True
.Cells(1, "F") = str
End If
End With
End Sub

extract specific set of digits from random strings in EXCEL VBA

Disclaimer- my case is specific, and in my case my code works because I know the pattern.
I was looking for an answer everywhere, and the codes I tried were not quite what I was looking for, this is my solution if you are looking for a set of numbers.
In my case, I was looking for 7 digits, starting with digit 1 in a a column with random strings, some string had the number some others didn't.
The number will appear in these three scenarios "1XXXXXX", "PXXXXXXXX", "PXXXXXXXXX"(this has more digits because there is a slash).
Here are the examples of strings:
9797 P/O1743061 465347 Hermann Schatte Earl Lowe
9797 Po 1743071 404440 Claude Gaudette Jose Luis Lopez
9817 1822037 463889 Jean Caron Mickelly Blaise
My Code
Sub getnum()
'i don't use explicit so i didn't declare everything
Dim stlen As String
Dim i As Integer
Dim arra() As String
Dim arran() As String
Orig.AutoFilterMode = False
Call BeginMacro
LastRow = Orig.Cells(Rows.Count, 1).End(xlUp).Row
Orig.Range("J2:J" & LastRow).Clear
'loop though column
For n = 2 To LastRow
celref = Orig.Cells(n, 4).Value
'split string on white spaces
arra() = Split(celref, " ")
'turn string to multiple strings
For counter = LBound(arra) To UBound(arra)
strin = arra(counter)
'remove white spaces from string
storage = Trim(strin)
lenof = Len(storage)
'if string has 9 characthers, check for conditions
If lenof = 9 Then
'position of first and last charachter
somstr = Mid(storage, 1, 1)
somot = Mid(storage, 9, 1)
If somstr = "P" Or somstr = "p" And IsNumeric(somot) = True Then
'removes Po or PO and keeps only 7 digits
storage = Right(storage, 7)
'stores in column J
Orig.Cells(n, 10).Value = storage
End If
ElseIf lenof = 10 Then
somstr = Mid(storage, 1, 1)
somot = Mid(storage, 10, 1)
'other conditions
If somstr = "P" Or somstr = "p" And IsNumeric(somot) = True Then
'removes Po or PO and keeps only 7 digits
storage = Right(storage, 7)
'stores in column J
Orig.Cells(n, 10).Value = storage
End If
End If
'eliminate comma within
arran() = Split(storage, ",")
If Orig.Cells(n, 10).Value <> storage Then
For counter2 = LBound(arran) To UBound(arran)
strin2 = arran(counter2)
storage2 = Trim(strin2)
'final condition if is 7 digits and starts with 1
If IsNumeric(storage2) = True And Len(storage2) = 7 Then
car = Mid(storage2, 1, 1)
If car = 1 Then
'stores in columns J at specific position
Orig.Cells(n, 10).Value = storage2
End If
Else
If isnumeric(orig.cells(n,10).value) =true and _
len(orig.cells(n,10).value = 7 then
orig.cells(n,10).value = orig.cells(n,10).value
else
Orig.Cells(n, 10).Value = "no po# in D"
End If
Next counter2
End If
Next counter
Next n
Call EndMacro
End Sub
you may try this
Option Explicit
Sub getnum()
Dim position As Variant
Dim cell As Range
With Worksheets("Orig") ' change it to your actual sheet name
With Intersect(.UsedRange, Columns("J"))
.Replace what:="P/O", replacement:="P/O ", lookat:=xlPart
For Each cell In .Cells
position = InStr(cell.Text, " 1")
If position > 0 Then cell.Value = Mid(cell.Value, position + 1, 7)
Next
End With
End With
End Sub
This code paste two formulas one in column G and one in column J). The first formula checks for a "P" in the first character of the cell in column 2 and if there is a "P" it extracts the last 7 characters in the string and puts them in column G. The second formula checks if there is not a "P" and if not extracts the last 7 characters in the string and puts them in column J.
Sub Extract()
Dim ws As Worksheet
Dim lRow As Long
Set ws = ThisWorkbook.Sheets("Sheet3")
lRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
ws.Range("G2:G" & lRow).Formula = "=IF(LEFT(B2)=""P"",(RIGHT(B2,7)),"""")"
ws.Range("J2:J" & lRow).Formula = "=IF(LEFT(B2)<>""P"",(RIGHT(B2, 7)),"""")"
End Sub
You may use the RegEx to extract the number in desired format.
Please give this a try...
Function Get10DigitNumber(ByVal Str As String) As String
Dim RE As Object
Set RE = CreateObject("VBScript.RegExp")
With RE
.Global = False
.Pattern = "1\d{6}"
End With
If RE.test(Str) Then
Get10DigitNumber = RE.Execute(Str)(0)
End If
End Function
Then if you want to use this function on the worksheet itself, assuming your string is in A2, try this...
=Get10DigitNumber(A2)
OR
You may use this function in another sub routine/macro like this...
Debug.Print Get10DigitNumber(<pass your string variable here>)
Edited Function:
Function Get10DigitNumber(ByVal Str As String) As String
Dim RE As Object, Matches As Object
Set RE = CreateObject("VBScript.RegExp")
With RE
.Global = False
.Pattern = "[Pp]?\/?[Oo]?(1\d{6})\b"
End With
If RE.test(Str) Then
Set Matches = RE.Execute(Str)
Get10DigitNumber = Matches(0).SubMatches(0)
End If
End Function
And use if as already described above.
After understanding what you were doing, I think this will work. Any feedback would be appreciated.
Dim cell As Range, LRow As Long
LRow = ActiveSheet.Cells(Rows.Count, 4).End(xlUp).Row
For Each cell In Range("D2:D" & LRow)
If cell.Value Like "*Po *" Then
cell.Offset(0, 6).Value = Split(cell.Value, " ")(2)
Else: cell.Offset(0, 6).Value = Split(cell.Value, " ")(1)
End If
Next cell
For Each cell In Range("J2:J" & LRow)
If Len(cell.Value) > 7 Then
cell.Value = Right(cell.Value, 7)
End If
Next

Excel, count first instance of a series of consective characters in a string

So I have a string that looks like this:
99999999999999999999999999999FFFFFFFFFFF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99999^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
I am trying to count the length of the first instance of a series of a given consecutive character.
Examples:
"9" as the given char, it should count that first set of 9's and return 30.
"F" as the given char, it should return 11, for the first set of consecutive "F"s that begins after the 30 "9"s.
I"m doing this in Excel, so a formula/VBA solution is ideal. I can translate any code into VBA if necessary though. I feel like this has a Reg-Ex solution but I'm the Jon Snow of Reg-Ex, I know nothing.
Thanks in advance for any insights/advice.
I will just put this here for posterity:
=IF(SUBSTITUTE(MID($A$1,FIND(A2,$A$1),LEN($A$1)),A2,"")="",LEN($A$1)+1,FIND(MID(SUBSTITUTE(MID($A$1,FIND(A2,$A$1),LEN($A$1)),A2,""),1,1),$A$1,FIND(A2,$A$1)))-FIND(A2,$A$1)
This will count the first grouping of the desired input:
And here is a REGEX solution. Note that we have to escape the metacharacters.
Option Explicit
Function LenFirstInstance(findCHAR As String, searchSTRING As String)
Dim RE As Object, MC As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = False
.ignorecase = False
.Pattern = Left(findCHAR, 1) & "+"
If .Pattern Like "[\^$.|?*+()[{]*" Then _
.Pattern = "\" & .Pattern
If .Test(searchSTRING) = True Then
Set MC = .Execute(searchSTRING)
LenFirstInstance = MC(0).Length
End If
End With
End Function
Does this help? I tried it with your sample data and it seemed to work.
Function number_Appearances(ByVal myText As String, ByVal myRng As Range)
Dim cel As Range
Dim txtFound As Boolean
Dim celText$
Dim findText$
findText = myText
Set cel = myRng
celText = cel.Text
Dim celLen&
celLen = Len(celText)
txtFound = True
Dim i&, k&
Dim iChar$
For i = 1 To celLen
iChar = Mid(celText, i, 1)
If iChar = findText And txtFound = True Then
k = k + 1
ElseIf k > 0 And iChar <> findText Then
txtFound = False
End If
Next i
Debug.Print "Found " & k & " " & findText & "'s"
number_Appearances = k
End Function
But I started this before thinking of a formula. #ScottCraner's suggestion is preferable, IMO.
I got off my lazy bum and wrote VBA to solve. Thank you Scott and Bruce. And yes it was 29, not 30. Thank you again.
Public Function count_first_instance_of_consecutive_chars(the_char, the_string)
Dim counter As Integer
Dim iter As Long
Dim is_a_match As Boolean
is_a_match = False
If the_char <> vbNullString And the_string <> vbNullString Then
For iter = 1 To Len(the_string)
If Mid(the_string, iter, 1) = the_char Then
If is_a_match = True Then
counter = counter + 1
ElseIf is_a_match = False Then
is_a_match = True
counter = 1
End If
Else
If is_a_match = True Then
count_first_instance_of_consecutive_chars = counter
Exit For
End If
End If
Next iter
End If
End Function

Resources