I am creating a userform in Word VBA that only has one combobox named cboType and one command button named cmdNext. In default, cboType have Null value and cmdNext is disabled.
I use cboType_Change event so that when an item is selected from the combobox, cmdNext is enabled and the combobox value is stored to a variable Type. However, I have another sub that will remove each item in cboType when cmdNext is clicked. I find out that removing item also fire the cboType_Change. I don't want this to happen because it will also change the value in variable Type.
In order to overcome this, I have tried using cboType_AfterUpdate event instead of cboType_Change, but I found out that this event will be fired only if the focus moved from cboType (cmiiw). Meanwhile, I don't have any other active/enabled control in the userform, so the cboType_AfterUpdate event won't be fired (the combobox value won't be stored to variable Type and cmdNext won't be enabled).
Any suggestion on how to do this?
If you just want the function to be called, can't you use
Call cboType_AfterUpdate()
to call this manually when the user clicks the cmdNext button?
Not sure if this solves your initial problem that cboType_Change is called when you change some value in the combobox.
Related
I have a form with a default view set to continuous forms. I want to set the enabled property of a command button control to disabled for records that have a null value in a specific column.
Short answer, you can't. What you need to do is start the button routine with an IF statement that says if the required control is null then exit sub. That way the button won't do anything if the field has a null value
Try setting the caption in the Detail_Paint event for the form:
cb_SetSpecies.Caption = [Species_Name]
This allows a different value to be set for each record.
I have a feeling this is a very simple thing that I'm overlooking.
I have two ComboBoxes that allow users to search for/select the record that they want to view. One is filled with Customer Names and the other is filled with Customer Numbers, so the user can look for a particular record by either selecting the Name or Number.
Each ComboBox is filled by a Data Table returned from a SQL Server database.
Each ComboBox has DropDownStyle set to DropDown, AutoCompleteMode set to SuggestAppend and AutoCompleteSource set to ListItems.
The user can either select by clicking the DropDown arrow and then clicking on the item they was or they can begin by typing and the ComboBox narrows the number of items in the list based on the characters the user is typing.
Using the mouse to click on the item in the list that they want works fine...it fires off a routine to retrieve the selected item from the database.
However, when the user types in the desired selection and presses ENTER, nothing happens. They must click the DropDown arrow and click on the item in order for the program to pull the appropriate record.
How do I get the ComboBox to pull the appropriate record when the user hits enter?
I'm using Visual Basic.
From the sounds of it, you need three events.
You need to use a timer to know when the user has stopped typing. To do that, you need one event would be when that field they're typing in has it's value change (<control's name>.TextChanged). That would start/restart a timer ticking (so that the user has a couple seconds to pause before the next event fires).
The next event would be the Tick event for that timer. That event would stop the timer, and then give focus to the right field so that when the user hits ENTER, they're not hitting ENTER in the field they've been typing in. You'll need to write a function to look up the right item in the ComboBox and call that.
Then you'd have a third event, either KeyPress, KeyDown, or KeyUp on the ComboBox itself. I'd lean towards the KeyUp to avoid issues if the user holds ENTER for whatever reason. That'd be what selects the item.
As a final FYI, I'm assuming you're using Visual Studio to write your code. If not, you should, and if you are/once you are, you can select the field you want to work with in the drop-down at the top left of the editor and then look at the associated events in the top right drop-down.
Thank you to JMichael for getting me on the right track with this one. I'm posting my solution here just in case it helps someone who has a similar question in the future:
The code that I added to the ComboBox's SelectionChangeCommitted event needed also to be added to the ComboBox's KeyUp event:
Private Sub cboPolicySearch_KeyUp(sended as Object, e As KeyEventArgs) Handles cboPolicySearch.KeyUp
If e.KeyCode = Keys.Enter Then
GetSelectedPolicySearchRecord()
e.Handled = True
End If
End Sub 'cboPolicySearch_KeyUp
The GetSelectedPolicySearchRecord() sub contained all of the information I needed to call my SQL Stored Procedure to select the data for the record that the user selected in the ComboBox.
Previously, this was only being called from the ComboBox's "SelectionChangeCommitted" event which is executed when the user clicks the drop down and then clicks a policy number from the drop down list.
I needed to add the same call to the GetSelectedPolicySearchRecord in the ComboBox's "KeyUp" event for when the user presses enter.
I'm trying to implement a very simple subform document grid on a form:
I have everything except getting the file path when the user clicks the grid. How can I get the filepath value from the user row click event ?
Sorry if my terminology is off I rarely write vba
You can create a public subroutine that references your FilePath field and then reference this subroutine in the on-click event of each of the fields on your subform.
So if your subform looks like this:
Go in to Design View of the form, and select one of your fields:
With a field selected, go to the Property Sheet on the right-hand side and go to the Event tab and click the [...] button on the On Click event:
You'll be taken to the form's VBA script module and it'll create the initial VBA for the on-click event of the field you selected:
Ignore that field's on-click event VBA for now, and instead move your cursor to the top and make some room for a public subroutine above the field's on-click event.
Write something like this at the top:
Public Sub GetFilePath()
Debug.Print Me.FilePath
End Sub
So your code in Access should now look something like this:
That public sub I've called GetFilePath can now be referenced in the on-click event of every field in your subform. Let's finish the on-click event of the ID field that we just started...
...and also reference the same public sub in every other field's on-click event (again, by selecting the field in Design View and then clicking [...] button in Property Sheet's on-click event):
In the VBA editor, make sure you have the Immediate Window open; it should be in the area below your VBA code. If it's not there press Ctrl + G or go to View > Immediate Window:
With the VBA editor and Immediate Window still open, go back to your form and put it into Form View.
Click on any row and you should see the FilePath data for the row you've clicked on print out in the Immediate Window (this is what Debug.Print does):
You probably don't want the FilePath to go the Immediate Window, but as you haven't specified where you want it to go I figured this would at least illustrate how you can get at that data by clicking on a record in your subform.
All you need to do is replace the Debug.Print Me.FilePath line to whatever is useful to you.
Hope this was enough to get you started though :)
MS Access does not provide Row click event. You have to either perform, [Form onClick Event] or ideally make the filePath as HyperLink and onClicking FilePath retrieve its value.
When you go for [Form onClick event] you will get the FilePath from selected row. But the click event is only fired if you are clicking the form and none of the fields.
As above mentioned, make the FilePAth field as hyperlink, add onClick event to it and retrieve the value.
sorry for upwarming but the accepted answer is not the best way to go.
Instead of creating an OnClick-event for every column in that subform (for each control),
you should rather use the OnCurrent event of the Subform itself, which is triggered whenever you change the current record. This basically happens whenever you click on another row in the subform.
Doing so will save you work whenever you extend the subform with a new column.
in that OnCurrent Event of the Subform you will then have the same code.
Basically it should look like this:
Public Sub Form_Current()
Debug.Print Me.FilePath
End Sub
Back in the old days of VBA, we used to be able to directly access controls on a form by name. I'm a little perplexed by how to do this in VBA 2010 (or if it's even possible any longer).
Say I have a ribbon control with a dropdown list called "channelList", and elsewhere on the ribbon I have a textbox called "labelText". Each of these items has a unique callback function - when I type something into labelText, its callback fires, and when I select an item from the channelList listbox, its callback fires with the list item passed as an argument.
Where I'm stumped by is how I would update the labelText textbox contents with 'something' from within the channelList callback.
Is there a way to directly access the textbox control from within the listbox callback, or must I generate some sort of event? What method or function would I use to set the text value for the control? (Do I need to cast the IRibbonControl object to something?)
The solution was a combination of an answer and the comments, so here goes:
Add a "getText" callback subroutine name to the Ribbon XML, specific to the "labelText" editbox.
editBox id="labelText" label="Text:" sizeString="xxxxxxxxxx"
onChange="TextboxCallback" getText="UpdateTextBoxText"
screentip="Channel label"
supertip="Limited to 10 characters. Press Enter once finished typing."
In the combo box callback function, set the desired editbox text to a global and call Ribbon.InvalidateControl with "labelText" as the argument.
MyRibbon.InvalidateControl "labelText"
Implement the editbox callback, passing a handle to the ribbon and another variable ByRef to contain the 'stuff' to be updated. Use the global to update the control's text via the ByRef argument.
Sub UpdateTextBoxText(control As IRibbonControl, ByRef returnedVal)
Select Case (control.id)
Case "labelText"
returnedVal = LabelText
End Select
End Sub
I guess this is "progress". labelText.Value = "blah" is far too simple.
Take a look at the Ribbon.Invalidate method. When you "invalidate" the ribbon you basically reset it, and in that moment you can set the properties of controls on the ribbon based on whatever you can track in that moment. In order to do so, you need to have Control.GetEnabled, GetVisible, etc., subroutines in your VBA.
You can also invalidate individual controls with Ribbon.InvalidateControl.
Here's a link that might help: http://sourcedaddy.com/ms-excel/resetting-controls.html
How do I force an update when the ComboBox value is changed in code. Below is piece of code I have tried but does not seem to work
If (Not Mid(sCode, 1, 2) = ddlLevelID1) Then
ddlLevelID1 = Mid(sCode, 1, 2) 'force change/force AFTER_UPDATE event to run.
End If
Assuming ddlLevelID1 is the ComboBox:
ddlLevelID1.value = foo
will change the value. I do not believe you can link a value displayed in a ComboBox to a variable value without pushing changes up to the userform after the value is changed.
Regarding the AfterUpdate method, from msdn:
Changing data in a control by using Visual Basic or a macro containing
the SetValue action doesn't trigger these events for the control.
However, if you then move to another record or save the record, the
form's AfterUpdate event does occur.
http://msdn.microsoft.com/en-us/library/office/bb238392(v=office.12).aspx