Академический Документы
Профессиональный Документы
Культура Документы
There are many situations that requires a dynamic userform, to add new comboboxes,
textboxes as other controls. The challenge is to control the position of the new controls, and
relocate the existing controls, to avoid overlappings.
Let's take a look at both situations: in first image, there are no extra controls in form, in the
second image, i added 2 extra lines, each line contains 3 controls (2 comboboxes and a
textbox):
Single Condition
Multiple Conditions
I am a fan of Excel Defined Tables, so this example contains 3 sheets, each with it's own
defined table.
For automation purposes, to make the code shorter and flexible, each table name is identical
to sheet name.
The scenario for building the form is simple: i have 3 tables, i need to be able to search in one
or more columns of the table from the selected worksheet. By default, the form will have
controls for a single condition (where a condition contains a combo for Column Name,
another combo to select from criterias like "start with", "contains", and a textbox with the
value to search for.)
The Add Condition button from form will add another set of controls, to set a new condition
for filtering the table.
Important note:
The code for applying filters is basic, just for demo purposes, you cannot apply more than 1
criteria for the same column; if you apply more than 1 criteria for the same column, only the
last criteria will be applied. The filter can apply multiple conditions to different columns
only!
'move down these 2 buttons, otherwise the new controls will be placed
over them:
Generate.Top = Generate.Top + NextTopValue
CancelReport.Top = CancelReport.Top + NextTopValue
The code is fairly simple, the .Top value for each new control is calculated based on the
NewSet number and the .Top value of the default control. Because we already have a default
condition line 1, the form will be initialized with NewSet value set to 2.
Because we have 3 tables, when you select another worksheet in userform, the column names
of that sheet table will be filled in all Field combos, using a simple procedure, that will extract
all column names from the table and add them to the field combos.
The selection of Worksheet is monitored by that combo's _Change event, which will activate
the selected sheet, and also will change all header names from Field combos:
Application.Goto Worksheets(ComboBox1.Text).Cells(1, 1)
ClearFilters_Click
ReDim ArrCells(1 To
Worksheets(ComboBox1.Text).ListObjects(ComboBox1.Text).HeaderRowRange.Colum
ns.Count)
i = 1
On Error GoTo 0
End Sub
The array created will be passed to the next procedure, that will add all items to ALL combos
with a name similar to "AddCondition*".
Private Sub FillCombo(CBox As ComboBox, Values As Variant)
CBox.Clear
Dim i As Integer
For i = LBound(Values) To UBound(Values)
CBox.AddItem Values(i)
Next
CBox.ListIndex = 0 'display the first item
End Sub
This procedure accepts an array of values to be added for the specified combo, the
comboboxes will display the first item.
Using defined tables will eliminate the problem of locating headers row in each sheet, your
tables can be located anywhere in sheet, this is only one of the many advantages of working
with tables.
I will definitely write more about tables, there are lots of amazing things that can be done
using defined tables...
Have fun :)