VBA: How to trigger event when selected value in combobox changes - excel

I am new to VBA and would like to trigger a simple change event when the selection in a combobox (within a UserForm) changes.
I tried both Private Sub myCombo_AfterUpdate() and Private Sub myCombo_Change() but in both cases nothing happens when I make select a different value in the combobox.
Is this the wrong approach for comboboxes ?
My Sub starts as follows as I want to compare the currently selected item in the dropdown with the value in a table:
Private Sub myCombo_AfterUpdate()
If Me.myCombo.Value = Worksheets(8).Range("A4") Then
'do stuff
End Sub
Many thanks for any help with this, Tim.

Related

Userform listbox click code does not trigger

I created a userform in Excel 2016 with two ListBoxes, using the Tools menu. I double clicked them to create subs and inserted code to check whenever one is selected.
Here is the code:
Private sub SaleType_Click ()
If SaleType.Value ="Core" then
'make sale label visible
QTDV.visible =true
' show core option btn
Core.Visible = true
End if
End sub
When I have a ListBox created from the toolbox this works, but every other time the form is run the saletype ListBox will be value null and this is a problem because I have a check to make sure the ListBox is not empty. Code follows:
If saletype = "" then
Dim msg as string Msg = " please select sale type"
Msgbox msg, and vbcritical
End if
If the ListBox presents value null it will not see it as empty and skip the check if I try saletype = null it still skips it.
I searched and it seems creating ListBoxes on the tool box is weird because Excel does not know what kind of control it is. I opted for creating the ListBoxes in VBA.
Private sub userform_initialize()
Dim saletype as msforms.Listbox
Set saletype = me.Controls.Add("Forms.ListBox.1", "SaleType")
But when running the form and selecting any option on the ListBox the SaleType_Click sub does not trigger.
If you want to implement event handling (like SaleType_Click) you need to declare the object with the WithEvents keyword:
Dim WithEvents saletype as msforms.Listbox
And if a variable/property is not set then its value doesn't exist, so instead of empty string ("") you need to validate for NULL - the IsNull function can do that (= NULL doesn't work as = only works with values):
If IsNull (saletype.Value) then
I just had a problem with my listbox_Click not being fired "every other time". Maybe it was when the same selection was desired twice in a row. Anyway, put this in the sheet code for the sheet that is "Show"ing the userform:
userformXXX.listboxYYY.ListIndex = -1
userformXXX.Show
This doesn't work if it is in the userform code.

How would you dynamically identify current control on a Multipage based Form

So what I'm trying to achieve is to display help text in a TextBox everytime a new field is selected (or gains focus). I am working with Excel 2013 and my Form has multiple tabs (multipage form).
So far here is what I know is possible: Everytime a field is selected, I can use one of the events (i.e. Click) to update the help text in help text box (just for info, help text is held on a worksheet and each field has a tag. I use this tag to pull the help text from the worksheet). What I cant figure out (or find on the web) is how to do this dynamically: so when a new field gets focus, maybe there is a form event I can use to get the ActiveControl and pass it to my sub? (which pulls the help text).
I've tried using Myform.Click (and Multipage.Click) event but that doesn't work when I click on a new field or tab to a new field
Please let me know if I can provide more information
Help much appreciated
Unless I misunderstand what you need, why not something like this?
Private Sub TextBox1_Enter()
UpdateHelp TextBox1
End Sub
Private Sub TextBox2_Enter()
UpdateHelp TextBox2
End Sub
Private Sub TextBox3_Enter()
UpdateHelp TextBox3
End Sub
Private Sub TextBox5_Enter()
UpdateHelp TextBox5 'this is on a multipage control
End Sub
Private Sub TextBox6_Enter()
UpdateHelp TextBox6 'this is on a multipage control
End Sub
Private Sub UpdateHelp(ByRef c As Control)
TextBox4.Text = c.Name
End Sub
You could pass ActiveControl, but for controls on a Multipage control the ActiveControl is the parent control and not the TextBox.

Excel ActiveX Combobox shows previous selection when losing focus

I have this code which fills a combobox on Sheet1 with the Name column of Table1 on Sheet2.
Public Sub Worksheet_Activate()
Me.ComboBox1.List = Worksheets("Sheet2").ListObjects("Table1")_
.ListColumns("Name").DataBodyRange.Value
End Sub
Works fine but it has a weird effect when I click off the combobox onto the sheet. The selected entry in the box quickly flashes to the previous entry. For example, the currently selected item is "b" and then I select "c". If I click on the worksheet the entry in the box quickly flashes to "b" before going back to "c".
I've put this code alone in a new file and I still get the same effect. Has anyone else seen this?
Edit regarding reason for Public Sub:
Forgot to include the Workbook_Open code so that Sheet1 is considered Activated when you open the Workbook. But it doesn't matter if I keep that code or not, I still see the effect.
Private Sub Workbook_Open()
Call ActiveSheet.Worksheet_Activate
End Sub
Adding a LostFocus event with code that selects a cell on your worksheet should cause the flicker not to happen when you select a cell after changing the ComboBox's value.
Like the following:
Private Sub ComboBox1_LostFocus()
ActiveSheet.Range("A1").select
End Sub

Checkboxes in a range

I have a sheet with checkboxes and names. I need one specific cell to show only the value of the cell related to the checkbox. For example.
when I press the checkbox for Lorena the cell A1 shows Lorena, if I check the one for Ricardo the cell A1 must show Ricardo. Is there any way to do it? I need to work with a range of 15 records.
Thank you!
An option button is going to work much better in this situation since it sounds like the there will only be one selected value, a collection of checkboxes won't work. The option button will ensure that only one value is selected at any time. I have an example set of code below for a set of three and attached images of it working. In order to achieve 15 records, it would simply be a matter of expanding from 3 to 15 option buttons.
In order to make this example work, simply add three option buttons and leave them with their default name. Then use the "Click" event that they have by default to trigger a function to post their caption into the cell A1. Make sure the option buttons have a caption of the name you want entered.
Option Explicit
Sub PrintName(name As String)
Cells(1, 1).Value = name
End Sub
Private Sub OptionButton1_Click()
PrintName OptionButton1.Caption
End Sub
Private Sub OptionButton2_Click()
PrintName OptionButton2.Caption
End Sub
Private Sub OptionButton3_Click()
PrintName OptionButton3.Caption
End Sub

Get Selected value of a Combobox

I have a thousands of cells in an Excel worksheet which are ComboBoxes. The user will select one at random and populate it.
How do I get the selected ComboBox value? Is there a way to trigger a function (i.e. an event handler) when the ComboxBoxes has been selected?
You can use the below change event to which will trigger when the combobox value will change.
Private Sub ComboBox1_Change()
'your code here
End Sub
Also you can get the selected value using below
ComboBox1.Value
If you're dealing with Data Validation lists, you can use the Worksheet_Change event. Right click on the sheet with the data validation and choose View Code. Then type in this:
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox Target.Value
End Sub
If you're dealing with ActiveX comboboxes, it's a little more complicated. You need to create a custom class module to hook up the events. First, create a class module named CComboEvent and put this code in it.
Public WithEvents Cbx As MSForms.ComboBox
Private Sub Cbx_Change()
MsgBox Cbx.Value
End Sub
Next, create another class module named CComboEvents. This will hold all of our CComboEvent instances and keep them in scope. Put this code in CComboEvents.
Private mcolComboEvents As Collection
Private Sub Class_Initialize()
Set mcolComboEvents = New Collection
End Sub
Private Sub Class_Terminate()
Set mcolComboEvents = Nothing
End Sub
Public Sub Add(clsComboEvent As CComboEvent)
mcolComboEvents.Add clsComboEvent, clsComboEvent.Cbx.Name
End Sub
Finally, create a standard module (not a class module). You'll need code to put all of your comboboxes into the class modules. You might put this in an Auto_Open procedure so it happens whenever the workbook is opened, but that's up to you.
You'll need a Public variable to hold an instance of CComboEvents. Making it Public will kepp it, and all of its children, in scope. You need them in scope so that the events are triggered. In the procedure, loop through all of the comboboxes, creating a new CComboEvent instance for each one, and adding that to CComboEvents.
Public gclsComboEvents As CComboEvents
Public Sub AddCombox()
Dim oleo As OLEObject
Dim clsComboEvent As CComboEvent
Set gclsComboEvents = New CComboEvents
For Each oleo In Sheet1.OLEObjects
If TypeName(oleo.Object) = "ComboBox" Then
Set clsComboEvent = New CComboEvent
Set clsComboEvent.Cbx = oleo.Object
gclsComboEvents.Add clsComboEvent
End If
Next oleo
End Sub
Now, whenever a combobox is changed, the event will fire and, in this example, a message box will show.
You can see an example at https://www.dropbox.com/s/sfj4kyzolfy03qe/ComboboxEvents.xlsm
A simpler way to get the selected value from a ComboBox control is:
Private Sub myComboBox_Change()
msgbox "You selected: " + myComboBox.SelText
End Sub
Maybe you'll be able to set the event handlers programmatically, using something like (pseudocode)
sub myhandler(eventsource)
process(eventsource.value)
end sub
for each cell
cell.setEventHandler(myHandler)
But i dont know the syntax for achieving this in VB/VBA, or if is even possible.

Resources