I started learning VBA and I don't understand why some macros copy-pasted from the internet do not show up in the run macro menu (Alt-F8).
Below there are 2 macros, but only the second one is showing. Why? And how do I fix it?
Sub Test1(ByVal Target As Hyperlink)
'...
End Sub
Sub Test2()
'...
End Sub
Macros with arguments are not available in Macros list because they cannot be run alone instead they are called by another macro by passing the required arguments.
If a Sub declaration contains parameters it will not show there.
You cannot call macros that have parameters as you are describing. If you need to have a parameter, you can take it out and then have the user input the value.
Sub Test1()
Dim hyperLink As String
hyperLink = InputBox("Please input hyperlink", "My Parameter")
'...
End Sub
Alternatively, if the hyperlink is in your document, grab the value from your document instead.
Here are my 5 cents - if you give an optional parameter, you will be able to call the sub routine, even if it will not be shown among the ones which you can chose from.
Write aaaaTestMe and press Run.
Public Sub aaaaTestMe(Optional lngA As Long = 8)
Debug.Print lngA
End Sub
You can call an even private macro from any excel object you can assign a macro, calling it this way:
'MyWorkbook'!'MyModule.MyProcedure "MyParameter1"'
(be careful with single quotes: ' around procedure name with parameter)
Related
I just finished some VBA and I was wondering if there is a way to hide certain macros on Excel.
I need the user to run a certain macro and only that one, but it shows all the sub macros in Excel. I want to hide the unnecessary macros from the user so that way the user doesn't accidentally click on the wrong one.
You can also do this by placing the macros you want to hide in a separate module and using Option Private Module at the top of the module before the code. The macros will still be available to your project but will not appear in the Macros seen by the user when he clicks the Macros button.
You can either create a button in the ribbon to run the macro, or you can add "Private" before each "Sub" in the VBA editor that you don't want the user to easily access.
To subjectively 'hide' certain sub procedures (i.e. 'macros') from the (Alt+F8) Developer, Macros dialog use an optional non-variant parameter that means nothing.
Sub meh(Optional w As Worksheet)
Debug.Print "hello world"
End Sub
The meh macro will not show up in the list of macros to run. If you dim the parameter as variant it will show in the list. This is likely due to a optional variant parameter being able to use the IsMissing function. It will also not be able to be run from the VBE with F5 or stepped through with F8.
The test sub procedure will run the code correctly.
Sub test()
meh
End Sub
Sub meh(Optional w As Worksheet)
Debug.Print "hello world"
End Sub
I want to call the following sub with a button from my excel sheet but it doesn't appear in the list when you try to assign a macro. I also call it from a bigger macro, in which case I don't want to show the "Finished" message box. Hence I have the DontShowMsgBox boolean argument.
Sub InteriorDumbCopyExport(DontShowMsgBox as Boolean)
'do stuff...
If DontShowMsgBox Then
MsgBox "Finished."
End If
End Sub
It's when I add the argument in that I can no longer see it in the list. Is there an easy way around this?
I want to call the sub directly as I have to call it from a shape so can't use an ActiveX button. I haven't found anything in my searching so far but feel there must be a solution, otherwise what is the difference between a function with an argument and a sub with an argument?
You can indeed do that. In the Assign Macros dialog, simply type the name of the macro and the argument, all enclosed in single quotes. For example:
'InteriorDumbCopyExport True'
Note however that this can cause problems if your workbook is saved as an xlsb file (I don't know why).
In this particular case though, I'd just make the argument optional and default to whichever value you want the shape to use. Then you just use the macro name in the Assign Macros dialog without adding a parameter.
Simply call your button sub with another sub:
Sub test() 'call with your button
Call InteriorDumbCopyExport(DontShowMsgBox as Boolean)
End Sub
Another way would be to know the source of your DontShowMsgBox. As a public variable, you could set it in front of executing the macro and then directly use it within having no arguments for the call itself.
In any module:
Dim DontShowMsgBox As Boolean
And if you only need it for debugging then make it a Const which will only be true if you want it to.
For a FORM control that's normal behaviour as you cannot assign a Sub depending on parameters as the button wouldn't know which parameter to hand over (for a similar reason you can't link functions to buttons), whereas an ActiveX button would create its own Sub (e.g. Private Sub CommandButton1_Click()) within the code space of the worksheet it appears.
So use a Sub without parameters for the button to call, within the sub determine the actual condition of DontShowMsgBox and call another Sub doing the job into which youdeliver this parameter.
I have a macro that goes through column(s) and removed numbers from all cells in the range. I would like to add an optional parameter, so I can call the sub while telling it which columns to run on. Here's what I have:
Sub GEN_USE_Remove_Numbers_from_Columns(Optional myColumns as String)
The idea being I can call it from another sub, like this GEN_USE_...Columns("A B C")
But, I can't run that from the VB Editor, nor can I see that macro in the Macro Window (when clicking View --> Macros). Why not? Why do I have to call it with a parameter (even GEN_USE_...Columns("")) I can't just call GEN_USE_...Columns() anymore.
I've seen that you can add = Nothing to the end, to set a default value if none is given. I've tried that () but it didn't do anything.
I guess my question is A) How come I can't see my macros that have Optional parameters, in the macro window? and B) Why can't I call the macro with parameters directly from the VB Editor? I have to actually create a sub, then I can call the macro within that sub. No more just highlighting some text and hitting "Play".
I know the two issues are probably related, so any insight would be appreciated!
(PS: I know we're supposed to post code, but I don't think that's very relevant. Of course, if you'd like to see it, let me know and I'll update).
Use Optional myColumns as Variant to show it in the Run Macro ([alt]+[F8]) dialog. Alternately, leave it hidden; you can type the name and click Run. The variant type is also the only one that responds properly to the IsMissing function.
Sub GEN_USE_Remove_Numbers_from_Columns(Optional myColumns As Variant)
If IsMissing(myColumns) Then
myColumns = Intersect(Selection.Parent.UsedRange, Selection).Address '.address 'cause you were using a string
End If
Debug.Print Range(myColumns).Address(external:=True)
End Sub
You can call the sub with parameters from the VBE's Immediate window ([ctrl]+G).
A Sub with ANY parameters, optional or not, cannot be run directly and can only be called from another Sub or Function
Best option is to write a wrapper Sub that will appear in the Macros window
Sub USER_Remove_Numbers_from_Columns()
GEN_USE_Remove_Numbers_from_Columns
End Sub
I am in Outlook 2010 in Windows 7 writing in VBA and want to pass the name of a macro (or sub routine) as a string variable to another sub routine and have that routine run the macro. In Word you can do this with
Application.Run MacroName:=strMacroName
Where strMacroName is a string variable with the name of the macro. That approach does not work in Outlook 2010. How can I accomplish the same thing?
I tried
Call Application.strMacroName
Call strMacroName
strMacroName on its own line
Outlook.Application.strMacroName
None of those things worked.
I just upgraded to Outlook 2010 and so can no longer use keyboard shortcuts to run custom code for handling email. So to restore some version of that functionality I have created code to present a dialog box with my most common macros. The code is fairly clean to modify as time goes along and pass along the name of the macro I want to run but I used to be able to run that routine in one command (Application.Run MacroName:=strMacroName).
Now I have to include a long switch statement to accomplish the same thing. Not nearly as simple.
Thanks!
CallByName seems the only way to go.
With this code in ThisOutlookSession:
Public Sub TestFoo()
Dim testClass As New TestClass1
CallByName testClass, "TestMethod1", VbMethod
End Sub
And this code in TestClass1:
Public Sub TestMethod1()
MsgBox "huzzah!"
End Sub
Calling ThisOutlookSession.TestFoo gives you the expected message box.
As far as I can tell, the only way to run a named macro programmatically in Outlook (without using custom Classes, as the other answer here does) is to create a temporary CommandBarButton, execute it, and immediately delete it. This works in Outlook 2013 even with the Ribbon:
Public Sub runProc(procToRun As String)
With Application.ActiveExplorer.CommandBars.Add("Custom", temporary:=True)
With .Controls.Add(msoControlButton, 1, , , True)
.OnAction = procToRun
.Execute
.Delete
End With
.Delete
End With
End Sub
I know this is an old question, but I was unable to find this exact answer myself in late 2017, so hopefully it will help someone else. Please note that this will NOT run macros that are in ThisOutlookSession...your macro needs to be in a code module.
I am trying to write a macro that will be attached to a series of buttons in an Office 2010 backstage tab. Depending on the button clicked the Macro should be called with different parameters.
The issue I am having is that if the Macro is defined as having parameters then VBA will display the "Macros" dialog box, with no Macros listed. Removing the parameters from the declaration will allow the macro to run, but it needs the Macros to make sense.
The VBA being used is below:
Sub NewDocs(docType As String, docTemplate As String)
Dim sMyShellCommand As String
sMyShellCommand = "C:\NewDocs.exe " & docType & docTemplate
WordBasic.Shell (sMyShellCommand)
End Sub
Any ideas
If I've got your question right....
Because there is no place in the Macros dialog box for entering parameters, the macros with parameters are simply not shown.
If you want to make them visible in the dialog box, you can enumerate those functions you need (and I hope it is not a big number).
For example,
Sub NewDocs1
Dim docType As String
Dim docTemplate As String
docType = "the type you want"
docTemplate = "the template you want"
NewDocs docType, docTemplate
End Sub
In addition, as you said in the question, you wanted the macro to run when buttons were pressed. Then there is no need to make the macro visible in the dialog box (which saves your labor). Simply associate it with the button with correct parameters.
You can pass arguments from the Macro dialog. For example, if you have this macro
Sub myMacro(n As Long)
MsgBox n
End Sub
To run it, enter
mymacro 1000
... and press the Run button.
You can't call functions or subs with parameters from UI components, just subs without parameters. The best solution is to create a parameter free sub for each button you need to associate with, and call the parameterized sub or function from inside each sub