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
Related
I have 10 Sub function macros in "This workbook". Instead of running each macros, everytime i wanted an userform with button, and when I click , it should execute all the Sub function in "This workbook".
I created another function like calling, and I used the following code,
Sub calling()
Call lookup
Call RangeTest
Call datecompare
Call AutoPivot
Call Autochart
Call pivot
Call chart
Call pivot1
End Sub
so, whenever I go for macros, I select Sub calling() and it executes the 10 Sub functions. I would like to have it through a button click. Could anyone suggest how I can do this ?
You should simply add a button from the developper ribbon and assign it to calling().
However, make sure all your macros are in the same module or else you'll have to specify it. If you still get an error it would be interesting to see on what line the error is coming from.
Thank you
I'm assuming the confusion arises because you are trying to use an ActiveX button. If you were using a Form Button, the macro name would appear in the "Assign Macro" popup box. But the ActiveX version doesn't provide the dialog, and because the button exists on the page, doesn't easily see the macros from "This Workbook".
Here's what worked for me.
Within Sheet3:
Private Sub CommandButton1_Click()
Application.Run ("'ThisWorkbook.calling'")
End Sub
I am trying to develop a macro for a publisher document. This macro will, when run, show a pop-up allowing the user to select one of three types of clients, and add different bullet points to a text box depending on which option was selected. I'm having two different problems which I suspect are coming from the same source. Problem number one is that I can't get the button on my User Form to run a different macro when the button is clicked. Problem two is that I've added my macros to one of the toolbars, and nothing happens when I click on them. In both cases, it's simply not running the macro. What am I doing wrong?
UserForm1
Private Sub CommandButton1_Click()
Application.Run ("ShapeTest")
End Sub
Private Sub UserForm_Initialize()
With ListBox1
.AddItem ("Federal")
.AddItem ("State")
.AddItem ("Local")
End With
End Sub
ThisDocument
Private Sub GenerateStatement()
UserForm1.Show
End Sub
Private Sub ShapeTest()
MsgBox ("Hello!")
Application.ActiveDocument.Pages(1).Shapes(1).TextFrame.TextRange.InsertAfter`enter code here`(Chr(13) & "My Text")
End Sub
Why are you using Application.Run("ShapeTest") rather than simply ShapeTest?
I don't have enough information to be 100% sure, but the following should work: To make ShapeTest callable from the userform you do two things:
1) Move it from ThisDocument to a general code module (first Insert/Module in the editor).
2) Eliminate the word Private in front of Sub ShapeTest()-- you don't want this to be a private sub since you want code outside of the module to be able to use it.
On edit: Alternatively -- you could keep ShapeTest() where it is in ThisDocument, get rid of the Private qualifier and in the userform code refer to ShapeTest as ThisDocument.ShapeTest. I prefer using the first method since I tend to like to keep as much code as possible in general code modules (reserving things like ThisDocument for event handlers) but OTOH my VBA experience is mostly Excel with a smattering of Word and there might be reasons to keep the code in ThisDocument in Publisher. I don't know Publisher, but a problem that I have run into in Word at times is I have sometimes accidentally put code in the Normal template that I wanted to go in the document's project. If something similar is possible in Publisher you should double check where your code is living.
I have created a cricket sheet in excel. I have also created a macro which is used to display a message when overs bowled are equal to 20 (A T-20 Match). My problem is that when the over get to 20 no message is shown unless I press the shortcut key. Is there anything which I can do so that whenever overs reach to 20 a message automatically displays.
My code is:
Sub Innings()
If Range("H43") = 20# Then
MsgBox "Innings Completed"
End If
End Sub
Include the following macros in the worksheet code area:
Private Sub Worksheet_Calculate()
Call Innings
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("H43")) Is Nothing Then
Call Innings
End If
End Sub
Because they are worksheet code macros, they are very easy to install and automatic to use:
right-click the tab name near the bottom of the Excel window
select View Code - this brings up a VBE window
paste the stuff in and close the VBE window
If you have any concerns, first try them on a trial worksheet.
If you save the workbook, the macros will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the macros:
bring up the VBE windows as above
clear the code out
close the VBE window
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
To learn more about Event Macros (worksheet code), see:
http://www.mvps.org/dmcritchie/excel/event.htm
Macros must be enabled for this to work!
Gary's Student's code is working well. You just need to write Worksheet_Change and Worksheet_Calculate to the List1 not to the Module1. I add a picture.
I know that even private vba scripts can be called by the user, such that making it "private" in fact only hides its name.
However, is there a way to set up a macro so it is only runnable if you are inside that particular VBA project? Not from Excel and not from any VBScript or the likes.
If you want to lock down the code you could
make the code private so the macro names areen't exposed
lock the protect, and then test that the project is actually unlocked before letting the code run
The sample code below checks that the VBA in the host workbook is not protected before running
Does this meet your needs?
Private Sub TestMe()
Dim objVB As Object
Set objVB = ThisWorkbook.VBProject
If objVB.Protection = 0 Then
Call TestSub
Else
MsgBox "Sorry sport - unauthorised", vbCritical
End If
End Sub
Private Sub TestSub()
MsgBox "Project unprotected - i've been run", vbOK
End Sub
Honestly, there is no foolproof way around it. You can have certain checks but that's all you can do.
If you are sure that a user will not have access to VBA Code then what brettdj suggested is the best way to go ahead. Protect your project. One cannot run a macro from Excel or from outside Excel if one doesn't know the macro name ;)
The basic intention of making a macro Private is not to prevent it from running but making it invisible to the user. Mostly, the only macros that needs to be private in Excel are the inbuilt Worksheet or Workbook events or macros referred by other macros which necessarily don't need to be accessed by the user. A user can still access them from outside VBA if he or she wants to.
Having said that, you can restrict (But not STOP - Not referring to disabling your macro security) the macros from running. Pass an authorization FLAG. Only when it receives an "Authorization", will it run.
For Example
Option Explicit
Private Sub Sample(Auth As Boolean)
If Auth = True Then
'~~> Your macro code goes here
End If
End Sub
Now if you want this macro to be called from VBA then you have to call it like this
Sample True
or
Call Sample(True)
This will ensure that the above macro will only run when you allow it to.
Would this method prevent user from running this from VBS?
NO. It won't. However, it won't run till the time the user specifies or gives the "Authorization"
HTH
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