VBA Excel Passing an Button as Argument - excel

I want to pass a CommandButton as an argument.
Example:
Sub calc(btn as button)
btn.Caption = "Something"
End Sub
Private Sub CommandButton1_Click()
calc(CommandButton1)
End Sub
Private Sub CommandButton2_Click()
calc(CommandButton2)
End Sub
Is something like the above possible? If yes how can I do it?
edit
Thanks for your response, but I dont get it. So it looks like this now:
Public Sub calc(ByRef btn as Object)
btn.Caption = "Something"
End Sub
Private Sub CommandButton1_Click()
calc(CommandButton1)
End Sub
Private Sub CommandButton2_Click()
calc(CommandButton2)
End Sub
Maybe someone can explain it to me in more detail, because Im very new to VBA.

You need:
Sub calc(btn As MSForms.CommandButton)
btn.Caption = "Something"
End Sub
And you must invoke it following the rules:
calc CommandButton1 // best
call calc (CommandButton1) // ok but verbose
calc (CommandButton1) // type mismatch!
(The type mismatch is because the parentheses evaluate CommandButton1 which results in its default property (a string) which is incompatible with the method argument type)

This is the sub:
Public Sub temp(ByRef cmdb As Object)
cmdb.Caption = "somethine else"
End Sub
This is how you would call it
call sub (commandbutton_1)

Related

Continue procedure if CommandButton is clicked

So far I have used the below VBA in order to continue with a procedure if the user clicked ok in the MsgBox:
Sub Button_Message_Box()
Answer = MsgBox("Do you want to continue the procedure?", vbOK)
If Answer = vbOK Then
Sheet1.Range("A1").Value = 1
Else
End If
End Sub
Now I want to achieve the exact same result using CommandButton1 in UserForm1.
Therefore I tried to go with this:
(1) VBA in UserForm1:
Private Sub CommandButton1_Click()
Unload Me
End Sub
(2) VBA in Modul1:
Sub Button_Procedure()
Call UserForm1.Show(vbModeless)
If CommandButton1 = True Then
Sheet1.Range("A1").Value = 1
Else
End If
End Sub
The VBA goes through but it does not enter the value 1 into Cell A1.
What do I need to modify to achieve the desired result?
I strongly suggest to follow the steps in this article: Rubberduck: UserForm1.Show
Nevertheless, a simple and dirty implementation could be as follows:
The form's code behind:
Add an event to raise when the OK-Cancel button has been pressed passing a boolean value indicating either to proceed or not:
Public Event OnClose(ByVal bool As Boolean)
Private Sub CmdOK_Click()
RaiseEvent OnClose(True)
End Sub
Private Sub CmdCancel_Click()
RaiseEvent OnClose(False)
End Sub
A simple wrapper class:
Here, we just instantiate the form and listen to the OnClose() event.
Option Explicit
Private WithEvents objForm As UserForm1
Private m_flag As Boolean
Public Function Show() As Boolean
Set objForm = New UserForm1
objForm.Show ' No vbModeless here, we want to halt code execution
Show = m_flag
End Function
Private Sub CloseForm()
Unload objForm
Set objForm = Nothing
End Sub
Private Sub objForm_OnClose(ByVal bool As Boolean)
m_flag = bool
CloseForm
End Sub
Calling the wrapper class:
Sub Something()
Dim bool As Boolean
With New FormWrapper
bool = .Show
End With
MsgBox "Should I proceed? " & bool
End Sub
With reference to this question I used a Boolean variable:
(1) Code in UserForm1:
Private continue_procedure As Boolean
Private Sub CommandButton1_Click()
continue_procedure = True
Unload Me
End Sub
Function check_procedure() As Boolean
UserForm1.Show
check_procedure = continue_procedure
End Function
(2) Code in Modul1:
Sub Button_Procedure()
If UserForm1.check_procedure() = True Then
Sheet1.Range("A1").Value = 1
Else
End If
End Sub

How to set variable to name of pressed command button

I'm trying to write a macro that will have many different buttons. I would like all the buttons to trigger the same function but I need to set a variable in the function to identify which button triggered the macro.
I'm not really sure how I should do this. Is there a way I can say like variableA = ClickedButton()?
Any advice is appreciated
Hi , I think something like this should work
Private Sub CommandButton1_Click()
myfunction "b1"
End Sub
Private Sub CommandButton2_Click()
myfunction "b2"
End Sub
Private Sub CommandButton3_Click()
myfunction "b3"
End Sub
sub myfunction (v as variant)
msgbox v
end sub
Try the following
In the button module:
Sub CommandButton1_Click()
myFunction btn_name:= Me.Name
End Sub
In a normal module:
Public Function myFunction(btn_name As String)
MsgBox "The button pressed was:" & btn_name
'do stuff
End Sub
Doing this, you pass the name of the pressed button (Me.Name) to the function as a variable, so it can be used generally inside that function.

VBA Userform ComboBox instantiation

I have a Problem with a Userform which I called "ComboTest2". It only consists of two Comboboxes. If I instantiate the USerform as an object then the following Code doesn't work in the sense that the second combobox of the Userform doesn't contain the desired data.
Sub FillCombo(ByVal row As Long)
Dim rgCities As Range
Set rgCities = Worksheets("Tabelle2").Range("B2:D2").Offset(row)
ComboTest2.ComboBox2.Clear
ComboTest2.ComboBox2.List = WorksheetFunction.Transpose(rgCities)
ComboTest2.ComboBox2.ListIndex = 0
End Sub
Sub FillMain()
Dim ComboForm2 As ComboTest2
Set ComboForm2 = New ComboTest2
ComboForm2.Show
End Sub
UserForm-Code:
Private Sub CommandButton1_Click()
Me.Hide
End Sub
Private Sub CommandButton2_Click()
Me.Hide
End Sub
Private Sub ComboBox1_Change()
FillCombo ComboBox1.ListIndex
End Sub
Private Sub UserForm_Initialize()
ComboBox1.List = Worksheets("Tabelle2").Range("A2:A5").Value
ComboBox1.ListIndex = 0
FillCombo ComboBox1.ListIndex
End Sub
But if I use the "default instantiation" by VBA which means that I change the FillMain Sub to:
Sub FillMain2()
Dim ComboForm2 As ComboTest2
Set ComboForm2 = New ComboTest2
'ComboForm2.Show
ComboTest2.Show
End Sub
Then everything is fine. Why is that so?
Best regards
It's because FillCombo is referring to the userform by name, and therefore to the default instance (you're actually creating a new instance of the form). If that code is not in the userform, and I'm not sure why you would have it outside the form, you should pass the combobox as an argument to it.

VBA Pass Form Controls to Function

All,
I have been struggling with this for a while: is it possible to pass an object to a function?
Here is what I am trying to accomplish:
Get the name of which control was pressed on a form (as object?)
Send the control's name to function "MyFunction" (as reference?)
Disable that same control on "MyFunction"
Called from form1:
Private Sub button1_Click()
Dim caller As String
caller = Form1.ActiveControl.Name
MyFunction(caller)
End Sub 'I'm able to pass it as a string
button1_Click calls MyFunction and passes caller to it:
Private Sub MyFunction(caller As String)
caller.Enabled = False
End Sub
I understand this will not work as a string. How could I possibly do it as an actual object?
Thank you!
There is little problem passing an object to a sub:
Private Sub Disable(c As Control)
MsgBox c.Name
c.Enabled = False
End Sub
Private Sub CommandButton1_Click()
Disable CommandButton1
End Sub
Private Sub CommandButton2_Click()
Disable CommandButton2
End Sub
Private Sub CommandButton3_Click()
Disable CommandButton3
End Sub
In the above I created a userform with three buttons, they say who they are when clicked and are then disabled.
Note that
Disable CommandButton1
can be replaced by
Disable Me.ActiveControl
or even just
Disable ActiveControl
You can even use Variant like so (rough example):
Private Sub CommandButton1_Click()
EnableDisable ActiveControl, "disable"
End Sub
Private Sub EnableDisable(control As Variant, status As String)
If status = "enabled" Then
control.Enabled = True
Else
control.Enabled = False
End If
End Sub
John Coleman's example is better than mine, though.

VBA: call Forms in sub

I have a big problem with getting called a UserForm from a sub.
This is a part of my code:
Sub TestForArray(ObjectName,FormName As String)
Forms(FormName).Controls(ObjectName).List = NewArr
End sub
when I call this sub in a Private Sub, like this
Private Sub UserForm_Initialize()
Call TestForArray("Form1", "ComboBox1")
End Sub
i get the error; "Sub or Function not defined" and higlights the word Forms
what am I doing wrong?
If the goal is to have one Sub that can be called from different UserForms to initialize the UserForm's Controls, you can give the UserForm itself as a parameter.
Example:
Sub TestForArray(oForm As UserForm, sObjectName As String)
aNewArr = [{1,2,3,4,5,6}]
oForm.Controls(sObjectName).List = aNewArr
End Sub
and:
Private Sub UserForm_Initialize()
Call TestForArray(Me, "ComboBox1")
End Sub
Greetings
Axel

Resources