问题
Use-Case Scenario
I have a client with low-income residents. These residents can fill out a paper form with a bunch of check boxes.
It has one section for "Education" (GED, diploma, associates, etc) and another for "Skills" (HVAC, plumbing, etc)
Employers reach out to my client, and for example ask for all their HVAC trained residents with a GED.
Right now, they manually comb through paper records looking for a match
Solution So far
I am setting them up with an access database.
We have short fields for name, cell, email, address, etc.
We then have yes/no boxes for the different skills that appear on the paper form.
I have built the table and a form that the clients employees can easily fill out once they receive the paper copy.
My Issue I need your help with
I would like to have a dynamic query that prompts the end user (my clients' employees) to simply check some boxes and spit out the Personal Information of the resident.
For example, they can tick "HVAC" and then tick "GED", hit a search button that starts the query against the yes/no boxes, and spits out the personal information of the residents that match the skills and education they checked.
I've built individual pre-made static queries for each individual skill, but it's clunky and isn't that user friendly.
I am very inexperienced when it comes to access, if you have training material (youtube video, how-to site) that covers this exact scenario, I can figure out with just that. I think my issue is, I don't know access terminology enough to properly search for what I'm wanting to find.
回答1:
For this simple case, where you only want to filter by yes/no columns, you don't have to use VBA. It's more flexible (and perhaps efficient) though.
Create a search form (let's call it frmSearch
), with unbound check boxes for all skills (chkHVAC
, chkGED
etc.)
Then you can use a single query that covers all skills, using boolean logic:
- If the check box is not checked (
chkHVAC = False
), this skill is not filtered (records are returned, whether the field is true or false). - If it is checked, only records are returned that have the field = True.
Like this. [HVAC]
and [GED]
are the table columns.
SELECT *
FROM myTable
WHERE (Forms!frmSearch!chkHVAC = False OR [HVAC] = True)
AND (Forms!frmSearch!chkGED = False OR [GED] = True)
AND ... etc.
You can put a button on the search form, that opens the query (and perhaps closes it if it's already open):
DoCmd.Close acQuery, "myQuery"
DoCmd.OpenQuery "myQuery
回答2:
More explicitly: we start with a table structure like:
Then we create a search form so the database users don't have to learn to use access.
Next, the users select some combination of skills and education levels from the form and hit the button triggering the button click event.
After clicking through some message boxes the user gets: I couldn't get the code from the internet that was supposed to open up the query as a datasheet to work so I created and opened a temporary table. I felt this was ok as this is the wrong approach anyway (more later). here is the code behind the button click event which creates the sql string for each combination of selected education and skills:
Private Sub SearchForSkillsButton_Click()
'listboxes are better for this application. do not have to add new checkboxes and code every time some client has a new skill.
Dim sqlstring As String
sqlstring = BuildBaseSQLStringandFilterBySkills
sqlstring = AddEducationLevelFilters(sqlstring)
OpenandDisplayTable sqlstring
End Sub
Public Function BuildBaseSQLStringandFilterBySkills() As String
Dim sqlquerystring As String
Dim item As Variant
sqlquerystring = "SELECT [Clients].[FirstName], [Clients].[LastName] INTO SearchResultsTable " & _
"FROM Skills INNER JOIN (EducationLevels INNER JOIN ((Clients INNER JOIN ClientEducation ON Clients.ClientsID = ClientEducation.ClientID) INNER JOIN ClientSkills ON Clients.ClientsID = ClientSkills.ClientID) ON EducationLevels.EducationID = ClientEducation.EducationLevelID) ON Skills.SkillID = ClientSkills.SkillsID"
Dim firstitem As Boolean
firstitem = True
For Each item In SelectMultipleSkillsListBox.ItemsSelected
If firstitem = True Then
firstitem = False
sqlquerystring = sqlquerystring & " Where ([Skills].[SkillID] = " & SelectMultipleSkillsListBox.ItemData(item)
Else
sqlquerystring = sqlquerystring & " AND [Skills].[SkillID] = " & SelectMultipleSkillsListBox.ItemData(item)
End If
Next item
BuildBaseSQLStringandFilterBySkills = sqlquerystring
End Function
Public Function AddEducationLevelFilters(filterstring As String) As String
If Me.CheckBoxGED = True Then
filterstring = filterstring & " AND [ClientEducation].[EducationLevelID] = 1 "
End If
If Me.CheckBoxHighSchool = True Then
filterstring = filterstring & " AND [ClientEducation].[EducationLevelID] = 2 "
End If
If Me.CheckBoxSomeCollege = True Then
filterstring = filterstring & " AND [ClientEducation].[EducationLevelID] = 2 "
End If
filterstring = filterstring & ")"
AddEducationLevelFilters = filterstring
End Function
Public Sub OpenandDisplayTable(sqlstring As String)
DoCmd.RunSQL (sqlstring)
DoCmd.OpenTable ("SearchResultsTable")
End Sub
Here is a link for a long tutorial about making access search forms: http://www.iaccessworld.com/create-search-form-using-vba-ms-access/ normally you would also turn the query into a report which has the advantage of being printable: https://edu.gcfglobal.org/en/access2016/creating-reports/1/
来源:https://stackoverflow.com/questions/59202421/create-a-dynamic-checkbox-query-in-access-for-end-users