Check if Column List Contains Header via Regex - Excel vba - excel

I'm trying to determine if a column has a header or not via VBA. Basically the column will have data following an unknown but identical regex pattern. My plan is to test if A2 has the same type regex string as A1. It would likely even be the same ID + 1. Eg
A1 = X001
A2 = X002
Func IsHeader("A") = True
A1 = ID's
A2 = X001
Func IsHeader("A") = False
I've got an idea to utilize an existing script I made to generate a regex pattern based on an input alphanumerical string, but I'm interested to see what other idea's/ways people might have of solving the issue. I realize there isn't much code, but I know I can do this and I'm working on it now. If you're not interested in answering, thats ok!
Update: Posted Answer, but I'm looking for more than a code review as I realize there is an exchange for that. I'd like to know better ways to achieve goal with a different attack vector.

This is what I got! I'm not sure how SO feels about code reviews, but im interested in what ppl think and how else they could "skin the cat" so please feel free to post an answer.
Sub Test()
If IsHeader = True Then
MsgBox "Has Header"
Else
MsgBox "No Header"
End If
End Sub
Public Function IsHeader() As Boolean
A1Pattern = RegExPattern(Range("A1").Value)
A2Pattern = RegExPattern(Range("A2").Value)
If A1Pattern = A2Pattern Then
IsHeader = True
End If
End Function
Public Function RegExPattern(my_string) As String
RegExPattern = ""
'''Special Character Section'''
Dim special_charArr() As String
Dim special_char As String
special_char = "!,#,#,$,%,^,&,*,+,/,\,;,:"
special_charArr() = Split(special_char, ",")
'''Special Character Section'''
'''Alpha Section'''
Dim regexp As Object
Set regexp = CreateObject("vbscript.regexp")
Dim strPattern As String
strPattern = "([a-z])"
With regexp
.ignoreCase = True
.Pattern = strPattern
End With
'''Alpha Section'''
Dim buff() As String
'my_string = "test1*1#"
ReDim buff(Len(my_string) - 1)
Dim i As Variant
For i = 1 To Len(my_string)
buff(i - 1) = Mid$(my_string, i, 1)
char = buff(i - 1)
If IsNumeric(char) = True Then
'MsgBox char & " = Number"
RegExPattern = RegExPattern & "([0-9])"
End If
For Each Key In special_charArr
special = InStr(char, Key)
If special = 1 Then
If Key <> "*" Then
'MsgBox char & " = Special NOT *"
RegExPattern = RegExPattern & "^[!##$%^&()].*$"
Else
'MsgBox char & " = *"
RegExPattern = RegExPattern & "."
End If
End If
Next
If regexp.Test(char) Then
'MsgBox char & " = Alpha"
RegExPattern = RegExPattern & "([a-z])"
End If
Next
'RegExPattern = Chr(34) & RegExPattern & Chr(34)
'MsgBox RegExPattern
End Function

Related

Extract value from URL and set it as variable

I want to double-click a cell in Excel to open a URL.
I've been using VBA for this aspect, but I am facing an issue.
I want to extract a value from URL and use it as variable in VBA.
Here is part of the script:
Dim ID As String
ID = ActiveSheet.Range("S" & Target.Cells.Row & "").Value
rptUrl = "http://...=" + ID
If (ID <> "") Then
ThisWorkbook.FollowHyperlink (rptUrl)
In such case, if the ID is at the end of the URL, it works.
What happens if the ID that I want to extract is somewhere in the middle of the URL, and not at the end?
For example:
rptUrl = "http://..**ID**..="
I tried the following:
rptUrl = "http://.. + **ID** + ..="
If you want to use a regular expression, here's an option that packages the regular expression into a function that you can call. If the URL contains "ID", it will return the corresponding value; otherwise, it will just return a blank string
Function GetId(sInput) As String
Dim oReg As Object
Dim m As Variant
Dim sOutput As String
sOutput = ""
Set oReg = CreateObject("VBScript.Regexp")
With oReg
.Global = False
.ignorecase = True
.MultiLine = False
.Pattern = "id=(\w+)[&|$]"
End With
If oReg.Test(sInput) Then
sOutput = oReg.Execute(sInput)(0).submatches(0)
End If
GetId = sOutput
End Function
Sub Test()
Debug.Print GetId("mysrv.com/form.jsp?id=12345&cn=0")
End Sub

How to remove the last character of a word in a text string and insert to another cell using VBA in Excel?

Everything is working except for that little comma in the 5th word. How to remove that? My code is as follows.
The text looks like this: The data as of 20.12.2019, and so on.
I only want 20.12.2019 without that comma. Any clue? Thanks.
Public Function FindWord(Source As String, Position As Integer)
Dim arr() As String
arr = VBA.Split(Source, " ")
xCount = UBound(arr)
If xCount < 1 Or (Position - 1) > xCount Or Position < 0 Then
FindWord = ""
Else
FindWord = arr(Position - 1)
End If
End Function
subroutine calls the function.
Sub InsertDate()
Sheets("Sheet1").Range("B3").Value = FindWord(Sheets("Sheet2").Range("A2"), 5)
End Sub
So just for fun, a short introduction to regular expressions (which, by no means, I am an expert in):
Sub Test()
Dim str As String: str = "The data as of 20.12.2019, and so on."
Dim regex As Object: Set regex = CreateObject("VBScript.RegExp")
regex.Pattern = "\b(\d{2}.\d{2}.\d{4})"
regex.Global = True
Debug.Print regex.Execute(str)(0)
End Sub
This would be good practice if your string won't follow that same pattern all the time. However when it does, there are some other good alternatives mentioned in comments and answers.
One option is to Replace:
Sub InsertDate()
With Sheets("Sheet1").Range("B3")
.Value = FindWord(Sheets("Sheet2").Range("A2"), 5)
.Value = Replace(.Value, ",", "")
End With
End Sub
This is still text-that-looks-like-a-date, so you can call DateValue to convert it.
.Value = Replace(.Value, ",", "")
.Value = DateValue(.Value) '<~ add this line

VBA convert custom date string to Date and Time

I have this date TimeAndDateTZ = "2014-12-15T21:48:40Z"
I'm trying to get two different variables from it:
Desired Output:
Date = "2014-12-15"
Time24 = "21:48:40"
Time12 = "09:48:40"
I know I could split() it on the "T" and replace() the "Z" but I want to know to do it properly.
I have tried to use CDATE and DateValue but I get an error.
What am I doing wrong?
Edit:
Everything will be continue to be used as Strings, and yes TimeAndDateTZ is a string.
Edit #2:
(See my answer)
Consider the following:
Sub dural()
TimeAndDateTZ = "2014-12-15T21:48:40Z"
ary = Split(Replace(TimeAndDateTZ, "Z", ""), "T")
Datee = ary(0)
Time24 = ary(1)
Time12 = Split(CStr(TimeValue(Time24)), " ")(0)
MsgBox Datee & vbCrLf & Time24 & vbCrLf & Time12
End Sub
DateSerial() and TimeSerial() would be good places to start. See This Tutorial for more information. Since your TimeAndDateTZ appears to be a string, you will need to extract the various parts of the date and time and add the components to the DateSerial() and TimeSerial() methods.
Sub DateTest()
Dim strDate As String
strDate = "2014-12-15T21:48:40Z"
Set objRegExp = CreateObject("vbscript.regexp")
objRegExp.Global = True
objRegExp.IgnoreCase = True
objRegExp.Pattern = "T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}Z"
If objRegExp.Test(strDate) Then entDate = objRegExp.Replace(strDate, "")
objRegExp.Pattern = "[0-9]{1,4}-[0-9]{1,2}-[0-9]{1,2}"
If objRegExp.Test(strDate) Then entTime = objRegExp.Replace(strDate, "")
entTime = Replace(entTime, "T", ""): entTime = Replace(entTime, "Z", "")
End Sub

Excel VBA insert character between number and letter

I would like some VBA code that would allow me to detect if a string contains any instances of a number followed by a letter and then insert a new character between them. For example:
User enters the following string:
4x^2+3x
Function returns:
4*x^2+3*x
Thanks in advance.
Edit: Thanks for the advice guys, I think I have it working but I'd like to see if you can improve what I've got:
Sub insertStr()
On Error Resume Next
Dim originalString As String
Dim newLeft As String
Dim newRight As String
originalString = Cells(1, 1).Value
Repeat:
For i = 1 To Len(originalString)
If IsNumeric(Mid(originalString, i, 1)) = True Then
Select Case Asc(Mid(originalString, i + 1, 1))
Case 65 To 90, 97 To 122
newLeft = Left(originalString, i)
newRight = Right(originalString, Len(originalString) - i)
originalString = newLeft & "*" & newRight
GoTo Repeat
Case Else
GoTo Nexti
End Select
End If
Nexti:
Next i
End Sub
And just to show how it might be done using Regular expressions, and also allowing you to specify any particular character to insert:
Option Explicit
Function InsertChar(S As String, Insert As String) As String
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.Pattern = "(\d)(?=[A-Za-z])"
InsertChar = .Replace(S, "$1" & Insert)
End With
End Function
The pattern is interpreted as
\d Find any number and capture it
(?=[A-Za-z]) that is followed by a letter
And the replacement is
$1 return the capturing group
& concatenated with
Insert (the string to be inserted)
Following Ron's suggestion:
Public Function InsertStar(sIn As String) As String
Dim L As Long, temp As String, CH As String
L = Len(sIn)
temp = Left(sIn, 1)
For i = 2 To L
CH = Mid(sIn, i, 1)
If IsLetter(CH) And IsNumeric(Right(temp, 1)) Then
temp = temp & "*"
End If
temp = temp & CH
Next i
InsertStar = temp
End Function
Public Function IsLetter(sIn As String) As Boolean
If sIn Like "[a-zA-Z]" Then
IsLetter = True
Else
IsLetter = False
End If
End Function

how to check if a string contains only numeric numbers in vba

I want to parse out the year info from a string like this one
$8995 Apr 18 2008 Honda Civic Hybrid $8995 (Orem) pic map cars & trucks - by owner
Since I retrieve this string online, sometimes the year element is not at the same place. The way I do it is to split the string by space using split function, then check if each node of the array contains only numeric digits.
However when i use the function IsNumeric, it also returns "$8995" node as true as well.
What is a good way to check if a string contains only numbers, no "$", no ".", not anything else?
Or in my situation, is there a better way to retrieve the year information?
Thanks.
This can be accomplished as a single line of code, using the Like operator
Function StringIsDigits(ByVal s As String) As Boolean
StringIsDigits = Len(s) And (s Like String(Len(s), "#"))
End Function
Will it be the case that all the strings with "years" will have substrings that look like dates? If that is the case, you could just cycle through the string looking for the first group of three that looks like a date, extracting the year from that:
Option Explicit
Function FindYear(S As String) As Long
Dim SS As Variant
Dim sDate As String
Dim I As Long, J As Long
SS = Split(S, " ")
For I = 0 To UBound(SS) - 2
sDate = ""
For J = 0 To 2
sDate = " " & sDate & " " & SS(I + J)
Next J
sDate = Trim(sDate)
If IsDate(sDate) Then
FindYear = Year(sDate)
Exit Function
End If
Next I
End Function
WIthout using Regular Expressions or some very complicated logic, it's going to be difficult to be perfect.
This code will return the pure numeric substrings, but in the case of your example it will return "18" and "2008". You could obviously try to add some more logic to disallow "18" (but allow "13" or "09", etc., but like I said that starts getting complicated. I am happy to help with that, but not knowing exactly what you want, I think it's best to leave that up to you for now.
Const str$ = "$8995 Apr 18 2008 Honda Civic Hybrid $8995 (Orem) pic map cars & trucks - by owner"
Option Explicit
Sub FindNumericValues()
Dim var() As String
Dim numbers As Variant
var = Split(str, " ")
numbers = GetNumerics(var)
MsgBox Join(numbers, ",")
End Sub
Function GetNumerics(words() As String) As Variant
Dim tmp() As Variant
Dim i As Integer
Dim n As Integer
Dim word As Variant
Dim bNumeric As Boolean
For Each word In words
n = 0
bNumeric = True
Do While n < Len(word)
n = n + 1
If Not IsNumeric(Mid(word, n, 1)) Then
bNumeric = False
Exit Do
End If
Loop
If bNumeric Then
ReDim Preserve tmp(i)
tmp(i) = word
i = i + 1
End If
Next
GetNumerics = tmp
End Function
You could parse the year out using RegEx:
Public Function GetYear(someText As String) As Integer
With CreateObject("VBScript.RegExp")
.Global = False
.MultiLine = False
.IgnoreCase = True
.Pattern = " [\d]{4} "
If .Test(testString) Then
GetYear = CInt(.Execute(testString)(0))
Else
GetYear = 9999
End If
End With
End Function
Example code:
Public Const testString As String = "$8995 Apr 18 2008 Honda Civic Hybrid $8995 (Orem) pic map cars & trucks - by owner "
Public Function GetYear(someText As String) As Integer
With CreateObject("VBScript.RegExp")
.Global = False
.MultiLine = False
.IgnoreCase = True
.Pattern = " [\d]{4} "
If .Test(testString) Then
GetYear = CInt(.Execute(testString)(0))
Else
GetYear = 9999
End If
End With
End Function
Sub Foo()
Debug.Print GetYear(testString) '// "2008"
End Sub

Resources