How to make a reusable button from a macro? - vba

Having a working macro, I'd like to reuse it. Namely, to create a button on a toolbar (with a name + icon) that will launch a macro. Tried some tutorials (example: http://www.officetooltips.com/excel/tips/create_a_toolbar_button_or_menu_item_to_run_a_macro.html), but I'd also like to pack the creation code in some file, so that when clicked, the macro would be installed.
Is there an easy way to do it, and if yes, than how? (the best option would work for both Windows and Mac)

Update 4/20: great comment about the complexity of building an add-in. That being said, I'm sure the old timers here would say that something worth doing is worth doing right :). Here is a short walkthrough for creating an add-in:
(1) Save an xlsm or xlsb file with a name that's easy to increment for versions of your add-in.
(2) Add the following scripts into ThisWorkbook to ensure that you create a menu bar when the workbook is opened and when the workbook is activated:
Private Sub Workbook_Open()
Call CreateMenuBar
End Sub
Private Sub Workbook_Activate()
Call CreateMenuBar
End Sub
(3) Create a new module and add the following code to create, delete and update your menu bar:
Option Explicit
Sub CreateMenuBar()
Dim MenuObject As CommandBarPopup
Dim MenuItem As Object
Dim SubMenuItem As Object
'clear the old menu bar
Call DeleteMenuBar("&MyMenuBar")
'create the menu bar and drop down options
Set MenuObject = Application.CommandBars(1).Controls.Add(Type:=msoControlPopup, _
before:=10, Temporary:=True)
MenuObject.Caption = "&MyMenuBar"
MenuObject.OnAction = "UpdateMenuBar"
'first level menu option
Set MenuItem = MenuObject.Controls.Add(Type:=msoControlPopup)
MenuItem.Caption = "&First Menu Stuff"
'link to first script
Set SubMenuItem = MenuItem.Controls.Add(Type:=msoControlButton)
SubMenuItem.Caption = "&First Script"
SubMenuItem.OnAction = "Script1"
'link to second script
Set SubMenuItem = MenuItem.Controls.Add(Type:=msoControlButton)
SubMenuItem.Caption = "&Second Script"
SubMenuItem.OnAction = "Script2"
'first level menu option
Set MenuItem = MenuObject.Controls.Add(Type:=msoControlPopup)
MenuItem.Caption = "&Second Menu Stuff"
'link to third script
Set SubMenuItem = MenuItem.Controls.Add(Type:=msoControlButton)
SubMenuItem.Caption = "&Third Script"
SubMenuItem.OnAction = "Script3"
End Sub
Sub DeleteMenuBar(MenuName As String)
On Error Resume Next
Application.CommandBars(1).Controls(MenuName).Delete
On Error GoTo 0
End Sub
Sub UpdateMenuBar()
'do special checks, like verifying sheets, in this routine
End Sub
(4) Verify your scripts work and save the file.
(5) Save the file again as an xlam or xla file and distribute that to users. Boom!
--Original post below--
Here's what an add-in looks like on a Windows Excel instance:
And here's what an add-in looks like on a Mac Excel instance:
An add-in can be very handy if you develop many scripts for a fleet of users and want to ensure they're all using the same code.

I posted this on another question, but it wasn't what they were looking for. Would this work for you?
In the options for Excel, click on Customize Ribbon. Above the list of things you can add there should be a dropdown box where you can select Macros. The list should then be populated with macros to add to your ribbon!

Related

how do I create a UserForm in VBA (Word) with code

I would like to program the user form in VBA, so that I can simply pass on the macro and it works for these people. I have read and tried a lot on the internet but there was an error with all solutions. The errors were different depending on the code. Thanks in advance for the help.
The macro is for Word.
My Code:
Dim UserForm1 As Object
Set UserForm1 = ThisWorkbook.VBProject.VBComponents.Add(3)
With UserForm1
.With = 400
.Height = 300
End With
First you need to change the macro setting. and then, you need make small adjustment in your code.
Step 1: Enable VBA project access
Open your workbook
Go to File > Options > Trust Center
Click on Trust Center Settings...
Under Macro Settings, make sure Trust access to the VBA project object model is checked.
Step 2: Dont assign width and height directly, instead use .properties
Sub test()
Dim UserForm1 As Object
Set UserForm1 = ThisWorkbook.VBProject.VBComponents.Add(3)
With UserForm1
.Properties("Caption") = "New Form"
.Properties("Width") = 300
.Properties("Height") = 270
End With
End Sub
EDIT: Above code will work only in Excel. For word document remove the line Set UserForm1 = ThisWorkbook.VBProject.VBComponents.Add(3) and add Set UserForm1 = ActiveDocument.VBProject.VBComponents.Add(3)

How to add a macro to mutiple excel files using VBA

Is there any way to write a VBA Macro to input another VBA Macro into multiple excel workbooks? If so, how do I start?
Any and all help is greatly appreciated.
you'll need a reference first
Microsoft Visual Basic For Applications Extensibility 5.3
And here you go. Have fun
Public Sub AddNewModule()
Dim proj As VBIDE.VBProject
Dim comp As VBIDE.VBComponent
Set proj = ActiveWorkbook.VBProject
Set comp = proj.VBComponents.Add(vbext_ct_StdModule)
comp.Name = "MyNewModule"
Set codeMod = comp.CodeModule
With codeMod
lineNum = .CountOfLines + 1
.InsertLines lineNum, "Public Sub ANewSub()"
lineNum = lineNum + 1
.InsertLines lineNum, " MsgBox " & """" & "I added a module!" & """"
lineNum = lineNum + 1
.InsertLines lineNum, "End Sub"
End With
End Sub
You can also just use the workbook with the code in it as a reference as well. Then you can call the module remotely.
As #BruceWayne mentioned, there is also sotring it in the personal book.
tl;dr - there's a few options that can get you there.
I recommend storing them in the Personal.xslb file which is accessible across Excel.
See this page or this page for more detail, but generally a quick way to get started is:
Press ALT+F11 to open the VBEditor.
Right click the "VBAProject (PERSONAL.XLSB)" and Add a new module
Add your code in the module.
Now, when you go to View --> Macros, you can choose to see those stored in the Personal.xlsb file:
(I "whited out" my macros for privacy, but they'll be listed by name)
Note: If you do not have a "Personal.xlsb", then you must create it. Simply record a new macro, but choose to store it in "Personal Macro Workbook". Then you should see it in the VBEditor.
I would think the easiest way to have the same code in slightly different Excel files is to have one 'template' and save it several times as several slightly different files. Or, if you want to get fancy, you can create an AddIn to make an Excel Macro available to all workbooks.
Option Explicit
Dim cControl As CommandBarButton
Private Sub Workbook_AddinInstall()
On Error Resume Next 'Just in case
'Delete any existing menu item that may have been left.
Application.CommandBars("Worksheet Menu Bar").Controls("Super Code").Delete
'Add the new menu item and Set a CommandBarButton Variable to it
Set cControl = Application.CommandBars("Worksheet Menu Bar").Controls.Add
'Work with the Variable
With cControl
.Caption = "Super Code"
.Style = msoButtonCaption
.OnAction = "MyGreatMacro"
'Macro stored in a Standard Module
End With
On Error GoTo 0
End Sub
Private Sub Workbook_AddinUninstall()
On Error Resume Next 'In case it has already gone.
Application.CommandBars("Worksheet Menu Bar").Controls("Super Code").Delete
On Error GoTo 0
End Sub
This code will be all you need to add a single menu item (called Super Code) to the end of the existing Worksheet Menu Bar as soon as the Add-in is installed by the user via Tools>Add-ins. When the Super Code menu item is clicked a macro (that is within a standard module of the add-in) is run. As mentioned earlier, the above code MUST be placed in the Private Module of ThisWorkbook for the Add-in.
If you want the Super Code menu item added, say before the Format menu item, you could use some code like this.
Option Explicit
Dim cControl As CommandBarButton
Private Sub Workbook_AddinInstall()
Dim iContIndex As Integer
On Error Resume Next 'Just in case
'Delete any existing menu item that may have been left
Application.CommandBars("Worksheet Menu Bar").Controls("SuperCode").Delete
'Pass the Index of the "Format" menu item number to a Variable.
'Use the FindControl Method to find it's Index number. ID number _
is used in case of Customization
iContIndex = Application.CommandBars.FindControl(ID:=30006).Index
'Add the new menu item and Set a CommandBarButton Variable to it.
'Use the number passed to our Integer Variable to position it.
Set cControl = Application.CommandBars("Worksheet Menu Bar").Controls.Add(Before:=iContIndex)
'Work with the Variable
With cControl
.Caption = "Super Code"
.Style = msoButtonCaption
.OnAction = "MyGreatMacro"
'Macro stored in a Standard Module
End With
On Error GoTo 0
End Sub
There would be no need to change the Workbook_AddinUninstall() code in this case.
We have covered ID numbers while working with CommandBars etc in a P rior Newsletter Issue The link to the Microsoft site that has a BIG list of all the ID numbers for working with CommandBars can be Found Here
The above examples actually have the all the menu item code in the Workbook_AddinInstall and Workbook_AddinUnInstall Not a problem when the code is only adding one menu item. If however, you will be adding more then one and perhaps even Sub menus, you should place it in a Procedure (or 2) inside a standard Module. Then use some code as shown below
Private Sub Workbook_AddinInstall()
Run "AddMenus"
End Sub
Private Sub Workbook_AddinUninstall()
Run "DeleteMenu"
End Sub
Then in the standard module put some code perhaps like this
Sub AddMenus()
Dim cMenu1 As CommandBarControl
Dim cbMainMenuBar As CommandBar
Dim iHelpMenu As Integer
Dim cbcCutomMenu As CommandBarControl
'(1)Delete any existing one.We must use On Error Resume next _
in case it does not exist.
On Error Resume Next
Application.CommandBars("Worksheet Menu Bar").Controls("&NewMenu").Delete
'(2)Set a CommandBar variable to Worksheet menu bar
Set cbMainMenuBar = Application.CommandBars("Worksheet Menu Bar")
'(3)Return the Index number of the Help menu. We can then use _
this to place a custom menu before.
iHelpMenu = cbMainMenuBar.Controls("Help").Index
'(4)Add a Control to the "Worksheet Menu Bar" before Help
'Set a CommandBarControl variable to it
Set cbcCutomMenu = cbMainMenuBar.Controls.Add(Type:=msoControlPopup, Before:=iHelpMenu)
'(5)Give the control a caption
cbcCutomMenu.Caption = "&New Menu"
'(6)Working with our new Control, add a sub control and _
give it a Caption and tell it which macro to run (OnAction).
With cbcCutomMenu.Controls.Add(Type:=msoControlButton)
.Caption = "Menu 1"
.OnAction = "MyMacro1"
End With
'(6a)Add another sub control give it a Caption _
and tell it which macro to run (OnAction)
With cbcCutomMenu.Controls.Add(Type:=msoControlButton)
.Caption = "Menu 2"
.OnAction = "MyMacro2"
End With
'Repeat step "6a" for each menu item you want to add.
'Add another menu that will lead off to another menu
'Set a CommandBarControl variable to it
Set cbcCutomMenu = cbcCutomMenu.Controls.Add(Type:=msoControlPopup)
' Give the control a caption
cbcCutomMenu.Caption = "Next Menu"
'Add a control to the sub menu, just created above
With cbcCutomMenu.Controls.Add(Type:=msoControlButton)
.Caption = "&Charts"
.FaceId = 420
.OnAction = "MyMacro2"
End With
On Error GoTo 0
End Sub
Sub DeleteMenu()
On Error Resume Next
Application.CommandBars("Worksheet Menu Bar").Controls("&NewMenu").Delete
On Error GoTo 0
End Sub
You can find all details here.
http://www.ozgrid.com/VBA/excel-add-in-create.htm

Outlook VBA insert line of text

I'm trying to write a piece of code (vba) that inserts a single line in the email i'm composing (open e-mail item). The code below is a first step i took
What works
if I run the code directly from the module (development window), the text is inserted.
What doesn't work
If I add the a macro (vba) in my ribbon and try to run it, nothing happens. The code only seems to work directly form the module (Play button).
What I want
Run macro (vba) from ribbon in active/open item;
Solution = A Module name can't contain a Macro of the same name.
Set font color to e.g. green;
Nice to have: insert text at bottom of page.
Code:
Sub InsertText()
Dim sText As String
sText = "Text to insert"
On Error GoTo ErrHandler
If TypeName(ActiveWindow) = "Inspector" Then
If ActiveInspector.IsWordMail And ActiveInspector.EditorType = olEditorWord Then
ActiveInspector.WordEditor.Application.Selection.TypeText sText
End If
End If
Exit Sub
ErrHandler:
Beep
End Sub
When you are adding it to the ribbon, are you adding it to the mail item ribbon or outlook ribbon? This gets confusing so I'm going to use mostly pictures to describe it.
This is it added to the mail item ribbon and it worked fine: -
If I place the button on the Outlook bar pushing the button does not work: -
This is because as soon as I push the button on the Outlook ribbon, the mail item is no longer the active window.
For confirmation, to add the button to to the mail item window, right click on the ribbon of a mail item and choose 'Customize the Ribbon...'
Press the 'New Tab' button in the lower right, change 'Choose commands from:' to 'Macros' and click on the macro in question from the list below it. Finally, click the 'Add > >' and then 'OK'.

Automatically add a single menu item of an add-in in Excel

I am using Microsoft Excel 2010 for Windows.
I have already developed an add-in addin.xlam, which contains a sub main. addin.xlam is at the right place so that it is visible and selectable via the menu Developer -> Add-Ins. When I open a normal workbook test.xlsm, and press Alt + F11, I can see the code of addin.xlam is loaded.
My aim is to add a single menu item to the menu bar of Excel, to allow users to launch main of add-in.xlam. By following this link, my code in addin.xlam is as follows:
Option Explicit
Dim cControl As CommandBarButtonPrivate
Sub Workbook_AddinInstall()
On Error Resume Next 'Just in case
'Delete any existing menu item that may have been left.
Application.CommandBars("Worksheet Menu Bar").Controls("Super Code").Delete
'Add the new menu item and Set a CommandBarButton Variable to it
Set cControl = Application.CommandBars("Worksheet Menu Bar").Controls.Add
'Work with the Variable
With cControl
.Caption = "Super Code"
.Style = msoButtonCaption
.OnAction = "main" 'Macro stored in a Standard Module
End With
On Error GoTo 0
End Sub
Private Sub Workbook_AddinUninstall()
On Error Resume Next 'In case it has already gone.
Application.CommandBars("Worksheet Menu Bar").Controls("Super Code").Delete
On Error GoTo 0
End Sub
This code is well placed in ThisWorkbook of addin.xlam, it is also visible in test.xlsm. But I can't see any change in the menu bar.
Does anyone know what happens?
The AddinInstall and AddinUninstall events are only fired when the the addin is "installed" or "uninstalled" using the Excel Addin Manager.
IMHO this can lead to problems, so I always recommend using the Workbook_Open and Workbook_BeforeClose events instead.
Charles is right, you need to replace Workbook_AddinInstall() with Workbook_Open(), and replace Workbook_AddinUninstall() with Workbook_BeforeClose().
furthermore, you need CommandBarButton not CommandBarButtonPrivate.
good luck!

Right click on sheet-tabs disabled in Excel

I used this vba code in the ThisWorkbook module to disable the right click menu in an Excel workbook.
Private Sub Workbook_Activate()
With Application.CommandBars.FindControl(ID:=847)
.Visible = False
End With
End Sub
Private Sub Workbook_Deactivate()
With Application.CommandBars.FindControl(ID:=847)
.Visible = True
End With
End Sub
Works like a charm.
Problem is, I can't access the right click menu on tabs in ANY workbook now.
The second part of the code is supposed to turn it back on, I assumed? Yet it doesn't.
Even when I remove the code entirely, no workbook, not even a new one, has a menu when I click right on one of the tabs.
Is there a general vba codesnippet that "resets" excel maybe? Or a general "enable all menus" thing?
REVISION:
This code posted here doesn't disable the rightclick menu, it removes the "delete" option from that specific menu.
omg
Application.CommandBars("Ply").Enabled = True
-.-
Started googling different keywords after the last edit and BAM.
Late again as usual, but tackled with the same problem today. Here's the solution to get your right-click functionality back:
Option Explicit
'
Sub tester()
'
Dim cBar As CommandBar
'
For Each cBar In CommandBars
Debug.Print cBar.Name
If (cBar.Type = msoBarTypePopup) Then cBar.Enabled = True
Next
End Sub
Also note that the below also exist. Some macro from work had them all disabled in my Excel.
Application.CommandBars("Cell").Enabled = True
Application.CommandBars("Row").Enabled = True
Application.CommandBars("Column").Enabled = True