I have a list of items:
B100Q91, B75NX2, BR100, XN20ZN..
I want to remove the first set of numbers in every item, so that it looks like this:
BQ91, BNX2, BR, XNZN..
My approach looks like this:
Function RemoveFirstNumbers(Txt As String) As String
With CreateObject("VBScript.RegExp")
Dim posn As Integer
posn = GetPositionOfFirstNumericCharacter(Txt)
1
If (IsError(posn)) = True Then Replace(Txt, 1, 1) As String
Dim posn As Integer
Else
End With
End Function
End If
GoTo 1
with
Public Function GetPositionOfFirstNumericCharacter(ByVal s As String) As Integer
Dim i As Integer
For i = 1 To Len(s)
Dim currentCharacter As String
currentCharacter = Mid(s, i, 1)
If IsNumeric(currentCharacter) = True Then
GetPositionOfFirstNumericCharacter = i
Exit Function
End If
Next i
End Function
EDIT to package the below as a function
Function ReplaceFirstDigits(sLookupExpression) as String
Dim oReg As Object
Set oReg = CreateObject("VBScript.Regexp")
With oReg
.Global = True
.ignorecase = True
.MultiLine = False
.Pattern = "([A-Za-z]+)(\d+)(\w*)"
End With
ReplaceFirstDigits = oReg.Replace(sLookupExpression, "$1$3")
End Function
Then you can call the function directly from the spreadsheet with a standard syntax, such as =ReplaceFirstDigits(A1)
If you wanted to use a regular expression, code such as the following might do the trick for you.
Sub Test()
Dim oReg As Object
Set oReg = CreateObject("VBScript.Regexp")
With oReg
.Global = True
.ignorecase = True
.MultiLine = False
.Pattern = "([A-Za-z]+)(\d+)(\w*)"
End With
Debug.Print oReg.Replace(Selection, "$1$3")
End Sub
EDITED:
If you don't want to use RegExp, just straight VBA:
Option Explicit
Function RemoveFirstNumber(strInput As String) As String
Dim strRet As String
Dim bFirstNumber As Boolean
bFirstNumber = False
Dim strChar As String
Dim nChar As Integer
For nChar = 1 To Len(strInput)
strChar = Mid(strInput, nChar, 1)
If IsNumeric(strChar) Then
bFirstNumber = True
Else
If bFirstNumber Then
strRet = strRet & Mid(strInput, nChar)
Exit For
End If
strRet = strRet & strChar
End If
Next nChar
RemoveFirstNumber = strRet
End Function
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 months ago.
Improve this question
excel value=M#9094562;M 0567468;M25969028;M25969029;Mployee e
Function simpleCellRegex(Myrange As Range) As String
Dim regEx As New RegExp
Dim strPattern As String
Dim strInput As String
Dim strReplace As String
Dim strOutput As String
strPattern = "m[0-9]{8}"
If strPattern <> "" Then
strInput = Myrange.Value
strReplace = ""
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = True
.Pattern = strPattern
End With
If regEx.Test(strInput) Then
simpleCellRegex = regEx.Replace(strInput, strReplace)
Else
simpleCellRegex = "Not matched"
End If
End If
End Function
Use a regex tester to check what you are getting. https://regexr.com/
Your current Regex only matches 2 occurrences in your pattern.
The others contain a space and a hash, and one only has 7 digits. If you want to find these as well you can expand your pattern.
m.?[0-9]{7,8}
But, if you truly want M followed by 8 digits (M12345678) then your pattern works.
Your Excel code is wrong... you are not looping through the matches (see below):
If regEx.Test(strInput) Then
simpleCellRegex = regEx.Replace(strInput, strReplace)
Else
You need to loop through the matches in the string (see below):
Function simpleCellRegex(Myrange As Range) As String
Dim regEx As New RegExp
Dim strPattern As String
Dim strInput As String
'Added to store matches
Dim objRegMC As Object
Dim objRegM As Object
Dim intCounter As Integer
Dim strDelimiter As String
intCounter = 1
strDelimiter = "|"
strPattern = "m[0-9]{8}"
If strPattern <> "" Then
strInput = Myrange.Value
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = True
.Pattern = strPattern
End With
If regEx.Test(strInput) Then
'Store matched string and loop through matches
Set objRegMC = regEx.Execute(strInput)
For Each objRegM In objRegMC
'Do what you want here to split values etc.
'I have added a delimiter, you can do whatever you want
If objRegMC.Count > 1 Then
If intCounter = objRegMC.Count Then
simpleCellRegex = simpleCellRegex & objRegM
Else
simpleCellRegex = simpleCellRegex & objRegM & strDelimiter
End If
intCounter = intCounter + 1
Else
simpleCellRegex = objRegM
End If
Next
Else
simpleCellRegex = "Not matched"
End If
End If
End Function
Results below:
I'm able to find and replace the special characters in a string but I'm trying to return that special character. Here's what i got so far.
Function replaceSpecialCharacter(theString As String)
Dim StrTest As String
Dim Result As String
Dim Reg1 As Object
Dim matches
StrTest = theString
Set Reg1 = CreateObject("VBScript.RegExp")
With Reg1
.Global = True
.IgnoreCase = True
.Pattern = "[-[\]{}()%*+?\\/^$|#\s]" ' escape special characters pattern
End With
If Reg1.test(StrTest) Then
Result = Reg1.Replace(StrTest, Result)
End If
replaceSpecialCharacter = Result
End Function
If there is only 1 match and you want to return it, you can use a matches object, returned by the Execute method of the regulat expression object:
Function findSpecialCharacter(theString As String)
Dim StrTest As String
Dim Result As String
Dim Reg1 As Object
Dim matches As Object
StrTest = theString
Set Reg1 = CreateObject("VBScript.RegExp")
With Reg1
.Global = True
.IgnoreCase = True
.Pattern = "[-[\]{}()%*+?\\/^$|#\s]" ' escape special characters pattern
End With
Set matches = Reg1.Execute(theString)
findSpecialCharacter = matches(0).Value 'assumes just 1 match, at index 0
End Function
I am trying to use VBA to loop through and find all dates within a textbox, regardless of format. I think I have my regex working. However, when trying to populate a combo box I am having difficulty.
Maybe my code is a bit messy and I am doing it the wrong way. Wha What I mean by that is it's putting every word in the combo box instead of just dates.
However, here is my code
Private Sub CommandButton2_Click()
Call dates1
End Sub
Function ExtractDates(S As String)
With CreateObject("VBScript.RegExp")
.Pattern = .Pattern = "^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$"
.Global = True
ExtractDates = Replace(Trim(.Replace(S, " $1")), " ", ", ")
End With
End Function
Sub dates1()
Dim dates1 As String
Dim dates2 As String
dates2 = ExtractDates(Me.txtS.Text)
Dim optarray
Dim opt
optarray = Split(dates2, ",")
With Me.ComboBox1
.Clear
For opt = 0 To UBound(optarray)
.AddItem (optarray(opt))
Next opt
End With
End Sub
I managed to do this if anyone else is interested:
Option Explicit
Private Sub CommandButton1_Click()
CountDates (Me.TextBox1.Text)
End Sub
Function CountDates(S As String) As Long
Dim i As Integer
Dim result As String
Dim RE As Object, MC As Object
Const sPat As String = "\b(?:\d{1,2}/){2}(?:\d{4}|\d{2})\b"
Set RE = CreateObject("vbscript.regexp")
With RE
.Pattern = sPat
.Global = True
Set MC = .Execute(S)
CountDates = MC.Count
CountDates = CountDates - 1
If MC.Count <> 0 Then
For i = 0 To CountDates
Me.ComboBox1.AddItem (MC.Item(i))
Next i
End If
End With
End Function
I found an old post regarding a sentence case function at the following link.
Converting to sentence case using vba
I happen to love the following function designed by bretdj
Function ProperCaps(strIn As String) As String
Dim objRegex As Object
Dim objRegMC As Object
Dim objRegM As Object
Set objRegex = CreateObject("vbscript.regexp")
strIn = LCase$(strIn)
With objRegex
.Global = True
.ignoreCase = True
.Pattern = "(^|[\.\?\!\r\t]\s?)([a-z])"
If .test(strIn) Then
Set objRegMC = .Execute(strIn)
For Each objRegM In objRegMC
Mid$(strIn, objRegM.firstindex + 1, objRegM.Length) = UCase$(objRegM)
Next
End If
MsgBox strIn
End With
What i can't figure out is how to make the function to sentence case the string typed in a particular cell and then put the corrected sentence back into the original cell. I don't need it in a message box. Something similar to the following:
If Not Intersect(Target, myrange2) Is Nothing Then
Target.Value = ProperCaps(Target.Value)
End If
Any help would be appreciated. Forgive me for reposting this, I'm not authorized to comment on posts.
Thanks
Gary
Your function is missing the last part, but if the last part is just one more line End Function then all you need to do is replace MsgBox strIn with ProperCaps = strIn:
Option Explicit
Function ProperCaps(strIn As String) As String
Dim objRegex As Object
Dim objRegMC As Object
Dim objRegM As Object
Set objRegex = CreateObject("vbscript.regexp")
strIn = LCase$(strIn)
With objRegex
.Global = True
.ignoreCase = True
.Pattern = "(^|[\.\?\!\r\t]\s?)([a-z])"
If .test(strIn) Then
Set objRegMC = .Execute(strIn)
For Each objRegM In objRegMC
Mid$(strIn, objRegM.firstindex + 1, objRegM.Length) = UCase$(objRegM)
Next
End If
End With
ProperCaps = strIn
End Function
I am new to vb.script so this may just be a formatting question that I cannot find the answer.
The problem is validating data in cells that are on different sheets in the same workbook.
Looping through worksheets and then looping through the cell range:
Private Sub Validate(ByRef objWorkbook As Workbook)
Dim strPattern As String: strPattern = "^\-{0,1}\d+(.\d+){0,1}$"
Dim regEx As New VBScript_RegExp_55.RegExp
Dim strInput As String
Dim strOutput As String
Dim Myrange As Range
Dim regExCount As Object
Set regExCount = CreateObject("vbscript.regexp")
On Error Resume Next
For Each objWorksheet In objWorkbook.Worksheets
If (UCase(objWorksheet.Name) = "Foo") Then
objWorksheet.Select
Range("Q2").Select
ElseIf (UCase(objWorksheet.Name) = "Bar") Or (UCase(objWorksheet.Name) = "Poo") Then
objWorksheet.Select
Set Myrange = ActiveSheet.Range("D51:AA76")
For Each cell In Myrange.Cells
If strPattern <> "" Then
strInput = cell.Value
strReplace = ""
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
Set regExCount = regEx.Execute(strInput)
If regExCount.Count = 0 Then
strOutput = strOutput + "Illegal character at " + cell.AddressLocal + "\r\n"
End If
Next cell
End If
Next
MsgBox (strOutput)
End Sub
When I compile I get an error of a Next without a For loop at the Next Cell. Removing that line and I get an error for Block If without an End Ff highlighting the End Sub. Adding an End If before the End sub and I get a Next without a For error.
Isn't it this block missing and end if?
If strPattern <> "" Then
strInput = cell.Value
strReplace = ""
Your
If strPattern <> "" Then
is not closed between
End If ' regExCount.Count
Next cell ' In Myrange.Cells