This question I asked previously mentions a function named BuildControlCollection
, which I didn't go into the details of since it wasn't relevant. However, because the implementation contains some funky code I'm not 100% on (it completely works, I'm just unsure if it's the best way to do it), I decided to put this up for review too.
Public Sub BuildControlCollection(ByRef ipForm As Form,
ByRef mpCollection As Collection,
ByVal ipControlType As ControlTypes)
The function takes the form that we're building a control collection from, an unset collection object (which will be created and filled), and an enum value to indicate the type(s) of controls to fill the collection with.
Enum ControlTypes
eTextBox = &H1
eComboBox = &H2
eLabel = &H4
eButton = &H8
eFrame = &H10
eRadioButton = &H20
eListBox = &H40
eLine = &H80
eRectangle = &H100
eCheckbox = &H200
eChart = &H400
eAll = &H800
End Enum
Public Sub BuildControlCollection(ByRef ipForm As Form, _
ByRef mpCollection As Collection, _
ByVal ipControlType As ControlTypes)
If Not mpCollection Is Nothing Then
Err.Raise 5000, "Collection has previously been set. This operation would delete the collection."
End If
Set mpCollection = New Collection
Dim lControl As Control
For Each lControl In ipForm.Controls
If ipControlType And eAll Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eButton) And TypeName(lControl) = "CommandButton" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eChart) And TypeName(lControl) = "ObjectFrame" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eCheckbox) And TypeName(lControl) = "CheckBox" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eComboBox) And TypeName(lControl) = "ComboBox" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eFrame) And TypeName(lControl) = "Frame" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eLabel) And TypeName(lControl) = "Label" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eLine) And TypeName(lControl) = "Line" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eListBox) And TypeName(lControl) = "ListBox" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eRadioButton) And TypeName(lControl) = "RadioButton" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eRectangle) And TypeName(lControl) = "Rectangle" Then
mpCollection.Add lControl
ElseIf (ipControlType And ControlTypes.eTextBox) And TypeName(lControl) = "TextBox" Then
mpCollection.Add lControl
End If
Next lControl
End Sub
The thinking behind the last argument of BuildControlCollection
is to allow multiple options to be passed (eg eTextBox Or eButton
) - I've seen this used in the built-in functions such as MsgBox
- the second argument (somewhat inaccurately named Buttons
) of which allows you to specify for eg vbOKOnly Or vbExclamation
to get a messagebox with both an OK button and a warning triangle. I don't know what this is called, so I haven't been able to Google a real implementation, so I've had to make my best guess at it.
I understand that it works by comparing bits - for eg, vbOKOnly
may be 0000 0001
, whilst vbExclamation
may be 0001 0000
, so passing vbOkOnly Or vbExclamation
(0001 0001
) matches on both bits.
Whilst my implementation above definitely works, that enormous If/ElseIf
smells funny. If anyone can tell me what the bit flagging thing used in MsgBox
is called, that would be really useful too.