Function to extract a string between the 2nd and 3rd comma - ms-access

I am looking for a function that will extract all the information between the 2nd and 3rd comma.
[DropOffAddress] = "Hotel, 1234 Johnson St, Minneapolis, MN 55449"
I am looking to extract just "Minneapolis" from the string above.
If it is less complicated, just extracting "Minneapolis, MN 55449" is workable.
I am using a query to display the information and I know the info I will always be between the second and third comma in the field [DropOffAddress]
Thanks

You can in VBA code use this:
dim strResult as string
strResult = split(strSourceString,",")(2)
So split is zero based, and hence "2" will get us the 3rd token out of the string delimited by ",".
You can't however use VBA split() function in sql query, but you can use it in code as per above.
If you need this in a query?
Then in a standard code module, then place this function.
Public Function MySplit2(v As Variant, ix As Integer) As String
MySplit = ""
If IsNull(v) Then Exit Function
If v = "" Then Exit Function
Dim vBuf As Variant
vBuf = Split(v, "|")
If ix > UBound(vBuf) Then Exit Function
MySplit = vBuf(ix)
End Function
Now, in a sql query, say one column was UserName (first name,LastName)
SELECT id, MySplit([UserName],0) as FirstName,
MySplit([UserName],1) as LastName, City, State from tblCustomers

Related

VBA: Why isn't my FOR loop returning anything?

The overall goal is to return the characters in between the commas and use each of them in another piece of code. If anyone knows a more optimal way of doing this, please let me know.
The problem:
I am trying to find the positions of the commas in the string.
The string:
Dim st As String
st = "1642377,001642381,010301642379"
My attempt:
For pos = 1 To Len(st)
If Mid(st, pos, 1) = "," Then
MsgBox ("Position of comma:" & pos)
End If
Next
Currently returning:
The code doesn't return anything. The If condition isn't returning true.
Expected result:
A MsgBox should pop up twice, showing the position of the comma each time.
Use the split function. It returns a string array
Dim parts() As String, p As Variant
parts = Split("1642377,001642381,010301642379", ",")
For Each p In parts
Debug.Print p
Next
prints
1642377
001642381
010301642379
You are using 2 different values: st and Me.Text585.Value. Did you mean to use st in the two places? If I do so, the code works and it returns the positions 8 and 18.

getting linked table path with tabledef.connect

I have been trying to get the path to a linked table. I am looping thru the tables. it works one the first loop but not on the 2nd loop. it returns "".
Ive tried several different ways, calling the table by name or by number. the code originally comes from Neville Turbit. Neville's code calls the table by name, but I could not get that to work.
Public Function GetLinkedDBName(TableName As String)
Dim tblTable As TableDef
Dim strReturn As String
Dim i As Integer
On Error GoTo Error_NoTable ' Handles table not found
'---------------------------------------------------------------
'
i = 0
On Error GoTo Error_GetLinkedDBName ' Normal error handling
For Each tblTable In db.TableDefs
If tblTable.Name = TableName Then
strReturn = tblTable.Connect
strReturn = db.TableDefs(i).Connect
Exit For
End If
i = i + 1
Next tblTable
You don't need a loop:
Public Function GetLinkedDBName(TableName As String) As String
Dim strReturn As String
On Error Resume Next ' Handles table not found
strReturn = CurrentDb.TableDefs(TableName).Connect
GetLinkedDBName = strReturn
End Function
This is my modification from Gustav's.
CurrentDb.TableDefs(TableName).Connect command will returns a string like this:
"MS Access;PWD=p455w0rd;DATABASE=D:\Database\MyDatabase.accdb"
The string above contains 3 information and parted by ";" char.
You need to split this information and iterate through it to get specific one which contain database path.
I am not sure if different version of ms access will return exact elements and with exact order of information in return string. So i compare the first 9 character with "DATABASE=" to get the index of array returns by Split command and get path name from it.
Public Function getLinkedDBName(TableName As String) As String
Dim infos, info, i As Integer 'infos and info declared as Variant
i = -1
On Error Resume Next ' Handles table not found
'split into infos array
infos = Split(CurrentDb.TableDefs(TableName).Connect, ";")
'iterate through infos to get index of array (i)
For Each info In infos
i = i + 1
If StrComp(Left(info, 9), "DATABASE=") = 0 Then Exit For
Next info
'get path name from array value and return the path name
getLinkedDBName = Right(infos(i), Len(infos(i)) - 9)
End Function

Create query in QueryEditor with VBA function call for specifying the WHERE IN clause

I have written a couple of VBA functions which in the end return a Collection of Integers:
Public Function ValidIDs() As Collection
Now I want to run create a query in the QueryEditor with the following condition: WHERE TableID IN ValidIDs(). That does not work since access for some reason does not even find my function as long as it returns a Collection. Therefore I wrote a wrapper around it, which joins the Collection:
Public Function joinCollectionForIn(Coll As Collection) As String
Now a third function which calls ValidIDs(), passes the result to joinCollectionForIn and returns that result. Lets call it GetIDCollectionAsString().
As a result I can now change my query to WHERE TableID IN (GetIDCollectionAsString()). Note the added parenthesis since the IN needs them in any case, they can not just be at the end and the beginning of the String returned by GetID....
Running that query however results in
Data type mismatch in criteria expression.
I guess that results from the fact that I return a String, therefore access automatically wraps that string in ' for the SQL and the IN-clause no longer works because I would check if a number is IN a collection of 1 string.
Therefore my question is:
Is there a way to prevent access from wrapping the returned string for the SQL
or (would be a whole lot better):
Is there an already existing way to pass a collection or array to the WHERE IN-clause?
P.S.: I am currently using a workaround by writing a placeholder in the parenthesis following the IN (e.g. IN (1,2,3,4,5)) and replacing that placeholder in Form_Load with the result of GetIDCollectionAsString() - that works but it is not pretty...
Edit: The final query should look like SELECT * FROM TestTable t WHERE t.ID IN (1,2,3,4,5,6,7). That actually works using above method, but not in a nice way.
Well this required more work than it seems.... i couldn't find a straight solution so here is a workaround
Public Function ListforIn(inputString As String) As String
Dim qdf As QueryDef
Dim valCriteria As String
Dim strsql As String
Dim splitcounter As Byte
Dim valcounter As Byte
Set qdf = CurrentDb.QueryDefs(**TheNameOfQueryYouWantToModify**)
strsql = qdf.sql
strsql = Replace(strsql, ";", "") 'To get rid of ";"
splitcounter = Len(inputString) - Len(Replace(inputString, ",", ""))
For valcounter = 0 To splitcounter
valCriteria = valCriteria & ValParseText(inputString, valcounter, ",")
Next
strsql = strsql & " WHERE TableId IN (" & Left(valCriteria, Len(valCriteria) - 1) & ")"
qdf.sql = strsql
End Function
Public Function ValParseText(TextIn As String, X As Byte, Optional MyDelim As String) As Variant
On Error Resume Next
If Len(MyDelim) > 0 Then
ValParseText = "Val(" & (Split(TextIn, MyDelim)(X)) & "),"
Else
ValParseText = Split(TextIn, " ")(X)
End If
End Function

Query to parse a field and display it

I have a table with values
Errors:
X_11;SR_4;D_11;SR_2
SR_4;T_22
E_18; E_28; SR_3;
E_28; SR_3;
SR_2;SR_4
I need to put in a query to parse the values so that anything with SR comes up so I do like "*SR*" but in the output I need to display only this:
Errors:
SR_4;SR_2
SR_4
SR_3
SR_3
SR_2;SR_4
I would like this in query with many fields other than this one ... instead of VBA. I am using MS Access 2010, I am guessing some type of parsing with each field being separated with ";" that will only capture SR ones?
I think regular expressions might be a way to go.
In VBA, you need to enable the reference to "Microsoft VBScript Regular Expressions 5.5". This question and its accepted answer has a detailed descrpition on what are Regular Expressions and how to enable them in your project (it's for Excel, but for Access is the same route).
Once you have the reference enabled, this little function will give you a "clean" string:
Public Function filterString(str As String)
Dim re As RegExp, obj As Object, x As Variant, first As Boolean
Set re = New RegExp
With re
.Global = True
.IgnoreCase = True
.MultiLine = False
.Pattern = "SR_[0-9]" ' This will match the string "SR_"
' followed by a digit
End With
filterString = ""
first = True
If re.Test(str) Then
Set obj = re.Execute(str)
For Each x In obj
If first Then
first = False
Else
filterString = filterString & ";"
End If
filterString = filterString & x
Next x
End If
End Function
If you test it you'll see that the result is:
filterString("X_11;SR_4;D_11;SR_2")
SR_4;SR_2
which is the result you want.
Now, a simple select query will give you what you need:
select filterString([Errors]) as err
from [yourTable]
where [yourTable].[Errors] like '*sr*'
Hope this helps
I think you can get what you need by splitting your input string into an array and then using the Filter function to create a second array which includes only the SR_ matches from the first array. Finally Join the second array to produce your output string which contains the matches.
Public Function filterString(ByVal pInput As String) As String
Dim array1() As String
Dim array2() As String
array1 = Split(Replace(pInput, " ", vbNullString), ";")
array2 = Filter(array1, "SR_")
filterString = Join(array2, ";")
End Function
Compared to a regular expression approach, this function is more concise. I find the logic simpler. And it does not require setting a reference.
Notice also it will accommodate SR codes which include more than a single digit (in case that eventually becomes a requirement). For example:
? filterString("X_11;SR_4;D_11;SR_234")
SR_4;SR_234
You could use that function in a query in the same way #Barranka suggested:
SELECT filterString(y.Errors) AS sr_codes
FROM [yourTable] AS y
WHERE y.Errors Like '*sr*';

(Error 3071) Access

I'm trying to search for the Course ID by checking the the faculty ID and Course ID in my Course table. Its a simple query but when launched I receive a
(This expression is typed incorrectly, or it is too complex to be evaluated. For example, a numeric expression may contain too many complicated elements. Try simplifying the expression by assigning parts of the expression to variables. (Error 3071)
The VB script I'm using looks like this.
Private Sub Course_ID_DblClick(Cancel As Integer)
Dim x As Integer
Dim y As String
Dim z As Integer
x = Me.Faculty_ID.Value
Me.Course_ID.RowSource = "SELECT Course.[Course ID] FROM Course WHERE Course.[Course Name]=['Course']AND Course.[Faculty ID]='" & x & "'"
End Sub
I think you are getting this message because you are using wrong delimiters and confusing terminology in object names (where field content 'course' and table name [course] are the same.
I guess your datasource is an ms-access database. You should then use the " (double quote) as value separator (you'll have to double the sign inside the expression) for text, and nothing for numbers. your select instruction could then look like:
"SELECT Course.[Course ID] FROM Course WHERE Course.[CourseName]=[""Course""] AND Course[FacultyID]=" & x
Add a 'debug.print Me.Course_ID.RowSource' to check the final string that should look like:
SELECT Course.[Course ID] FROM Course WHERE Course.[CourseName]=["Course"] AND Course[FacultyID]= 3
There should be no brackets around your string literals:
Me.Course_ID.RowSource = "SELECT Course.[Course ID] FROM Course WHERE Course.[Course Name]='xyz' AND ...
Also, you can use either single or double quotes as string delimiters in an access query.