I'm using a text box to filter a combo box list in Access 2013. I put the filter code in the Form_Timer sub so as to give users time to type the entire filter string before applying the filter, and I invoke the timer from the text box Change sub. It works great except for one thing: I want the combo box list to drop down and display results, and it just won't work. However I put the exact same line of code in the GotFocus sub for the combo box, and that line works perfectly.
I also tried executing the filter code within the Change sub, just in case there was some weirdness regarding Form_Timer execution. Same result. Here is the code:
Private Sub cboCENamesMain_GotFocus()
Me.cboCENamesMain.Dropdown '<---This line works perfectly.
End Sub
Private Sub Form_Timer()
Dim strSQL As String
Me.TimerInterval = 0
Me.txtFilter.Value = Me.txtFilter.Text
Me.cboCENamesMain.SetFocus
strSQL = ""
strSQL = strSQL & "Select DISTINCT [CE ID] "
strSQL = strSQL & "From [tblMyTable] "
If Len(Me.txtFilter) > 0 Then
strSQL = strSQL & "Where [CE ID] Like ""*" & Me.txtFilter & "*"" "
End If
strSQL = strSQL & "Order By [CE ID];"
Me.cboCENamesMain.RowSource = strSQL
Me.cboCENamesMain.Dropdown '<---This line doesn't do what it's supposed to.
Me.txtFilter.SetFocus
Me.txtFilter.SelStart = Len(Me.txtFilter.Text)
Me.txtFilter.SelLength = 0
End Sub
Private Sub txtFilter_Change()
If Len(Me.txtFilter.Text) = 0 _
Or Len(Me.txtFilter.Text) > 2 Then
Me.TimerInterval = 500
End If
End Sub
I could use a list box instead of a combo box to allow users to see the results of their filter typing, but that would seriously detract from my form design. I have searched on Google and on StackOverflow, and have not found anybody else discussing this issue. Any ideas?
Here is my final code. This works just the way I want. The user types a few characters, and the timer automatically filters the combo box list down to items containing the typed string.
StackOverflow is a great place to file stuff like this - going from job to job it will save some time reinventing the wheel.
The extensive comments in the code are for the analysts who will need to maintain the applications after my contract ends. Neither of them has ever written VBA.
Private Sub cboCENamesMain_Change()
' Ordinarily the AfterUpdate event would automatically fire off the Change event.
' We set a flag to avoid that - otherwise the list would be filtered to only the selected record.
If booCancelChange = False Then
' Don't bother filtering the combo box list unless the filter text is null or longer than
' 1 character.
If Len(Me.cboCENamesMain.Text) <> 1 Then
' Set the Form_Timer event to fire off in 0.3 second to give them time to type a few characters.
Me.TimerInterval = 300
End If
Else
' Reset the flag, otherwise the Change code would stop working after the first record selection.
booCancelChange = False
End If
End Sub
Private Sub Form_Timer()
Dim strSQL As String
' Reset the timer to not fire off, so that it won't keep running without a change
' in the combo box.
Me.TimerInterval = 0
' If they have tabbed out of the combo box after selecting an item, we don't want to
' do this. It's unnecessary and it throws errors from references to the control's
' properties when focus is no longer on the control.
If Screen.ActiveControl.Name = Me.cboCENamesMain.Name Then
' Create a SQL filter for the combo box using the entered text.
strSQL = ""
strSQL = strSQL & "Select DISTINCT [CE ID] "
strSQL = strSQL & "From [Covered Entities] "
If Len(Me.cboCENamesMain.Text) > 0 Then
strSQL = strSQL & "Where [CE ID] Like ""*" & Me.cboCENamesMain.Text & "*"" "
End If
strSQL = strSQL & "Order By [CE ID];"
' Apply the filter.
Me.cboCENamesMain.RowSource = strSQL
Me.txtRowCount = Me.cboCENamesMain.ListCount
' Drop down the combo list so they can see the results of their filter text.
Me.cboCENamesMain.Dropdown
End If
End Sub
Related
I have a combobox that builds it's list upon first usage. I know that the way I want "NotInList" to behave isn't conventional - I don't want to waste adding the item to a table separate from the needed entry, but I'd like to still warn about an item that hasn't been used yet, so that the user has to think twice before accepting the entry.
Once the user adds the item, it will automatically appear in the list next time because the data source for the combo box is as follows:
SELECT tbl_SP.PROGRAM
FROM tbl_SP
GROUP BY tbl_SP.PROGRAM
HAVING (((tbl_SP.PROGRAM) Is Not Null And (tbl_SP.PROGRAM)<>""));
I tried this:
Private Sub cmbPROGRAM_NotInList(NewData As String, Response As Integer)
If MsgBox("'" & Chr(34) & NewData & Chr(34) & " hasn't been used yet. Add to list? ", vbQuestion + vbYesNo, "Add - " & NewData & "?") = vbYes Then
Response = acDataErrAdded
End If
End Sub
but of course, Access wants the item to actually exist before it will release the error. And...if I set LimitToList to "No" then the user doesn't get a warning.
How can I achieve this behavior?
Ok, I tried this which works fine if the user selects YES, but becomes more complicated when the user selects "NO"
Public Function ReturnsRecords(strSQL As String) As Boolean
Dim d As DAO.Database
Dim arr(1 To 3) As DAO.Recordset
'Dim rs As DAO.Recordset
'assume 3 items in array above
Set d = CurrentDb
Set arr(1) = d.OpenRecordset(strSQL)
' MsgBox "Record Count is " & arr(1).RecordCount
If arr(1).RecordCount > 0 Then
ReturnsRecords = True
Else
ReturnsRecords = False
End If
Set d = Nothing
End Function
Private Sub cmbPROGRAM_BeforeUpdate(Cancel As Integer)
Dim strSQL As String
strSQL = "Select * from LU_PROGRAM where PROGRAM ='" & Me.cmbPROGRAM & "'"
If ReturnsRecords(strSQL) = False Then
If MsgBox("'" & Chr(34) & Me.cmbPROGRAM & Chr(34) & " hasn't been used yet. Add to list? ", vbQuestion + vbYesNo, "Add - " & Me.cmbPROGRAM & "?") = vbNo Then
Cancel = True
' how do I reset this? Me.cmbPROGRAM.Text = Null
End If
End If
End Sub
How do I clear the combobox if the user selects NO? If I select me.undo, that will undo all of the entries, but I just want to clear the combobox.
Incidentally, the form is totally unbound and doesn't accept an entry until the user selects "Save"
First, I'm not quite sure what you wish to achieve ...
Then, educate the users to press Escape to cancel. This is mandatory wisdom when operating an Access application.
For your code to work, you can't change the content of a control in the BeforeUpdate event. So try the AfterUpdate event with either:
Me!cmbPROGRAM.Text = ""
or:
Me!cmbPROGRAM.Value = Null
I am trying to create a form with 3 combo boxes on which will run a report from existing data. The combo boxes will filter down based on the data chosen in the next level up combo box.
However I'm having issues with the Batch Number Combobox not populating it's list
Now this is my VBA script:
Private Sub Form_Load()
Me.cboDate.RowSource = ""
Me.cboBatchNo.RowSource = ""
End Sub
Private Sub cboBottleNo_AfterUpdate()
Dim sDateSource As String
sDateSource = "SELECT [tblNewCC].[Date] FROM [tblNewCC]" & _
" WHERE [tblNewCC].[BottleNo] = " & Me.cboBottleNo.Value
Me.cboDate.RowSource = sDateSource
Me.cboDate.Requery
End Sub
Private Sub cboDate_AfterUpdate()
Dim sBatchSource As String
sBatchSource = "SELECT [tblBatchTotals].[BatchNo] FROM [tblBatchTotals] INNER JOIN [tblNewCC] ON [tblBatchTotals].[RunNo]=[tblNewCC].[RunNo]" & _
" WHERE [tblNewCC].[BottleNo] = " & Me.cboBottleNo.Value & _
" AND [tblNewCC].[Date] = " & Me.cboDate.Value
Me.cboBatchNo.RowSource = sBatchSource
Me.cboBatchNo.Requery
End Sub
From what I can see this is working alright on the vba side as I can see it replacing the rowsource of the batch number combobox, and in datasheet view it is giving me results.
However the combobox isn't showing anything in it's list....
Unless I go in make a change and save the sql query again.
Any clues?
The last part of sBatchSource should be " AND [tblNewCC].[Date] = #" & Me.cboDate.Value & "#" As an aside, 'Date' is a terrible name for a field. It is a reserved word in Access and will eventually cause you problems. Here is a helpful link http://www.fontstuff.com/access/acctut15pfv.htm
I have searched and have found a lot of information on using requery on a subform, but I can't seem to find anything that indicates attempting to requery the active form with a new recordset.
I have a form based on a query. I am using an unbound text box to capture the address which needs to be searched then changing the sql statement in the query to locate the records then attempting to use me.requery to load the new results.
The code is updating the sql statement, but the form is not requerying with the new record results. My code is below.
I am fairly new to access and VBA, and appreciate any wisdom you may have. Also, is there ANYTHING that I could be doing in other code which would cause this to fail?
Private Sub Command51_Click()
Dim d As DAO.Database
Dim q As DAO.QueryDef
Dim Addy As String
Dim Search As String
Set d = CurrentDb()
Set q = d.QueryDefs("SQL_Search")
If IsNull(Me!Addy) Then
MsgBox ("Please select a valid address from the list and try again.")
GoTo CleanUp
Else: End If
Addy = Me!Addy
Search = "select * from dbo_ECNumberVerify Where (((dbo_ECNumberVerify.invalidrecord)=False) AND ((dbo_ECNumberVerify.updated)=False) AND ((dbo_ECNumberVerify.Locations) Like '*" & Addy & "*'));"
'Send SQL SP execute command.
q.SQL = Search
Me.Requery
CleanUp:
Set q = Nothing
Set db = Nothing
End Sub
In your example you have a query, but the query is never set or attached to the forms record source in "any way". So the “query” acts independent from the form data source.
You can simply stuff the sql directly into the forms reocrdsouce like this:
Me.RecordSource = Search
(so you don’t need all of your existing code, nor do you need the queryDef.
And when you set the forms SQL directly as per above, then a requery is done automatic for you. So the code required will look like this:
Dim strSearch As String
If IsNull(Me.Addy) Then
MsgBox ("Please select a valid address fromthe list and try again.")
Exit Sub
End If
strSearch = "select * from dbo_ECNumberVerify WHERE " & _
"(invalidrecord = False) AND (updated = False) AND " _
"(Locations Like '*" & Addy & "*')"
Me.RecordSource = strSearch
So you don't need much code, and you really don't need to use + declare the querydef at all.
I have a database with 2 primary keys, one for a LINE NUMBER and one for PHASE of construction. The reason for this is that we have projects that may use the same Line Number but must track several Phases of the project entirely seperatly. What I have is a combo box that will drive the record information on a form. This works fine, but now when I have more than one phase it will only bring up the line's first phase and not the other 4 phases. When something other than phas one is picked it results the first phase information.
Is there a way to tie a combo box with 2 fields to select the proper record based on both fields picked?
Or maybe I need to rething the way the form is brought up... Is there a better way to do this?
Code used to select the record:
Sub SetFilter()
Dim LSQL As String
LSQL = "select * from tblLineData_Horizon"
LSQL = LSQL & " where lineno = '" & cboSelected & "'"
Form_frmHorizon_sub.RecordSource = LSQL
End Sub
Private Sub cboSelected_AfterUpdate()
'Call subroutine to set filter based on selected Line Number
SetFilter
End Sub
Private Sub Form_Open(Cancel As Integer)
'Call subroutine to set filter based on selected Line Number
SetFilter
End Sub
A basic idea, but you'll most likely want to tweak the behaviour a bit and have some more checks. When the form loads, you only have the ability to select LineNo. When cbxLineNo has a value in it, it enables cbxPhaseNo for selection and upon selection, it changes the RecordSource of your subform.
Private Sub cbxLineNo_AfterUpdate()
If IsNull(cbxLineNo) Then
cbxPhaseNo.Enabled = False
Else
cbxPhaseNo.Enabled = True
cbxPhaseNo.RowSource = "SELECT PhaseNo FROM tblLineData_Horizon WHERE LineNo = " & cbxLineNo & ";"
End If
End Sub
Private Sub cbxPhaseNo_AfterUpdate()
If IsNull(cbxPhaseNo) = False And IsNull(cbxLineNo) = False Then
tblLineData_Horizon_sub.Form.RecordSource = "SELECT * FROM tblLineData_Horizon WHERE LineNo = " & cbxLineNo & " AND PhaseNo = " & cbxPhaseNo & ";"
End If
End Sub
Private Sub Form_Load()
cbxLineNo.Enabled = True
cbxPhaseNo.Enabled = False
cbxLineNo.RowSource = "SELECT LineNo FROM tblLineData_Horizon GROUP BY LineNo;"
End Sub
You question is a little unclear, but you can create a combobox with more than one column, then your select statement would be:
where lineno = '" & cboSelected.Column(0) & "' And otherfield='"& cboSelected.Column(1)&"'"
Go to the query behind your combobox by clicking into its RowSource property and clicking the Build button (...). Once you've added the columns you need, bring up the Properties for the query and set Unique Values to Yes, so that it doesn't repeat the combinations of the fields.
You will also need to change other properties of the combobox: 'Column Count' and 'Column Widths'.
I'm having a problem in which I can't requery a subform inside of a form in Access.
The form's name is frmSearch
The subform's name is SearchResults
I've tried
Private Sub Command38_Click()
Me!SearchResults.Form.Requery (or)
Me.SearchResults.Form.Requery
End Sub
My form & subform look like this:
To be clear, I'm using the "Search" button to create a string which contains the textbox and combobox values. This string creates a SQL query called qryTrialQuery. Then my subform makes a query of the qryTrialQuery and produces the results in the table bellow.
I would like to be able to press the search button and then the results appear below it immediately after. The problem is, is that the results don't appear unless I close and reopen the form.
Thanks for all your help in advance.
Update
The following is the code I used to create a query from the textbox and combobox values.
LineOne = "SELECT tblPoolPersonnel.LName, tblPoolPersonnel.FName, tblPoolPersonnel.[Tel Natel], tblPoolPersonnel.[Tel Home], tblPoolPersonnel.Email" & vbCrLf
LineTwo = "FROM (tblPoolPersonnel INNER JOIN tblDayAvailable ON tblPoolPersonnel.Code_Personal = tblDayAvailable.Code_Personal) INNER JOIN tblServiceYES ON tblPoolPersonnel.Code_Personal = tblServiceYES.Code_Personal" & vbCrLf
LineThree = "WHERE (((tblServiceYES.Service)=" & comboService & ") AND ((tblDayAvailable.Availability)=True) AND ((tblDayAvailable.Date)=" & txtDate & ") AND ((tblDayAvailable.CodeHoraire1)=" & comboCodeHoraire & "));"
Set qdf = CurrentDb.QueryDefs("myQuery")
Application.RefreshDatabaseWindow
strSQL = LineOne & LineTwo & LineThree
qdf.SQL = strSQL
qdf.Close
Set qdf = Nothing
Set dbs = Nothing
Assuming you are reconstructing the SQL of your query based on the criteria the user selected, you should just be able to do something like this:
Private Sub Command38_Click()
Dim qryTrialQuery as String
...
' code to construct the SQL SELECT statement for the query, '
' based on the criteria the user entered '
...
SubForm.Form.RecordSource = qryTrialQuery
End Sub
Setting the Subform's RecordSource will refresh the data.
You can try this:
Dim frm as Form
Set frm = frmSearch
frmSearch!SearchResults.Form.Requery