I am using this function:
https://www.devhut.net/2010/06/22/ms-access-vba-generate-a-random-string/
To create a random alpha numeric string through my form.
This needs to be unique so I need it to check for uniqueness in the column and regenerate a new string if it is not unique. I'm not married to this code if there is a better way to generate a string.
You can do something like this:
Dim Criteria As String
Dim NotFound As Boolean
Do
RandomString = GetRandomString(StringLength, False, True, False)
Criteria = "[YourField] = '" & RandomString & "'"
NotFound = IsNull(DLookup("[YourField]", "[YourTable]", Criteria))
Loop Until NotFound
Related
I’m trying to create a query adding a new calculated field from a VBA function
I’ve an existing table called QLIK
To calculate the new field I need two existing fields called SOCIETA and UNBUNDLING that are included in the table QLIK.
The new field it’s called WBS and I’m using a SWITCH Function (but I guess using some IIF nested would be the same) in a VBA routine because there are too many arguments to create the field with the code buldier directly in the query
Then I call it from an SQL statement like:
SELECT fieldA, fieldB,…, GetWBS() AS WBS_C
FROM QLIK;
At the moment I have the following (simplified) code:
Public Function GetWBS() As String
Dim WBS As String
Dim cdb As DAO.Database
Dim Q As Recordset
Dim SOCIETA As Field, UNBUNDLING As Field
Set cdb = CurrentDb
Set Q = cdb.OpenRecordset("QLIK")
Set SOCIETA = Q.Fields("SOCIETA")
Set UNBUNDLING = Q.Fields("UNBUNDLING")
While Not Q.EOF
GetWBS = Switch( _
[SOCIETA] = "Company 1" And ([UNBUNDLING] = "U1"), WBS = "AAA", _
[SOCIETA] = "Company 1" And ([UNBUNDLING] <> "U1"), WBS = "BBB", _
[SOCIETA] = " Company 2", WBS = "CCC", _
[SOCIETA] = " Company 3", WBS = "DDD")
Q.MoveNext
Wend
Q.Close
End Function
But I’m getting the “run time error 94 invalid use of null”. I tried to specify the GetWBS() Function and variable WBS as Variants but I’m getting only zeros in the new column.
Any ideas of what’s wrong with my code or other ways to do it?
Thanks
Use the Nz function to handle null values in the fields - this allows you to specify a value that the VBA code can handle when the field value is null. So your code would be something like;
Switch((Nz(SOCIETA.Value, "") = "Company 1") And (Nz(UNBUNDLING.Value, "") = "U1") ....
This means that when the field value is null the Nz function will return "".
I know this has been ask already I tried everything but none work for me.
Please help this is my first post..
My Code `
Dim MyDataRow As DataRow = MyDataTbl.Rows(0)
Dim strName As String
Dim strState As String
strName = MyDataRow("ContactName")
strState = MyDataRow("State")
NameTxt.Text = strName.ToString
StateTxt.Text = strState.ToString
If MyDataTbl.Rows.Count = 0 Then
NameTxt.Text = " "
StateTxt.Text = " "
Exit Sub
End If
NameTxt.Text = MyDataTbl.Rows("ContactName").ToString() "ERROR HERE"
StateTxt.Text = MyDataTbl.Rows("State").ToString()
The error is Conversion from String "Contact Name" to type 'Integer' is not valid.
Retrieving from The DataTable seems wrong in your code.
Use NameTxt.Text = MyDataTbl.Rows(<Row Number>).Item("<Column Name>") To retrieve the Data from DataTable.
Data Table might contains more than one row so while retrieving the data, it is important to specify the Row Number. After specifying the Row number, we must choose the Column from which we want to retrieve the Data and that is done by .Item(<Column Number as Integer or Column Name as string>) method.
I have a table Contacts in Access and a search form. After the user specifies the search criteria, the table only shows records that meet the criteria
Is their a way to retrieve all email addresses of searched contacts as semi-colon separated list so that i can just copy and paste in new email's To field.
Any help is appreciated
Roshan.
You might as well make use of an UDF, just keeping it out of the procedure. Get the criteria by which you filter the result. Then you simply pass the criteria. I am not sure how you have built your criteria. A stab in the dark is get all email of people named "Paul". So your code will be.
Public Sub getEmailString(FieldName As String, Tablename As String, Criteria As String)
Dim tmpRS As DAO.Recordset
Dim tmpStr As String, retStr As String
tmpStr = "SELECT " & FieldName & " FROM " & Tablename & " WHERE " & Criteria
Set tmpRS = CurrentDB.OpenRecordset(tmpStr)
If tmpRS.RecordCount > 0 Then
Do While Not tmpRS.EOF
retStr = retStr & tmpRS.Fields(0) & ";"
tmpRS.MoveNext
Loop
End If
getEmailString = retStr
Set tmpRS = Nothing
End Sub
To use it, you simply use.
Dim someEmailString As String
someEmailString = getEmailString("EmailFieldName", "ContactsTableName", "FirstName = 'Paul'")
If you have something it should return,
paul.someone#somedomain.com;paul.someoneelse#somenewdomain.co.uk;
Hope this helps.
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
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*';