How to get rid of the zero '0' numeric from a string? - ms-access-2007

BEFORE:
Johnson0, Yvonne
AFTER:
Johnson, Yvonne

String functions for Access can be found at http://www.techonthenet.com/access/functions/string/replace.php
In your example, code like
Replace("Johnson0", "0", "")
will do the trick for the particular string Johnson0. If you need to only remove the zero if it is the last character, play with the additional start and count parameters described in the link above.

You can try executing following query..
UPDATE table set
columnName = REPLACE(columnName,'0','')
WHERE columnName LIKE "%0%";
This will replace all occurrence of "0" with "".

The answer you submitted clarifies your requirement. Based on that, you don't need to create a user-defined function if your Access version is 2000 or later. You can get the same result with the Replace() function.
MsgBox Replace("Jonson0, Yvonne", "0,", ",")

One approach is to create a custom function
See http://www.techonthenet.com/access/functions/misc/alphanumeric.php for an example. You could do something similar, but in the loop you would only keep the alpha characters.

Public Sub xxx()
MsgBox RemoveStr0("Jonson0, Yvonne")
End Sub
Public Function RemoveStr0(sString As String) As String
Dim ipos As Long, sTemp As String
ipos = InStr(1, sString, "0,")
sTemp = Mid$(sString, 1, ipos - 1)
sTemp = sTemp & Mid$(sString, ipos + 1)
RemoveStr0 = sTemp
End Function

if you can pull it out to java or another OO lang you can just do a matching using regexes.

Related

InSTR or find function in VBA

I am stuck with an issue. I've done my research and found out that I can use InSTR function to search for a specific character in a string.
What I am trying to do is get a file name extracted from a file path.
Currently I have
InStr(StrFrom(pName), "\")
The issue here is, it returns the first occurrence of slash, where as I want to get the last occurrence of the slash (so that I can use a 'right' function wrapped around the above code to capture the file name)
Any help is appreciated on how to get the last slash in a string!
Thanks!
Instr looks from the start of the text string, InstrRev starts looking from the other end.
Public Function FileNameOnly(ByVal FileNameAndPath As String) As String
FileNameOnly = Mid(FileNameAndPath, InStrRev(FileNameAndPath, "\") + 1, Len(FileNameAndPath))
End Function
Consider:
Sub marine()
Dim s As String, ary
s = "C:\whatever\sub1\sub2\reallydeep\x.xlsm"
ary = Split(s, "\")
MsgBox ary(UBound(ary))
End Sub
Use InStrRev() to find the first occurrence of the slash from the right side of the string.
https://msdn.microsoft.com/en-us/library/t2ekk41a(v=vs.90).aspx
Assuming StrFrom is some user defined function, the following will do what you want:
Dim filename as String
Dim path as String
path = StrFrom(pName)
filename = Mid$(path, InstrRev(path, "\") + 1)
Note that its easier to use Mid$ than Right$, as InstrRev returns the character position from the left of the string. Omitting the final parameter of Mid$, returns the rest of the string from that position.

How to extract numbers UNTIL a space is reached in a string using Excel 2010?

I need to pull the code from the following string: 72381 Test 4Dx for Worms. The code is 72381 and the function that I'm using does a wonderful job of pulling ALL the numbers from a string and gives me back 723814, which pulls the 4 from the description of the code. The actual code is only the 72381. The codes are of varying length and are always followed by a space before the description begins; however there are spaces in the descriptions as well. This is the function I am using that I found from a previous search:
Function OnlyNums(sWord As String)
Dim sChar As String
Dim x As Integer
Dim sTemp As String
sTemp = ""
For x = 1 To Len(sWord)
sChar = Mid(sWord, x, 1)
If Asc(sChar) >= 48 And _
Asc(sChar) <= 57 Then
sTemp = sTemp & sChar
End If
Next
OnlyNums = Val(sTemp)
End Function
If the first character in the description part of your string is never numeric, you could use the VBA Val(string) function to return all of the numeric characters before the first non-numeric character.
Function GetNum(sWord As String)
GetNum = Val(sWord)
End Function
See the syntax of the Val(string) function for full details of it's usage.
You're looking for the find function.. Example:
or in VBA instr() and left()
Since you know the pattern is always code followed by space just use left of the string for the number of characters to the first space found using instr. Sample in immediate window above. Loop is going to be slow, and while it may validate they are numeric why bother if you know pattern is code then space?
In similar situations in C# code, I leave the loop early after finding the first instance of a space character (32). In VBA, you'd use Exit For.
You can get rid of the function altogether and use this:
split("72381 Test 4Dx for Worms"," ")(0)
This will split the string into an array using " " as the split char. Then it shows us address 0 in the array (the first element)
In the context of your function if you are dead set on using one it is this:
Function OnlyNums(sWord As String)
OnlyNums = Split(sWord, " ")(0)
End Function
While I like the simplicity of Mark's solution, you could use an efficient parser below to improve your character by character search (to cope with strings that don't start with numbers).
test
Sub test()
MsgBox StrOut("72381 Test 4Dx")
End Sub
code
Function StrOut(strIn As String)
Dim objRegex As Object
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
.Pattern = "^(\d+)(\s.+)$"
If .test(strIn) Then
StrOut = .Replace(strIn, "$1")
Else
StrOut = "no match"
End If
End With
End Function

Convert range to comma delimited string

If I had a column like this:
Col1
abc
def
ghi
jkl
How can I convert it to a string like this?:
"abc,def,ghi,jkl"
You can use the Join() function to join all the elements of a 1 dimensional array with a delimiter.
The Transpose() function is used below to form the dimensional array (this approach works on a single column or row).
Sub Main()
Dim arr
arr = Join(Application.Transpose(Range("A2:A5").Value), ",")
MsgBox arr
End Sub
or as a UDF
Public Function Merge(r As Range) As String
Merge = Join(Application.Transpose(r.Value), ",")
End Function
Just in case you need heavier machinery use one of the solutions provided in the answer below. I had similar challenge for ranges containing milion of cells. In such cases JOIN will lead to crash.
Check the question here:
Turn Excel range into VBA string
I have tested all the approaches provided in the above link. Solutions based on function JOIN have slow performance, or even lead to crash.
Ordinary loop through all the cells is way faster than JOIN function. The sting builder in accepted answer is even faster. With string builder, the strings consisting of millions of cells are build in seconds. This is the solution I have end up with.
Double-transpose works for doing string join on single-row values. Thanks #user2140173 and #brettdj!
debug.print join(Application.Transpose(Application.Transpose(Range("A1:G1").Value)),",")
Public Function COLSASLIST(Rng As Range) As String
Dim tempStr1 As String
tempStr1 = Replace(Replace(Join(Application.Transpose(Application.Transpose(Rng.Value)), ","), ",,", ""), ",,", ",")
If Right(tempStr1, 1) = "," Then tempStr1 = Left(tempStr1, Len(tempStr1) - 1)
COLSASLIST = tempStr1
End Function
Public Function ROWSASLIST(Rng As Range) As String
Dim tempStr1 As String
tempStr1 = Replace(Replace(Join(Application.Transpose(Rng.Value), ","), ",,", ","), ",,", ",")
If Right(tempStr1, 1) = "," Then tempStr1 = Left(tempStr1, Len(tempStr1) - 1)
ROWSASLIST = tempStr1
End Function
Using the new dynamic worksheetfunction TextJoin() of Microsoft 365/Excel2019 (+/-Mac) and Excel for the Web you can build a udf with the following range arguments
(1) a column or
(2) a row or even
(3) a contiguous range input (e.g. "A2:C5")
The optional 2nd argument ExcludeBlanks allows to omit blank values.
The function result is a comma separated list (important for case (3): the reading order is row wise).
Function Rng2List(rng As Range, Optional ExcludeBlanks As Boolean = True) As String
Rng2List = WorksheetFunction.TextJoin(",", ExcludeBlanks, rng)
End Function
See help at Textjoin function

Basic VB troubles

I'm simply wondering what symbol/character I can use to define any character in a string...
Basically I have a number of records with RR 2, RR#2, RR1, RR 1, etc. and I want to use a symbol that will define anything after the RR and replace it with nothing "". I know in SQL it's the "%" symbol, but not sure in VBA.
I am using the Replace function in ArcGIS field calculator.
I tried searching but cannot come up with the right question to find the answer I'm looking for.
Any ideas?
Since it's unclear if you want VBA or VB.Net,
Here's a VBA answer just use the ChopString function using the format shown in the Test sub:
Function ChopString(str As String, after As String, Optional caseInsensitive As Boolean = True) As String
Dim x As Long
If caseInsensitive Then
x = InStr(1, str, after, vbTextCompare)
Else
x = InStr(1, str, after, vbBinaryCompare)
End If
If x Then
str = Left(str, x + Len(after) - 1)
End If
ChopString = str
End Function
Sub Test()
Dim OriginalString As String
Dim choppedString As String
OriginalString = "1234RR this will be chopped"
choppedString = ChopString(OriginalString, "RR")
MsgBox choppedString
End Sub
Sadly the .net REPLACE() function doesn't support wildcard characters, you can use a function as described here but it's a bit long winded.

Strip out non-numeric characters in SELECT

In an MS Access 2007 project report, I have the following (redacted) query:
SELECT SomeCol FROM SomeTable
The problem is, that SomeCol apparently contains some invisible characters. For example, I see one result returned as 123456 but SELECT LEN(SomeCol) returns 7. When I copy the result to Notepad++, it shows as ?123456.
The column is set to TEXT. I have no control over this data type, so I can't change it.
How can I modify my SELECT query to strip out anything non-numeric. I suspect RegEx is the way to go... alternatively, is there a CAST or CONVERT function?
You mentioned using a regular expression for this. It is true that Access' db engine doesn't support regular expressions directly. However, it seems you are willing to use a VBA user-defined function in your query ... and a UDF can use a regular expression approach. That approach should be simple, easy, and faster performing than iterating through each character of the input string and storing only those characters you want to keep in a new output string.
Public Function OnlyDigits(ByVal pInput As String) As String
Static objRegExp As Object
If objRegExp Is Nothing Then
Set objRegExp = CreateObject("VBScript.RegExp")
With objRegExp
.Global = True
.Pattern = "[^\d]"
End With
End If
OnlyDigits = objRegExp.Replace(pInput, vbNullString)
End Function
Here is an example of that function in the Immediate window with "x" characters as proxies for your invisible characters. (Any characters not included in the "digits" character class will be discarded.)
? OnlyDigits("x1x23x")
123
If that is the output you want, just use the function in your query.
SELECT OnlyDigits(SomeCol) FROM SomeTable;
There is no RegEx in Access, at least not in SQL. If you venture to VBA, you might as well use a custom StripNonNumeric VBA function in the SQL statement.
e.g. SELECT StripNonNumeric(SomeCol) as SomeCol from SomeTable
Function StripNonNumeric(str)
keep = "0123456789"
outstr = ""
For i = 1 to len(str)
strChar = mid(str,i,1)
If instr(keep,strChar) Then
outstr = outstr & strChar
End If
Next
StripNonNumeric = outstr
End Function
You can do it all in a query, combining this question with your previous question, you get:
SELECT IIf(IsNumeric([atext]),
IIf(Len([atext])<4,Format([atext],"000"),
Replace(Format(Val([atext]),"#,###"),",",".")),
IIf(Len(Mid([atext],2))<4,Format(Mid([atext],2),"000"),
Replace(Format(Val(Mid([atext],2)),"#,###"),",","."))) AS FmtNumber
FROM Table AS t;
Public Function fExtractNumeric(strInput) As String
' Returns the numeric characters within a string in
' sequence in which they are found within the string
Dim strResult As String, strCh As String
Dim intI As Integer
If Not IsNull(strInput) Then
For intI = 1 To Len(strInput)
strCh = Mid(strInput, intI, 1)
Select Case strCh
Case "0" To "9"
strResult = strResult & strCh
Case Else
End Select
Next intI
End If
fExtractNumeric = strResult
End Function