This has to be an obvious thing to do, but I want to use the name of a command button that is pressed in excel as a variable in a macro. The macro would be as simple as setting the value of a cell to the name of the button; So if button captioned "10" is pressed the cells value would be "10", the same macro needs to work for all numeral button captions/names.
Again, sorry if this is obvious!
Try this, works with Forms buttons but not ActiveX buttons.
Sub Button1_Click()
If Not IsError(Application.Caller) Then
Dim obj2 As Object
Set obj2 = ActiveSheet.Shapes.Item(Application.Caller)
Debug.Print obj2.AlternativeText
End If
End Sub
but your question asked about command buttons (the ActiveX variety) and this is more involved, we need to find the shape and then drill in via OLEFormat and two layers of IDispatch to get a reference to the command button, then we use WithEvents to fire event handler.
Option Explicit
'* Inside Sheet module
Private WithEvents mcmd As MSForms.CommandButton
Private Sub Initialise()
Dim obj As Object
Set obj = Me.Shapes.Item("CommandButton1")
Set mcmd = obj.OLEFormat.Object.Object
End Sub
Private Sub mcmd_Click()
Debug.Print mcmd.Caption
End Sub
Sadly you need to initialise code like this for every command button I think.
Related
I have a VBA Excel application with about 200ish buttons. I want them all to change one textbox called "Name" with the caption of the button pressed. I did blur some stuff from the image as these boxes are all real peoples name. How can I do this without having to create 200+ functions?
An example is let's say I have 3 buttons. The three values are foo1, foo2, and foo3. When I click any of the buttons, let's say I click foo2, I want the TextBox to update the value to foo2. I know how to do this but how do I do it without having to manually write a function for all 3 buttons. The textbox value will always be the button value. Now imagine it is 200+ buttons.
Thanks!
Here is how I'd approach it. First add a class module and call it buttonClass:
Option Explicit
Public WithEvents aCommandButton As msforms.CommandButton
Private Sub aCommandButton_Click()
MsgBox aCommandButton.Name & " was clicked"
End Sub
Then in your userform initiation event, use code similar to:
Dim myButtons() As buttonClass
Private Sub UserForm_Initialize()
Dim ctl As Object, pointer As Long
ReDim myButtons(1 To Me.Controls.Count)
For Each ctl In Me.Controls
If TypeName(ctl) = "CommandButton" Then
pointer = pointer + 1
Set myButtons(pointer) = New buttonClass
Set myButtons(pointer).aCommandButton = ctl
End If
Next ctl
ReDim Preserve myButtons(1 To pointer)
End Sub
This will wire up all of your command buttons to display their name on click. You can tweak the logic in the buttonClass to be fancier. Or you can tweak the logic in the initialize event to include on certain buttons (expanding on the "If" part).
Hope that helps!
If i was going to do this (and I'm not sure I would), I would create and populate each button through a loop, which also set up a link to one event handler which could determine what to do.
If each button is created manually and already exist, then I think you need to update them manually.
Another possibility, is to catch another higher-level event such as mouse click and then, from the information provided by that event, work out which button was pressed.
Is it possible to have multipe buttons, lets say 'Button 1' and 'Button 2' run the same VBA code but yield a different result based on the button that was pressed?
For instance when I press button 1 I want it to go to a website, load data and put it on to Sheet 1. But when I press button 2, it goes to the same site and loads it to Sheet 2.
I know I can have multiple instances of the same VBA code (with different names) however I am hoping to simplify the code and prevent it from being overly complicated.
If you are using a Forms button you can assign the same macro and use Application.Caller to return the name/id of the calling button.
Sub Test()
MsgBox Application.Caller & " was pressed"
End Sub
Create one sub to do the work and pass the sheetname as an argument to that sub. I did it with a string variable, but you can do it with a worksheet variable as well.
Sub Button1_Click()
LoadWebsiteToSheet "Sheet1"
End Sub
Sub Button2_Click()
LoadWebsiteToSheet "Sheet2"
End Sub
Sub LoadWebsiteToSheet(sName as String)
'... code to load website to Worksheets(sName)
End Sub
I was leaning more towards brettdj's solution as well
If you assign the same macro to many buttons, you will get different results based on the button name.
You could name the button to the sheet you wanted. Practice with this. Add several buttons and assign this code to them. Click each button to see what happens.
Sub GetButtonName()
Dim Btn As String
Btn = ActiveSheet.Shapes(Application.Caller).Name
MsgBox Btn
End Sub
I kept a userform control button in my worksheet to fire up a macro, which in turn shows a user form, In the form I wish to display the opened files in checkboxes(using the Workbooks collection).I wish to run a macro that performs action for the user selected files only.
So for the button in my worksheet, I have assigned the following macro
Private Sub Button2_Click()
Load MyForm
MyForm.Show
End Sub
At first I kept the below code in the module where my macro sub is there.Since it's not working, I right clicked on user form and selected view code and kept the below code there.But still it's showing the same static designed user form, not the dynamic.I kept breakpoint at both load Myform and MYform.Show() and I stepped through code.It never went into intialize or activate method at all.
Private Sub MyForm_Activate()
'for checking the whether this method is called or not I am trying to change caption
MyForm.LabelSelectFile.Caption = "dhfdfldkfldzjf;zdfkz;d"
Dim mymyWorkBook As Workbook
For Each mymyWorkBook In Workbooks
'code for creating checkbox based on the file name displayed by the workbook collection
Next mymyWorkBook
End Sub
I can't understand why that event is not getting triggered.Please help me to overcome this.Thanks in advance
Even though the name of the form is MyForm, you still need to use userform.
'~~> in your worksheet
Private Sub Button2_Click()
MyForm.Show
End Sub
'~~> In the userform code area
Private Sub UserForm_Initialize()
'~~> Your code here
End Sub
or
Private Sub UserForm_Activate()
End Sub
The best is to always select the event from the drop down, rather than typing it
I have a userform with a basic combobox and command button. When the user hits the command button, I want the UserForm to close, and the value of the combobox to be saved in a variable that can be accessed by a subroutine contained within "ThisWorkbook".
In the UserForm code:
Public employee_position As String
Public Sub CommandButton1_Click()
employee_position = Me.ComboBox1.Value
Unload Me
End Sub
In the "ThisWorkbook" Code
Private Sub GetUserFormValue()
Call Userform_Initialize
EmployeePosition.Show
MsgBox employee_position
End Sub
When "GetUserFormValue()" runs, the UserForm comes up, you can select a value in the combobox and press the command button, but when the MsgBox comes up, it displays "" (Nothing)
What am I doing wrong here?
When you Unload Me, I think you lose all information associated with the module (including the global variable). But if you use Me.Hide rather than Me.Unload, then you can access the value of the form after the routine returns. So try this:
-- userform code includes:
Public Sub CommandButton1_Click()
Me.Hide
End Sub
-- main module includes:
Private Sub GetUserFormValue()
Call Userform_Initialize
EmployeePosition.Show
MsgBox EmployeePosition.ComboBox1.Value
Unload EmployeePosition
End Sub
I think that should work.
I had the same problem, and this is how I resolved it:
If the main code is in a worksheet, and the variable is declared as public in that worksheet (e.g. in Microsoft Excel Objects -> Sheet1 (Sheet1)), the result from "Unload Me" cannot be passed from a UserForm to the worksheet code.
So to solve my problem, I inserted a new Module, and declared my public variable there. I didn't even have to move my code from the worksheet to the module... just the declaration of the public variable.
I hope this works for you too!
Andrew
I have a workbook Wbk1 where a sheet has an ActiveX button. I want to run the button's associated Sub from another workbook,Wbk2. It's not practical to just copy the Sub's code into Wbk2 because it in turn calls a bunch of functions from Wbk1. I tried the following:
Sub pushButton()
Dim obj As OLEObject
Dim btn As MSForms.CommandButton
For Each obj In Wkb1.Sheets("testSheet").OLEObjects
If TypeOf obj.Object Is MSForms.CommandButton Then
set btn=obj.Object
debug.print btn.Caption 'used to test whether or not For loop is picking up button
obj.Activate
SendKeys " "
End If
Next
End Sub
It's not only an inelegant SendKeys() hack, but it doesn't work; the button gets focus but it doesn't get pushed. I know that the For loop is correctly iterating through the objects, including the CommandButton, because I can pick up the caption for the button. How can I click on this button (and thereby run its private Sub) from Wbk2?
EDIT: The actual filename in question is in the format 123A_1.0-2.0.xlsm. I think the periods are causing some trouble with regard to the solutions posted in comments and responses below, because when I remove the periods these techniques are successful.
How about just
Application.Run (wb1.Name & "!MacroName")