In VBA (in Excel), differentiating between a listb

2019-09-09 13:04发布

问题:

I have two multi select listboxes in a userform in VBA in Excel.

One contains countries, the other contains cities.

If the user clicks and selects/deselects a country, I would like my script to automatically select/deselect all of the cities located in that country in the second listbox.

Equally, I would like that if the user clicks and selects/deselects a city, it automatically updates the first listbox to highlight only countries for which all of their corresponding cities are currently selected.

My problem is:

By using the OnChange event (OnClick is not available with multi select listboxes), each time either listbox is changed, it will change the other.

In this context, this means that any time a country is changed it will change all of the corresponding cities in the second listbox - for each country the user is effectively limited to selecting all cities or none.

Is there to tell whether the listbox is being changed by the user or by the script? If not, does an alternative method exist which could meet my aim?

Thank you for reading.

回答1:

Application.EnableEvents doesn't have effect on the UserForm objects.

What you need is a form scoped variable (best way is adding a custom property) to store and manipulate the form's event state.

See this example and re-work your code along this, this example is for CheckBox but the same logic applies ListBox, ComboBox etc...

'/ UserForm with 2 CheckBoxes :  CheckBox1 and  CheckBox2
Private m_bEvents         As Boolean

Public Property Let EnableFormEvents(bVal As Boolean)
    m_bEvents = bVal
End Property

Public Property Get EnableFormEvents() As Boolean
    EnableFormEvents = m_bEvents
End Property

Private Sub CheckBox1_Click()

    '/ Custom Event Status

    Me.EnableFormEvents = False
        Me.CheckBox2 = Me.CheckBox1
    Me.EnableFormEvents = True

End Sub

Private Sub CheckBox2_Click()

        If Me.EnableFormEvents Then
            MsgBox "Check box clicked by user."
        Else
             MsgBox "Check box clicked by code."
        End If
End Sub