Advanced search text box (search through multivalued column) - vba

How to create a filtering search box that can search through a multivalued column? For instance, I have a column called languages, and for each cell it may contain more than 1 language (eg, english, chinese, japanese). So when I search for english and japanese in the search box it will return the rows that contain these words.
Private sub txtquicksearch_Change()
Dim strFilter As String
Dim sSearch As String
If Me.txtquicksearch.Text Then
sSearch = "'*" & Replace(Me.txtquicksearch.Text, "'", "''") & "*'"
strFilter = "[languages] Like " & sSearch & ""
Me.[Languages Subform].Form.Filter = strFilter
Me.[Languages Subform].Form.FilterOn = True

If this is a truly Multi-Value type field and search for a single language selected in a combobox, consider:
Me.[Languages Subform] = "ID IN (SELECT ID FROM tablename WHERE Languages.Value = '" & Me.cbxLanguage & "')"
This gets more complicated if want to search for multiple languages at once. Use a multi-select listbox for selecting languages and VBA that constructs selections into an array list (common topic and should be able to find example code). Array list for text values looks like "English","Japanese" - yes, quote marks (or apostrophes) must part of the construct. Use that list:
Me.[Languages Subform] = "ID IN (SELECT ID FROM tablename WHERE Languages.Value IN (" & strList & "))"

Related

String surronded by single quotation mark

so I have this check combo box data source from SQL Server
Let's say I have these string value from the combo box
ABC, DEF, GHI
What I wanted next is get those string
and make them become like this
'ABC', 'DEF', 'GHI'
I've tried combining them with "'" & comboBox.Text & "'"
but it looks like this
'ABC, DEF, GHI'
You're starting with a delimited string and you want to process each substring separately, so that means splitting, processing and joining the string. There are a number of variations on a theme that will do that. Here are a couple of examples:
Dim substrings = comboBox.Text.Split(","c)
For i = 0 To substrings.getUpperBound(0)
substrings(i) = "'" & substrings(i).Trim() & "'"
Next
Dim result = String.Join(", ", substrings)
Dim result = String.Join(", ",
comboBox.Text.
Split(","c).
Select(Function(s) $"'{s.Trim()}'"))
Note that, if you're confident that there will always be a comma and one space between substrings then you can incorporate the space into the Split and do away with the Trim:
Dim substrings = comboBox.Text.Split({", "}, StringSplitOptions.None)
For i = 0 To substrings.getUpperBound(0)
substrings(i) = "'" & substrings(i) & "'"
Next
Well, you can do it LINQ style like:
Dim res as string = String.Join(“, “, String.Split(“,”c, original).Select(Function(f) $”’{f.Trim}’”))
The process is to split the original into its component parts, remove any white space, add surrounding quotes and combine back into a single string with “, “ as a separator.

Dlookup reference where name of column being searched is the name of the textbox on my form

I am editing a database created by my predecessor at work. I am creating a "helper" textbox that will pull a value from a table in the same database.
Problem is, in my Dlookup, the name of the column that I am searching is also the name of the textbox on my form that contains the criteria. To change the name of my textbox, I would have to update a lot of code that I did not create. Is there a way around this?
txtgreigeweight = Application.DLookup("[GreigeWeightAvg]", "dbo_TuftingGreigeData", "GreigeRoll# = GreigeRoll#")
I expect the output to be the "GreigeWeightAvg" value from the table.
The output is:
"Syntax error (missing operator) in query expression 'GreigeRoll# = GreigeRoll#'."
Try to concatenate the value:
txtgreigeweight = Application.DLookup("[GreigeWeightAvg]", "dbo_TuftingGreigeData", "[GreigeRoll#] = " & Me![GreigeRoll#].Value & "")
or, it text:
txtgreigeweight = Application.DLookup("[GreigeWeightAvg]", "dbo_TuftingGreigeData", "[GreigeRoll#] = '" & Me![GreigeRoll#].Value & "'")
Include the fully-qualified control name in your selection criteria, e.g.:
txtgreigeweight = Application.DLookup("[GreigeWeightAvg]", "dbo_TuftingGreigeData", "GreigeRoll# = [Forms]![YourFormName]![GreigeRoll#]")
Change YourFormName as appropriate.
At first stop using special characters in field Names...some might think that it improves readability..BUT it won't...its almost a recipe for issues.
So ... just clarify what kind of value is GreigeRoll#
If its numeric (like 1,21,21321) then you should have :
txtgreigeweight = DLookup("[GreigeWeightAvg]", "dbo_TuftingGreigeData", "GreigeRoll# =" & [GreigeRoll#])
On the other hand is alphanumeric (like "A12", "BigGreige","1stG") then it should be :
txtgreigeweight = DLookup("[GreigeWeightAvg]", "dbo_TuftingGreigeData", "GreigeRoll# ='" & [GreigeRoll#] & "'")

MS-ACCESS VBA Multiple Search Criteria

In my GUI, I have several ways to filter a database. Due to my lack of knowledge, my VBA programming has exploded with nested IF statements. I am getting better at using ACCESS now, and would like to find a more succinct way to perform multiple filters. My form is continuous.
Is there a simple way to do the following task (I made a toy model example):
I have a combo box SITE where I can filter by work sites A, B, C. After filtering by SITE, I have three check boxes where the user can then filter by item number 1-10, 11-20, 21-30, depending on what the user selects.
Is there a way to append multiple filters (or filter filtered data)? For example, filter by SITE A, then filter A by item number 1-10?
Currently, for EACH check box, I then have an IF statement for each site. Which I then use Form.Filter = . . . And . . . and Form.FilterOn = True.
Can I utilize SQL on the property sheet to filter as opposed to using the VBA?
What I do for these types of filters is to construct a SQL statement whenever one of the filter controls is changed. All of them reference the same subroutine to save on code duplication.
What you do with this SQL statement depends on what you're trying to do. Access is pretty versatile with it; use it as a RecordSource, straight execute it, and use the results for something else, even just printing it to a label.
To try to modularize the process, here's an example of how I do it:
Dim str As String
str = "SELECT * FROM " & Me.cListBoxRowSource
Me.Field1.SetFocus
If Me.Field1.Text <> "" Then
str = AppendNextFilter(str)
str = str & " SQLField1 LIKE '*" & Me.Field1.Text & "*'"
End If
Me.Field2.SetFocus
If Me.Field2.Text <> "" Then
str = AppendNextFilter(str)
str = str & " SQLField2 LIKE '*" & Me.Field2.Text & "*'"
End If
Me.Field3.SetFocus
If Me.Field3.Text <> "" Then
str = AppendNextFilter(str)
str = str & " SQLField3 LIKE '*" & Me.Field3.Text & "*'"
End If
Me.cListBox.RowSource = str
Variables edited to protect the guilty.
My AppendNextFilter method just checks to see if WHERE exists in the SQL statement already. If it does, append AND. Otherwise, append WHERE.
Making quite a few assumptions (since you left out a lot of info in your question), you can do something like this:
Dim sSql as String
sSql = "Select * from MyTable"
Set W = Me.cboSite.Value
sSql = sSql & " WHERE MySite = " & W & ""
Set X = Me.Chk1
Set Y = Me.Chk2
Set Z = Me.Chk3
If X = True Then
sSql = sSql & " And MyItem between 1 and 10"
If Y = True Then
sSql = sSql & " And MyItem between 11 and 20"
If Z = True Then
sSql = sSql & " And MyItem between 21 and 30"
End If
DoCmd.ExecuteSQL sSql
Again, this is entirely "air code", unchecked and probably needing some edits as I haven't touched Access in some time and my VBA is likely rusty. But it should put you on the right track.
The way i use combobox filtering in access is first I design a Query that contains all the data to be filtered. The Query must contain fields to be used for filtering. QueryAllData => "SELECT Table.Site, Table.ItemNumber, FROM Table;" Then make a copy of the query and Name it QueryFilteredData and Design the report to display the data using QueryFilteredData.
Then create a form with a Site ComboBox, ItemNumber Combo Box, and Sub Report Object and Assign SourceObject the Report Name. Use Value List as the combo box Row Source type and type in the values for Row Source to get it working. To get the report to update I always unassign the SubReport.SourceOject update the QueryFilteredData and then Reassign the SubReport.SourceObject
Combobox_Site_AfterUpdate()
Combobox_ItemNumber_AfterUpdate
End Sub
Combobox_ItemNumber_AfterUpdate()
Select Case Combobox_ItemNumber.value
Case Is = "1-10"
Store_Filters 1,10
Case Is = "11-20"
Store_Filters 11,20
Case Is = "21-30"
Store_Filters 21,30
Case Else
Store_Filters 1,10
End Sub
Private Sub Store_Filters(Lowest as integer, Highest as integer)
Dim SRpt_Recset As Object
Dim Temp_Query As Variant
Dim Temp_SourceObject as Variant
Temp_SourceObject = SubReport.SourceObject
SubReport.SourceObject =""
Set SRpt_Recset = CurrentDb.QueryDefs("QueryFilteredData")
Filter_Combo_Box1 = " ((QueryAllData.[Sites])= " & Chr(39) & Combo_Box1 & Chr(39) & ") "
Filter_Combo_Box2 = (Filter_Combo_Box1 AND (QueryAllData.ItemNumber <= Highest)) OR (Filter_Combo_Box1 AND (QueryAllData.ItemNumber >= Lowest));"
Temp_Query = " SELECT " & Query_Name & ".* " & _
"FROM " & Query_Name & " " & _
"WHERE (" & Filter_Combo_Box2 & ") ORDER BY [Field_Name_For_Sorting];"
SRpt_Recset.SQL = Temp_Query
'Debug.print Temp_Query
SubReport.SourceObject = Temp_SourceObject
End Sub
After the Combo Boxes Work if the Data is going to Change like Site and Item Number then you might want to change the Row Source of the combo boxes to Use a Query that uses Select Distinct Site From QueryAllData. I don't know if Filter_Combo_Box2 step so it may need some correction. Hope this helps.

default value "1484-002" is evaluated as 1482 instead of displaying as string

I have some vba code on my form load that searches for the most recent record in a table then sets the default value for a field on the form to the value from that record.
The values are always in the format of 1484-002. The correct value is being found no problem but when it is displayed on the form it is 1482. This is leading me to believe that it is being treated as a formula and subtracting 2 from 1484 instead of displaying like a string.
The field in the table is set to short text. My form is bound to the table.
Here is a bit of my code:
Private Sub Form_Load()
Dim lastID as Integer
lastID = DMax("ID", "Drilling Detail")
Pattern.DefaultValue = DLookup("[Pattern]", "Drilling Detail", "[ID] = " & lastID)
How do I get the proper 1484-002 displayed?
Text values need delimiters. And maybe handle case of empty table.
Me.Pattern.DefaultValue = "'" & Nz(DLookup("Pattern", "Drilling Detail", "ID = " & Nz(DMax("ID", "Drilling Detail"),0)), "1484-001") & "'"
Can possibly eliminate the intermediate DMax() on the ID field and just DMax() Pattern.
If you really need to increase the sequence by 1:
Dim strNext As String
strNext = Nz(DMax("Pattern", "Drilling Detail"), "1484-000")
Me.Pattern.DefaultValue = "'" & Left(strNext, 5) & Format(Mid(strNext, 6) + 1, "000") & "'"
OnCurrent event is a better location if you need to increment the sequence for multiple records entry.
Advise not to use spaces in naming convention. Better would be DrillingDetail or Drilling_Detail.

How do I automate the built in "find and replace" function in MS-Access?

Is there a way to automate the find and replace function for MS Access?
I've got a lot of data I need to obscure (names and addresses), in a non-reversible way. It's going to an outside contractor that can't see the information (no NDA, etc. will do). But otherwise, I want the data to look as real as possible.
My plan right now is to do a find-n-replace on each character a-z and replace it with a random character. I recognise that chances are, I'll likely end up mapping two or more characters to the same value (which is not a bad thing in my books).
Ideally I'd like to have some kind of function that looks something like:
autoFindNReplace ("table name", "field name", _
"search char", random_alpha_generator(), _
DO_ALL_RECORDS)
And then I can run loop that on each field on each table that I have obscure.
My alternate methods are to:
walk each table and obscure each field individually.
try to come up with some sql statement that will do the same as the mythical autoFindNReplace I describe above.
You can just write a quick hash function in a VBA module and call it from a SQL Update query. Here's an example with table "Table1", and the field "address". The hashField code was taken from here.
Sub MaskAddress()
'Change 1234 to whatever key you'd like.
DoCmd.RunSQL "UPDATE Table1 SET address = hashField(address, 1234)"
End Sub
Public Function hashField(strIn As String, lngKey As Long) as String
Dim i As Integer
Dim strchr As String
For i = 1 To Len(strIn)
strchr = strchr & CStr(Asc(Mid(strIn, i, 1)) Xor lngKey)
Next i
hashField = strchr
End Function
Here was my solution:
Sub autoFindAndReplace(TableName As String, _
FieldName As String, _
Search As String, _
Replace As String)
Dim UpdateString As String
UpdateString = ("update " & TableName & _
" set " & FieldName & _
" = replace (" & FieldName & ", " & _
"""" & Search & """, """ & Replace & """)")
CurrentDb.Execute (UpdateString)
End Sub
Then I loop on autoFindAndReplace with my random character generator, once for alphas and once for numerics.
Yes, I could have done it with multiple Update statements - however, I had a lot of tables and fields to deal with, and this made it look cleaner.