I've got an Access Database filled with some product-informations.
unfortunately data like height, width etc. isn't in a separated column.
So I was wondering how I could use some SQL so I can filter/split those values.
For example it looks like this:
Table: SHP_PRODUCT
Field: SHORT_DSC
Value: Candle "Country", Height 120mm, Diameter 50mm, red
Result should be: "120mm"
Note: The height doesn't always have the same position like "It's the second word". Also I can't guarantee it's comma-separated.
How about using RegEx?
Public Function extractHeight(ByVal val as String) As String
Dim regEx As New VBScript_RegExp_55.RegExp
Dim regExMatches As Object
regEx.Pattern = "Height\s[\d*\,*\.*]+[a-z]{0,1}m"
regEx.Global = False
Set regExMatches = regEx.Execute(val)
If regExMatches.Count > 0 Then
extractHeight = Replace(regExMatches(0), "Height ", "")
Else
extractHeight = ""
End If
End Function
Use in query as aforementioned
The regex pattern Height\s[\d*\,*\.*]+[a-z]{0,1}m matches for a string that begins with "Height", followed by a space, then a number of whatever length with '.' or ',', then a string such as cm, mm, m.
Make sure to add Microsoft VBScript Regular Expressions 5.5 to References in the VBA edtior (Extras - References)
You can create small function to retrieve this:
Public Function ExtractHeight(ByVal Value As String) As String
Dim Parts As Variant
Parts = Split(Value, "Height")
If UBound(Parts) > LBound(Parts) Then
ExtractHeight = Replace(Trim(Split(Parts)(1), " ")(0)), "m,", "m")
End If
End Function
Then use that in your query:
Height: ExtractHeight([SHORT_DSC])
Related
I have records that include text between square brackets.
aaaaaa[aaaaa]
I need to erase that text, square brackets included.
The result would be:
aaaaaa
I'm trying this code:
Dim sqr as Integer
Dim origin as String
Dim result as String
InStr(origin,[)
I can find the first square bracket, but it does not do the job.
Since in your question you state that you wish to remove text within square brackets (including removing the brackets), I would suggest the following:
Function RemoveSqBracketText(strStr As String) As String
Dim lngId1 As Long
Dim lngId2 As Long
lngId1 = InStr(strStr, "[")
lngId2 = InStr(strStr, "]")
If lngId1 > 0 And lngId2 > 0 Then
RemoveSqBracketText = Left(strStr, lngId1 - 1) & RemoveSqBracketText(Mid(strStr, lngId2 + 1))
Else
RemoveSqBracketText = strStr
End If
End Function
This will recursively remove all instances of text enclosed in square brackets, and assumes that you only wish to remove text if it is enclosed within an opening and closing bracket.
Examples:
?RemoveSqBracketText("abc[123]")
abc
?RemoveSqBracketText("abc[123]def[ghi]")
abcdef
?RemoveSqBracketText("abc[123]defghi]")
abcdefghi]
You need to work out the index of the opening square bracket - InStr(origin, "[") (note the double quotes) is a good start.
Now you can loop from that index up to the end of the string, using the Mid$ function to inspect the character at the current index, until the closing bracket is located:
Dim currentPosition As Long
currentPosition = InStr(origin, "[")
If currentPosition = 0 Then
' no opening bracket. now what?
Else
Dim bracketedWord As String
For currentPosition = currentPosition + 1 To Len(origin)
If Mid$(origin, currentPosition, 1) <> "]" Then
bracketedWord = bracketedWord & Mid$(origin, currentPosition, 1)
Else
'found the closing bracket: we're done.
Exit For
End If
Next
End If
Or, you can use InStr to locate the [ opening brace and the closing brace ] positions, then compute the length of the substring between these two positions, and use the Mid$ function to pull the substring without looping.
Alternatively, with a reference to Microsoft VBScript Regular Expressions 5.5 you could use a simple regular expression:
Public Function FindBracketedWord(ByVal value As String) As String
Dim regex As RegExp
Set regex = new RegExp
regex.Pattern = "\[(\w+)\]" ' matches a square-bracketed "word", no spaces
Dim matches As MatchCollection
Set matches = regex.Execute(value)
If matches.Count <> 0 Then result = matches(0).SubMatches(0)
FindBracketedWord = result
End Function
To prevent errors, I need to check if a String retrieved from a custom input box is not a valid hex color code. So far I found various solutions for other languages, but none for VBA.
Working on the following code, giving a not hex value input will cause a run time error. That's critical to my project, since I am working on a protected sheet.
Public Function HexWindow(MyCell As String, Description As String, Caption As String)
Dim myValue As Variant
Dim priorValue As Variant
priorValue = Range(MyCell).Value
myValue = InputBox(Description, Caption, Range(MyCell).Value)
Range(MyCell).Value = myValue
If myValue = Empty Then
Range(MyCell).Value = priorValue
End If
tHex = Mid(Range(MyCell).Text, 6, 2) & Mid(Range(MyCell).Text, 4, 2) & Mid(Range(MyCell).Text, 2, 2)
Range(MyCell).Interior.Color = WorksheetFunction.Hex2Dec(tHex)
End Function
How can I set a condition that recognizes a value not being in the format of "#" & 6 characters from 0-9 and A-F in any case?
Couple ways to do this. The easiest way is with a regular expression:
'Requires reference to Microsoft VBScript Regular Expressions x.x
Private Function IsHex(inValue As String) As Boolean
With New RegExp
.Pattern = "^#[0-9A-F]{1,6}$"
.IgnoreCase = True 'Optional depending on your requirement
IsHex = .Test(inValue)
End With
End Function
If for some reason that doesn't appeal to you, you could also take advantage of VBA's permissive casting of hex strings to numbers:
Private Function IsHex(ByVal inValue As String) As Boolean
If Left$(inValue, 1) <> "#" Then Exit Function
inValue = Replace$(inValue, "#", "&H")
On Error Resume Next
Dim hexValue As Long
hexValue = CLng(inValue) 'Type mismatch if not a number.
If Err.Number = 0 And hexValue < 16 ^ 6 Then
IsHex = True
End If
End Function
I would use regular expressions for this. First you must go to Tools-->Referencesin the VBA editor (alt-f11) and make sure this library is checked
Microsoft VBScript Regular Expressions 5.5
Then you could modify this sample code to meet your needs
Sub RegEx_Tester()
Set objRegExp_1 = CreateObject("vbscript.regexp")
objRegExp_1.Global = True
objRegExp_1.IgnoreCase = True
objRegExp_1.Pattern = "#[a-z0-9]{6}"
strToSearch = "#AAFFDD"
Set regExp_Matches = objRegExp_1.Execute(strToSearch)
If regExp_Matches.Count = 1 Then
MsgBox ("This string is a valid hex code.")
End If
End Sub
The main feature of this code is this
objRegExp_1.Pattern = "#[a-z,A-Z,0-9]{6}"
It says that you will accept a string that has a # followed by any 6 characters that are a combination of upper case or lower case strings or numbers 0-9. strToSearch is just the string you are testing to see if it is a valid color hex string. I believe this should help you.
I should credit this site. You may want to check it out if you want a crash course on regular expressions. They're great once you learn how to use them.
I'm looking for a way in VB to find a string between two characters,
"(" and ")".
For example, for the string...
"THIS IS (ONE) AND THIS IS (TWO)"
....I would like for a variable to store the characters between the
second set of parenthesis, e.g.
strMyString = "TWO".
But if the string to search only contains one set of parenthesis, to
store this instead. e.g.
strFirstString = "THIS IS (ONE)"
strMyString = "ONE"
As a preliminary answer, you can use this function to find the string within the last pair or brackets in your test string. If the brackets are in the wrong order or if brackets are missing it will throw an exception.
Private Function StringInLastBracketPair(testString As String) As String
Dim startBracket, endBracket As Integer
startBracket = testString.LastIndexOf("(") + 1
endBracket = testString.LastIndexOf(")")
If startBracket >= endBracket Or startBracket = 0 Or endBracket = -1 Then
Throw New System.Exception("String is not formatted properly : " & testString)
End If
StringInLastBracketPair = stringToTest.Substring(startBracket, endBracket - startBracket)
End Function
How can I pull only the number from a field and put that value into its own field?
For example, if a field1 contains a value of "Name(1234U)".
I need an SQL or VBA way to scan that field and pull the number out. So field2 will equal "1234".
Any ideas?
It is possible that this or a variation may suit:
SELECT t.Field1, Mid([Field1],InStr([field1],"(")+1,4) AS Stripped
FROM TheTable As t
For example:
UPDATE TheTable AS t SET [field2] = Mid([Field1],InStr([field1],"(")+1,4);
EDIT re comment
If the field ends u), that is, alpha bracket, you can say:
UPDATE TheTable AS t SET [field2] =
Mid([Field1],InStr([field1],"(")+1,Len(Mid([Field1],InStr([field1],"(")))-3)
The following VBA function might do the trick:
Option Compare Database
Option Explicit
Public Function RegexReplaceAll( _
OriginalText As Variant, _
Pattern As String, _
ReplaceWith As String) As Variant
Dim rtn As Variant
Dim objRegExp As Object ' RegExp
rtn = Null
If Not IsNull(OriginalText) Then
Set objRegExp = CreateObject("VBScript.RegExp") ' New RegExp
objRegExp.Pattern = Pattern
objRegExp.Global = True
rtn = objRegExp.Replace(OriginalText, ReplaceWith)
Set objRegExp = Nothing
End If
RegexReplaceAll = rtn
End Function
Example using the regular expression pattern
[^0-9]+
which matches one or more non-digit characters
RegexReplaceAll("Name(1234U)","[^0-9]+","")
returns
1234
edit:
To use this in a query run from within the Access application itself, try something like
SELECT Field1, RegexReplaceAll(Field1,"[^0-9]+","") AS JustNumbers
FROM Table1;
Create a VBA function, call it as a field in your query and pass it the original field (like select GetNumerals(field1) from table...). The VBA function will loop through each letter in the field and return only the numeric values. It could look something like this:
Public Function GetNumerals(str As String) As String
Dim i As Integer
For i = 1 To Len(str)
If IsNumeric(Mid(str, i, 1)) Then
GetNumerals = GetNumerals & Mid(str, i, 1)
End If
Next i
End Function
Good day!
There is a problem:
Selected piece of text. In the allocation is as follows:
, .
Example: book 100, pencil 20, ...
I would like to find the sum of the numbers in the row and write it at the end, that is,
book 100, the handle 20
$ 120
I'm trying to solve this problem, but does not go ...
It is unclear, for example, how to access the character in the string.
Did so:
While i <> EndOfText
Char = Mid (AllSelectionText, i, 1)
If Char> = "0" And Char <= "9" Then
...
End If
i = i 1
Wend
But it is not very nice ... must have a function like string (i).
How about using regular expressions? You would need to add a reference to Microsoft VBScript Regular Expressions 5.5, and then you could use the following (not tested):
Function sumOfNumbersInText(text As String) As Long
Dim rgx As New RegExp 'creates a new instance of the Regular Expression object
Dim matches As MatchCollection
Dim mtch As Match
Dim sum As Long
sum = 0
rgx.Pattern = "\d+" 'pattern for a sequence of digits
rgx.Global = True 'find all matches within text
Set matches = rgx.Execute(text) 'get collection of all substrings matching the pattern
For Each mtch In matches
sum = sum + CLng(mtch.Value) 'change each substring into a number and add to sum
Next
sumOfNumbersInText = sum
End Function