Мне нужно динамически создавать ярлыки и кнопки, а затем добавлять их во фрейм в пользовательской форме. Как мне это сделать? Кажется, что это должно быть проще, чем есть на самом деле.
Добавление элементов управления во фрейм в пользовательской форме Excel с помощью VBA
Ответы (3)
Следующий код демонстрирует, как вы можете динамически заполнять фрейм в пользовательской форме элементами управления...
В форме, которую я использовал, у меня был элемент управления фреймом с именем Frame1, поэтому в UserForm_Initialize вы вызываете Frame1.Controls.Add для встраивания элемента управления в фрейм. Вы можете установить элемент управления, который возвращается в управляющую переменную WithEvents, которую вы определили в модуле кода UserForm, чтобы вы могли реагировать на события в любых элементах управления, которые вы хотите...
Таким образом, с помощью этого метода вам нужно предварительно написать любой код события, который вы хотите для любых элементов управления, которые вы создаете...
Также обратите внимание, что вы можете размещать и изменять размер элементов управления, даже если свойства top, left, width и height не обязательно появляются в intellisense...
Private WithEvents Cmd As MSForms.CommandButton
Private WithEvents Lbl As MSForms.Label
Private Sub UserForm_Initialize()
Set Lbl = Frame1.Controls.Add("Forms.Label.1", "lbl1")
Lbl.Caption = "Foo"
Set Cmd = Frame1.Controls.Add("Forms.CommandButton.1", "cmd1")
End Sub
Private Sub Cmd_Click()
Cmd.Top = Cmd.Top + 5
End Sub
Private Sub Lbl_Click()
Lbl.Top = Lbl.Top + 5
End Sub
"1"
в конце имени класса в методе add
?
- person Tristian; 03.02.2012
Моя вариация на тему выше. Это только для массива кнопок 4x4. Создайте пользовательскую форму и добавьте это в ее код. Те же концепции можно использовать с вашими ярлыками (или см. предыдущий ответ):
Private cmdLots(20) As MSForms.CommandButton
Private Sub UserForm_Initialize()
For i = 1 To 4
For j = 1 To 4
k = i + (4 * j)
Set cmdLots(k) = UserForm2.Controls.Add("Forms.CommandButton.1", "cmd1")
With cmdLots(k)
.Top = i * 25
.Left = (j * 80) - 50
.BackColor = RGB(50 * i, 50 * j, 0)
.Caption = "i= " & i & " j= " & j
End With
Next j
Next i
End Sub
Метод Add
Чтобы добавить элементы управления в пользовательскую форму или фрейм, используйте add
.
SetControl = object.Add(ProgID [, Name [, Visible ]] )
Первый аргумент будет ссылаться на тип элемента управления, который вы хотите добавить, и это ProgID
, который определяется как
Программный идентификатор. Текстовая строка без пробелов, идентифицирующая класс объекта. Стандартный синтаксис для ProgID: ... ProgID сопоставляется с идентификатором класса (CLSID).
Функциональное решение
Чтобы упростить этот процесс, давайте воспользуемся перечислением, которое поможет нам управлять различными элементами управления.
' List of all the MSForms Controls.
Public Enum MSFormControls
CheckBox
ComboBox
CommandButton
Frame
Image
Label
ListBox
MultiPage
OptionButton
ScrollBar
SpinButton
TabStrip
TextBox
ToggleButton
End Enum
С помощью этого перечисления мы теперь можем легко создать функцию для получения строки ProgID для всех элементов управления.
' Gets the ProgID for each individual control. Used to create controls using `Object.add` method.
' @see https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/add-method-microsoft-forms
Public Function GetMSFormsProgID(control As MSFormControls) As String
Select Case control
Case MSFormControls.CheckBox: GetMSFormsProgID = "Forms.CheckBox.1"
Case MSFormControls.ComboBox: GetMSFormsProgID = "Forms.ComboBox.1"
Case MSFormControls.CommandButton: GetMSFormsProgID = "Forms.CommandButton.1"
Case MSFormControls.Frame: GetMSFormsProgID = "Forms.Frame.1"
Case MSFormControls.Image: GetMSFormsProgID = "Forms.Image.1"
Case MSFormControls.Label: GetMSFormsProgID = "Forms.Label.1"
Case MSFormControls.ListBox: GetMSFormsProgID = "Forms.ListBox.1"
Case MSFormControls.MultiPage: GetMSFormsProgID = "Forms.MultiPage.1"
Case MSFormControls.OptionButton: GetMSFormsProgID = "Forms.OptionButton.1"
Case MSFormControls.ScrollBar: GetMSFormsProgID = "Forms.ScrollBar.1"
Case MSFormControls.SpinButton: GetMSFormsProgID = "Forms.SpinButton.1"
Case MSFormControls.TabStrip: GetMSFormsProgID = "Forms.TabStrip.1"
Case MSFormControls.TextBox: GetMSFormsProgID = "Forms.TextBox.1"
Case MSFormControls.ToggleButton: GetMSFormsProgID = "Forms.ToggleButton.1"
End Select
End Function
И, наконец, давайте создадим функцию, которая добавляет форму или фрейм, используя нашу новую функцию.
' Easly add control to userform or a frame.
' @returns {MSForms.control} The control that was created
Public Function AddControl(userformOrFrame As Object _
, control As MSFormControls _
, Optional name As String = vbNullString _
, Optional visable As Boolean = True _
) As MSForms.control
Set AddControl = userformOrFrame.Controls.Add(GetMSFormsProgID(control), name, visable)
End Function
Прелесть использования подобных перечислений в том, что теперь у нас есть интеллектуальное понимание всех элементов управления, и нам не нужно запоминать их все.
Демо
Чтобы продемонстрировать это, мы можем добавить каждый элемент управления в пустую пользовательскую форму, зациклив перечисление.
Private Sub UserForm_Initialize()
demoAddingControlsToUserform
End Sub
Private Sub demoAddingControlsToUserform()
' Offset used to prevent controls
' overlapping as well as provide
' a height for the scrollbars
Dim offsetHeight As Double
' Add each control to the userform
' and set top to make sure they are not overlapping
' (Although this looks odd, you can actually loop enums this way.)
Dim control As MSFormControls
For control = CheckBox To ToggleButton
With AddControl(Me, control)
.Top = offsetHeight
offsetHeight = offsetHeight + .Height
End With
Next
' Show scrollbars and adjust the height to show
' all the added controls.
With Me
.ScrollBars = fmScrollBarsVertical
.ScrollHeight = offsetHeight + 20
End With
End Sub