Removing Combo Box value without having to lose focus - vba

I have a combo box with a list of customers which I am filtering as the user types.
When the form loads there is a preset value in the combo box, however when I backspace the combo box doesn't update the value (it keeps the original customer). The value will only become null once I click away from the combo box. Then I click back and it starts filtering as I type.
I tried setting the focus to another control and then coming back to the combo box on the AfterUpdate events but the code doesn't change the focus
Private Sub cboCustCode_AfterUpdate()
Me.txtCustName = DLookup("[CUST_NAME]", "[PLACE_HOLDER_CUST_LIST]", "[CUST_CODE] = '" & Me.cboCustCode & "'")
Me.txtCustName.SetFocus
Me.cboCustCode.SetFocus
End Sub
I want to be able to backspace in the combo box and then start typing and see the filtered results

I fixed it by checking if the combo box text length is 0 and then setting the combo box value = null
Private Sub cboCustCode_Change()
Me.txtCustName = DLookup("[CUST_NAME]", "[PLACE_HOLDER_CUST_LIST]", "[CUST_CODE] = '" & Me.cboCustCode & "'")
If Len(Me.cboCustCode.Text) = 0 Then
Me.cboCustCode = Null
End If
End Sub

Related

Can I filter an Access form based on a match criteria using VBA?

I have created a form that acts like a more advanced find dialog box. The user clicks on a button within a form, which opens my search form. This search form filters the original form to only display records that match certain fields from the original record within a certain tolerance.
Is there a way to sort the filtered form to display the closest matches first? I have considered using a couple of helper fields within the form. These helper fields would be equivalent to the absolute value of the difference between my criteria and the data within the record's fields. However, I was unsure of whether there was a better way to approach the problem.
Thank you.
Yes, you can certainly set the forms sort order quite much as easy to set the filter.
You might have say this:
Dim f As String
Dim strWhere As String ' our filter
Dim strSortBy As String ' our sort by
f = "frmFilter" ' name of our filter form.
DoCmd.OpenForm f, , , , , acDialog
If CurrentProject.AllForms(f).IsLoaded = False Then
' user closed the dialog form, so lets cancel
Exit Sub
End If
' setup our form filter.
If IsNull(Forms(f)!CompanyName) = False Then
' user entered company name - filter by that
' match by starting
strWhere = "CompanyName LIKE '" & Forms(f)!Company & "%'"
strSortBy = "CompanyName"
End If
If IsNull(Forms(f)!City) = False Then
' user entered Persons name - filter by that
strWhere = "LastName = '" & Forms(f)!LastName & "'"
strSortBy = "City, LastName"
End If
' ok, done with that form, close it
DoCmd.Close acForm, f
Me.Filter = strWhere
Me.FilterOn = True
Me.OrderBy = strSortBy
Me.OrderByOn = True
For the dialog form to work (allow the code to continue?). The ok button on the dialog form will cause the code above to wait. So, to get "back" to this calling code, the ok button on the dialog form (the filter form) will have:
me.Visible = False
And the cancel button on the filter form will have:
docmd.Close acForm, me.Name
So, we assume that
If user hits ok on filter form - it is a "ok", and the form is STILL open. This allows our above code to use/look at/grab values from that dialog form.
If the user hits cancel in that dialog form, it is closed and once again our above code will run after the user closes that dialog form. So, closing the form means cancel, and setting visible = False means ok. (both actions (close, or visible = False) will flip the dialog form OUT of dialog mode and allow our above code to run after the open dialog form command we have above.
It is then a simple matter to get/grab values from the dialog form , setup our filter, and also setup our "order by"

Set a sub-form hidden field to visible, based on a check box status

C, Thank you for your input and encouragement! I have changed my form and script slightly, I am afraid I kept the if then statement as I am comfortable with the formatting. The script now works when the 'On Open'event runs.
Private Sub Form_Open(Cancel As Integer)
Me.ChkAlbumNotes.SetFocus
If Me.ChkAlbumNotes.Value = False Then
Me.lblAlbumNotes.Visible = False
Me.txtAlbumNotes.Visible = False
Me.btnAlbumNotes.Visible = True
Else
Me.lblAlbumNotes.Visible = True
Me.txtAlbumNotes.Visible = True
Me.btnAlbumNotes.Visible = False
End If
Me.TrackName.SetFocus
If Me.TrackName = " " Then
Me.btnAddRecord.SetFocus
Else
Me.btnNextRecord.SetFocus
End If
End Sub
This is fine when the form opens for the first time but I have a set of navigation buttons that are installed by the application as Macros. I cannot add my script to the On_Click event when the button is clicked, as On_Click is linked to the Macro. Is there a way to incorporate the script from the On_Load process to the pre-defined macro? Or can you suggest a neater way to achieve my requirements which are;
When the form opens,a check is made for the existence of a false value in the checkbox
if the check box is set to false, then the Notes Text Box and label are hidden and the notes button is visible.
If the check box has a true value, then the Notes text box and label are made visible and the button is hidden.
On completion of the test I check the field Track Name
if this is empty, I assume I am at the last record and give the Add New Record button the focus
If Track Name is not empty, then focus is set to Next Record button
when this button is clicked, the next record page opens and the process starts again.
Many Thanks
Mike
You should use the Form_Current event instead of Form_Open . This fires on starting the form (2 times) and everytime you move to another record.
Private Sub Form_Current()
Me.lblAlbumNotes.Visible = Me.ChkAlbumNotes.Value
Me.txtAlbumNotes.Visible = Me.ChkAlbumNotes.Value
Me.btnAlbumNotes.Visible = Not Me.ChkAlbumNotes.Value
If Me.TrackName = "" Then ' I suggest If Me.TrackName = " " being a typo and you want to check if empty ( that's why you should use vbNullString instead of "")
Me.btnAddRecord.SetFocus
Else
Me.btnNextRecord.SetFocus
End If
End Sub

Show value based on selection in combo box vba

I need to show denominations based on selection in combo box in my access form.
The tricky thing here is that I need to show immediately after selecting in the combo box (without saving it). This one is working just after I save my selection.
If cmb_Main_Impact.Value = "Productivity" Then
Me.txt_Units = "minutes"
End If
If cmb_Main_Impact = "Quality" Then
Me.txt_Units = "number of errors"
End If
That code should work fine. You want to put it in the combobox on change event.
Also added an elseif so there isnt multiple if and end ifs. Put that code in in the userform that has the combo box.
So your code will look like.
Private Sub cmb_Main_Impact_Change()
If cmb_Main_Impact.Value = "Productivity" Then
Me.txt_Units = "minutes"
elseIf cmb_Main_Impact = "Quality" Then
Me.txt_Units = "number of errors"
End If
End Sub

SubForm won't Requery after MainForm Changes are made

I have an access 2010 database that has a main form 'MainForm' and a subform 'SubForm'. The SubForm is attached to the MainForm as a Subform/Subreport object. The user will select a unique identifier from a dropdown and the subform should use that identifier to pull up employee information on the subform. I have tried any number of ways to avail...
Private Sub Dropdown_Exit(Cancel As Integer)
If IsNull(Me!Dropdown) Or Me!Dropdown= "" Then
' nothing to do due to no one selected
Else
Forms!MainForm!SubForm.Requery
' Forms!SubForm.Requery
' DoCmd.OpenForm "SubForm",,,"[ID]=" & me!SubForm!ID,,acDialog
End If
End Sub
The commented out statements are only some of the things I have tried.
Thanks in advance
You should be able to do this without any code by specifying the LinkMasterField and LinkChildField properties of the subform control on your main form.
It is clear that LinkChildField should be set to ID in the form design mode. It looks like you'll want to set LinkMasterField to Dropdown. You can set the FilterOnEmptyMaster property to Yes to hide all records before the Dropdown is filled, or No to show all records before Dropdown is specified.
EDIT:
If LinkMaster/LinkChild are not appropriate, then code for Dropdown's AfterUpdate event. This fires after a choice is completed via keyboard or mouse. It should look like :
Private Sub Dropdown_AfterUpdate()
If Len(Me!Dropdown & "") = 0 Then
'' handle cleared Dropdown
Else
Subform.Form.Filter = "[ID] = " & Me!Dropdown
Subform.Form.FilterOn = True
End If
End Sub
Changing the filter should update the subform.

VB Avoiding text box that is occupied

I am making an application where there is a form with a column of text boxes that are filled from two different forms with a button on each. when the button of these forms are clicked they input the results into the text boxes in the column.
the problem I am having is that say i click (form2.button 1) three times it will occupy text boxes 1,2 and 3. Now say I want to use (form1.button 1) to input data into text box 4 it will occupy text box 1.
I have each button set up for multiple clicks so I would like to understand how i can have is so say(form2.button 1) is clicked then (form1.button1) will go to 2nd click for example. there are 10 text boxes so I will need it so that they react to how many times each has been clicked.
Assuming the TextBoxes were called TextBox1 thru TextBox10, you could use a sub like this:
Public Sub AddValue(ByVal value As String)
For i As Integer = 1 To 10
Dim tbName As String = "TextBox" & i
Dim matches() As Control = Me.Controls.Find(tbName, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is TextBox Then
Dim tb As TextBox = DirectCast(matches(0), TextBox)
If tb.Text.Trim.Length = 0 Then
tb.Text = value
Exit Sub
End If
End If
Next
MessageBox.Show("All TextBoxes are already taken!")
End Sub
Why not just store a counter variable in the form that contains the textboxes, say NextTextBoxNumber that increments each time a textbox is filled in and then you know exactly which textbox to go to next based upon the value of this variable?
Also, to continue with #Oded's comment, you can easily accomplish what he meant using something along the lines of If Textbox1.Text <> "" Then ...
Does that make sense??