How to use the controls that are dynamically created?

ABK

New member
Joined
Feb 16, 2017
Messages
4
Reaction score
0
Points
0
Hello friends,

I have created three buttons on my userform using the code. I dont know how i can use those buttons to further initialize some code. For example: CommandButton1_Click() does not exists as the buttons are created programatically.
Your help would be appreciated.

Thanks in advance :)
 
You can set them to a variable that accepts events

Code:
' in UserForm code module

Public WithEvents NewButton As MSForms.CommandButton


Sub MakeRunTimeButton()
    Set NewButton = Me.Controls.Add("forms.CommandButton.1")
    With NewButton
        .Top = 10
        .Left = 20
        .Caption = "Newly Made"
    End With
End Sub


Private Sub NewButton_Click()
    MsgBox "hello"
End Sub
 
The above method only works when you know how many buttons you are going to add.
For a variable number of run-time buttons, you could use a class module to drive the events.
Add a Class Module to the project and name it clsRunTimeButton and put this code in it
Code:
' in class module clsRunTimeButton


Public WithEvents MyButton As MSForms.CommandButton


Public Function CreateButton(Container As Object, Optional Caption As String = "RunTimeButton", _
                                                Optional Left As Single = 0, Optional Top As Single = 0) As MSForms.CommandButton
    If MyButton Is Nothing Then
        Set MyButton = Container.Controls.Add("forms.CommandButton.1")
        With MyButton
            .Caption = Caption
            .Left = Left
            .Top = Top
        End With
    Else
        MsgBox "error, button already exists"
    End If
    Set CreateButton = MyButton
End Function


Private Sub MyButton_Click()
    MsgBox "You clicked " & MyButton.Caption
End Sub

Then code like this in the user form will allow you to as as many buttons as needed.
Code:
' in userform code module


Dim MyRunTimeButtons As Collection


Private Sub MakeNewButton()
    Dim newButton As clsRunTimeButton
    Dim newButtonCount As Long
    
    Set newButton = New clsRunTimeButton
    newButtonCount = MyRunTimeButtons.Count + 1
    newButton.CreateButton Me, "New Button" & newButtonCount, Left:=10, Top:=30 * (newButtonCount - 1)
    MyRunTimeButtons.Add Item:=newButton
    Set newButton = Nothing
End Sub




Private Sub UserForm_Click()
    Call MakeNewButton
End Sub


Private Sub UserForm_Initialize()
    Set MyRunTimeButtons = New Collection
End Sub
 
In the above class module scenario, the code for the button is buried in the class module's MyButton_Click event.
Code:
MsgBox "You clicked " & MyButton.Caption

If you want that code in the user form's code module (along with the code for the other controls' events), you can pass the Click event back to the use form with code like this. (Changed code highlighted)

Note that in the user form code module, the variable ActiveRunTimeButton is a clsRunTimeButton object. ActiveRunTimeButton.MyButton is a CommandButton object.

Code:
' in class module clsRunTimeButton

Public WithEvents MyButton As MSForms.CommandButton
[COLOR=#ff0000]Event Click()[/COLOR]


Public Function CreateButton(Container As Object, Optional Caption As String = "RunTimeButton", _
                                                Optional Left As Single = 0, Optional Top As Single = 0) As MSForms.CommandButton
    If MyButton Is Nothing Then
        Set MyButton = Container.Controls.Add("forms.CommandButton.1")
        With MyButton
            .Caption = Caption
            .Left = Left
            .Top = Top
        End With
    Else
        MsgBox "error, button already exists"
    End If
    Set CreateButton = MyButton
End Function

[COLOR=#ff0000]Private Function UFParent() As Object
    Set UFParent = MyButton.Parent
    On Error Resume Next
    Do
        Set UFParent = UFParent.Parent
    Loop Until Err
End Function

Private Sub MyButton_Click()
    Set UFParent.ActiveRunTimeButton = Me
    RaiseEvent Click
End Sub[/COLOR]



Code:
' in userform code module


Dim MyRunTimeButtons As Collection
[COLOR=#ff0000]Public WithEvents ActiveRunTimeButton As clsRunTimeButton[/COLOR]


Private Sub MakeNewButton()
    Dim newButton As clsRunTimeButton
    Dim newButtonCount As Long
    
    Set newButton = New clsRunTimeButton
    newButtonCount = MyRunTimeButtons.Count + 1
    newButton.CreateButton Me, "New Button" & newButtonCount, Left:=10, Top:=30 * (newButtonCount - 1)
    MyRunTimeButtons.Add Item:=newButton
    Set newButton = Nothing
End Sub


[COLOR=#ff0000]Private Sub ActiveRunTimeButton_Click()[/COLOR]
[COLOR=#ff0000]    With ActiveRunTimeButton[/COLOR]
[COLOR=#ff0000]        MsgBox "You have clicked " & ActiveRunTimeButton.MyButton.Caption[/COLOR]
[COLOR=#ff0000]    End With[/COLOR]
[COLOR=#ff0000]End Sub[/COLOR]


Private Sub UserForm_Click()
    Call MakeNewButton
End Sub


Private Sub UserForm_Initialize()
    Set MyRunTimeButtons = New Collection
End Sub
 
I'd suggeste not to create userforms/userformcontrols/userformcode at run time.
The only thing you should do at run time is making controls visible/invisible.
 
Thanks a lot everyone. I will try it out and get back to you for further queries :)
 
Hello snb,

I took your advice and created the userform with all the controls possible. I make it visible/ invisible according to user's choice using a code in the userform. But now i have an array of textboxes to which i have named according to their column and row number. for example: TextBoxC1R1.Untitled1.jpg
The user will be adding values to these textboxes. and i need to control the values in it. for example: if the enterd value is a number then the textbox should turn green and the other boxes in that particular column should be disabled. How do i do this? Bcoz each textbox has a separate _change menu and i cant think of a way how to link a code to all the textboxes in the array.

Looking forward for your help. Thanks:)
 
Back
Top