Call macro from combobox selection - excel

I have added an activex combobox "ComboBox1" to my excel spreadsheet "Sheet1" and I want to be able to call different macros based on the selection in the combobox. Some of the macro names I have are "MC323", "MC616", "MC813".
So basically you select MC616 from the combobox list I want it to run the MC616 macro.
I have tried searching for answers but nothing has made since to me. Here is what I have so far, which isn't much and I'm sure isn't right anyway.
Option Explicit
Private Sub Workbook_Open()
With Sheet1.ComboBox1
ComboBox1.Clear
.AddItem "MC323"
.AddItem "MC616"
.AddItem "MC813"
End With
End Sub
Sub ComoBox1_Change()
With Sheet1.ComboBox1
Select Case ComboBox1.Value
Case "MC323": MC323
Case "MC616": MC616
Case "MC813": MC813
End Select
End With
End Sub
Sub MC323()
Call MC323
End Sub
Sub MC616()
Call MC616
End Sub
Sub MC813()
Call MC813
End Sub

You have a spelling error, that could be an issue, anyway...
This should go into the Sheet1 module
Sub ComboBox1_Click()
Select Case ComboBox1.Value
Case Is = "MC323": MC323
Case Is = "MC616": MC616
Case Is = "MC813": MC813
End Select
End Sub
This should go into a regular module,
Sub MC323()
MsgBox "MC323"
End Sub
Sub MC616()
MsgBox "MC616"
End Sub
Sub MC813()
MsgBox "MC813"
End Sub
This is in the Workbook Module,
Private Sub Workbook_Open()
With Sheet1.ComboBox1
.Clear
.AddItem "MC323"
.AddItem "MC616"
.AddItem "MC813"
End With
End Sub

It all looks good until you get here:
Sub MC323()
Call MC323
End Sub
Sub MC616()
Call MC616
End Sub
Sub MC813()
Call MC813
End Sub
Subroutine MC323 has only one line and that line says to call subroutine MC323 which has only one line and that line and that line says to call subroutine MC323 which has only one line and that line says to call subroutine MC323 which has only one line and that line says to call subroutine MC323 which has only one line and that line says to call subroutine MC323 which has only one line and that line says to call subroutine MC323 which has only one line and that line asays to call subroutine MC323.
So anyway, you get into a endless recursive loop, which is no good. Don't call subroutine MC323 inside of MC323. Put the code you want ran into the subroutine MC323. Like...
Sub MC323()
MsgBox("Endless recursive loops are bad")
End Sub

I've been wondering why I couldn't get my examples to work - MC323, MC616 and MC813 are also worksheet cell references.
So..... ensure you have a sheet with a codename Sheet1 and an ActiveX combo-box called ComboBox1.
In the ThisWorkbook module:
Private Sub Workbook_Open()
With Sheet1
.ComboBox1.Clear
.ComboBox1.AddItem "MC323"
.ComboBox1.AddItem "MyMacro2"
.ComboBox1.AddItem "MyMacro3"
End With
End Sub
Note the first item will cause an error - 'Cannot run the macro 'MC323'. The macro may not be available in this workbook or all macros may be disabled.
In a normal module:
Public Sub MC323()
MsgBox "1"
End Sub
Public Sub MyMacro2()
MsgBox "2"
End Sub
Public Sub MyMacro3()
MsgBox "3"
End Sub
Finally, in the Worksheet module for Sheet1:
Private Sub ComboBox1_Change()
Application.Run Sheet1.ComboBox1.Value
End Sub
Useful links to help files:
Application.Run Method
Ron de Bruin - How do I use Application.Run in Excel

Related

Worksheet.Activate does not trigger the Worksheet_Activate event

I created macros in vba but they don't work.
In the ThisWorkbook code I wrote:
Private Sub Workbook_Open()
Worksheets("Sheet1").Activate
End Sub
In the code of Sheet1 (Sheet1) I wrote:
Private Sub Worksheet_Activate()
MsgBox ("hello")
End Sub
but when I open the file nothing happens ...
If Sheet1 is already active when you open the workbook, then
Worksheets("Sheet1").Activate
does exactly nothing. Because you cannot activate what is already active.
Test it by adding 2 Sheets Sheet1 and Sheet2. Then select Sheet2 save the file and close it. Now open it again, it will run Worksheets("Sheet1").Activate and this will trigger the Worksheet_Activate properly.
Also note that MsgBox ("hello") should be without parenthesis as it does not return a value to a variable: MsgBox "hello"
An alternative solution is:
Write in a module:
Public Sub Sheet1_Activate()
MsgBox "Sheet1 Activate"
End Sub
In Sheet1 write:
Private Sub Worksheet_Activate()
Sheet1_Activate
End Sub
And in ThisWorkbook write:
Private Sub Workbook_Open()
If ThisWorkbook.ActiveSheet.Name = "Sheet1" Then
Sheet1_Activate
Else
ThisWorkbook.Worksheets("Sheet1").Activate
End If
End Sub
The idea is to have a new procedure Sheet1_Activate that takes the actual code and is triggered by the Worksheet_Activate as well as by the Workbook_Open in case the sheet is already the active sheet.
Sub auto_open()
MsgBox "HueHueHue"
End Sub
You can't activate the same thing twice.

Macro to run when file is protected

I did macro that creates a graph but need to make the file password protected.
Of course, when I protect the file, the macro will stop working.
I inserted the below into my code to unprotect the file, run the code, then protect the file again. As I the code is a function, I had to create two sub procedures, which is maybe the reason why the trick is not functioning.
Any idea how I can fix this?
Option Explicit
Sub protection()
Worksheets("Sheet1").Unprotect "abc123"
End Sub
Function (here is my function code)
End Function
Sub protection2()
Worksheets("Sheet1").protect "abc123"
End Sub
I guess you want to start one sub procedure to do the trick. My example unprotects your sheet, let the function do its magic and protects the sheet.
Option Explicit
Sub protection()
Worksheets("Sheet1").Unprotect "abc123"
Call Function (here may be values for your arguments)
Worksheets("Sheet1").protect "abc123"
End Sub
Function (here may be prameters)
the function code belongs here
End Function
On a protected sheet you can't changed cells which are locked. You may wan't to play around with the attached code:
Option Explicit
Sub SheetSetup()
Range("B3:C7").Locked = False
Range("E3:F7").Locked = True 'This is default
End Sub
Sub Sample_ProtectedSheet()
ClearValues
ChangeAllValues_on_ProtectedSheet
MsgBox ("Only values in ""B4:C7"" are set to ""yes""!")
End Sub
Sub Sample_UnprotectedSheet()
ClearValues
ChangeAllValues_on_UnprotectedSheet
MsgBox ("All values set to ""yes""!")
End Sub
Function ChangeAllValues_on_UnprotectedSheet()
Call Unprotect
On Error Resume Next
Range("B4:C7").Value = "yes"
Range("E4:F7").Value = "yes"
On Error GoTo 0
End Function
Function ClearValues()
Call Unprotect
On Error Resume Next
Range("B4:C7").Value = ""
Range("E4:F7").Value = ""
On Error GoTo 0
End Function
Function ChangeAllValues_on_ProtectedSheet()
Call Protect
On Error Resume Next
Range("B4:C7").Value = "yes"
Range("E4:C7").Value = "yes"
On Error GoTo 0
End Function
Sub Protect()
Worksheets("Sheet1").Protect "abc123"
End Sub
Sub Unprotect()
Worksheets("Sheet1").Unprotect "abc123"
End Sub

How to determine if a macro was called by another macro in excel, and perform code accordingly

This is just an example of what I want to do. I have an elaborate macro that I want to do different things depending on whether it was called by another macro or not.
sub Example()
Call MyCode
end sub
sub MyCode()
If Called by Example GoTo SkipNextLine
Do these things
exit sub
SkipNextLine:
Do other things
end sub
You can create hidden name (which, actually, isn't tied to range). Think of it as global variable. The difference between global variable and this name is that name is persisted in workbook when you close it. When you open workbook again - you can start using it without any initialization. As a bonus, this name won't be displayed in Name Manager. The defining of name is required only once.
Sub SetHiddenName()
Names.Add Name:="Caller", RefersTo:="StartValue", Visible:=False
End Sub
Sub FF()
Names("Caller").Value = "FF"
Call SS
End Sub
Sub SS()
Select Case [Caller]
Case "FF": MsgBox "Called by FF" '...
Case "ZZ": MsgBox "Called by ZZ"
End Select
End Sub
A simple approach would be to use arguments and parameters.
Sub Example()
Call MyCode("Example")
End Sub
Sub Example2()
Call MyCode("Example2")
End Sub
Sub MyCode(Origin as String)
Select Case Origin
Case "Example"
'Do stuff here
Case "Example2"
'Do other stuff here
End Select
End Sub
I made my way to this post wanting a macro that changed things on the sheet, but not wanting to kick off event driven macros. In case it's also useful for someone else, it's possible to turn these off in excel using Application.EnableEvents in the parent macro using:
Sub parentMacro()
Application.EnableEvents = False
'Do stuf here
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
'this now only is called on worksheet changes outside of parent macro,
'as it's disabled while parent runs
'Note: This disables all event macros running, so might not be perfect for all cases
End Sub

Unload me or formname.hide doesnt work excel-vba

In excel-vba i have a form named frmTemplateSelector when I select one of the two options and click on "done", the form doesn't hide!
I am calling frm.show from another module, where in depending on choice, other pop ups will appear.
Private Sub btnDone_Click()
frmTemplateSelector.Hide
Exit Sub
End Sub
Private Sub btn1_Click()
name = "XYZ"
End Sub
Private Sub btn2_Click()
name = "ABC"
End Sub
You can either Unload or Hide an UserForm.
Hide literally only hide the UF
Unload hide and reset all variables in the UF
Private Sub btnDone_Click()
Unload frmTemplateSelector 'or Unload Me
Exit Sub
End Sub
You can also change the UF's name to Me in this code, as it is the UF's code module, like this :
Private Sub btnDone_Click()
Me.Hide
Exit Sub
End Sub

How to runs macros on multiple worksheets

I have several macros so I use call macro to run them simultaneously but it only works on worksheet1 so now I want the macros to run on all worksheets in a workbook. Is there a way whereby i use callmacros to run the first macro for worksheet1 and then the other macros to run on all worksheets.
Sub callmacros()
Call macro1 '(run on only worksheet1)
Call macro2 '(run on all worksheets)
Call macro3 '(run on all worksheets)
End Sub
Pls help. Thanks
In Sheet1
Sub Test1()
MsgBox "1"
End Sub
In Sheet2
Sub Test2()
MsgBox "3"
End Sub
In Sheet3
Sub Test3()
MsgBox "3"
End Sub
In ThisWorkbook
Private Sub Workbook_Open()
Call Sheets(1).Test1
Call Sheets(2).Test2
Call Sheets(3).Test3
End Sub
Hope this helps.

Resources