Is there a way to define a shortcut key (e.g. Ctrl-Y) to start a VBA sub/macro while the VBE window is active? - vba

I'm trying to automate some development steps by using VBA code and want to start those macros with a shortcut key while the VBE window is active/on top. Is there a way to do this? The Macro dialog in VBE does not offer the Options button, which allows to define a shortcut key in Excel proper. I also have not found a way to solve my problem via the VBE toolbar customization.

The F5 key us the shortcut to run this. This can be viewed by hovering the pointer over the "continue" option in the toolbar so the dialog pop up displays.

You cannot define Keyboard shortcuts within the VBE.
As long as your Subroutine gets no parameter:
put the cursor inside the subroutine and press F5
put the cursor outside of any routine and press F5 - you will get a list of Subs that you can start
Enter the name of the sub in the immediate window (Ctrl+G) and press Enter
If your Subroutine expects some parameter (even if it is only optional), only the method with the immediate window works. But you can write a short wrapper routine that calls the subroutine you want to call.

Thanks for the replies on my question. I was aware of the options presented there. As it seems that no real shortcut capabilities are available in VBE, I finally used a custom menu to access the VBA code I want to start during VBE sessions. I now have access to all of them (distributed over several modules and partially with long, description like names) via one macro (I call DM = short for DeveloperMenu) I (still) need to start via the immediate window.
Code below. Of course the specific menu items are custom for my environment and need to be adapted.
Sub Dm(Optional dummy As Boolean)
Call CreateAndDisplayDevelopmentPopUpMenu
End Sub
Sub CreateAndDisplayDevelopmentPopUpMenu(Optional dummy As Boolean)
Dim menuName As String
menuName = "Development"
'Delete PopUp menu if it exist
On Error Resume Next
Application.CommandBars(menuName).Delete
On Error GoTo 0
'Create the PopUpmenu
Call DevelopmentPopUpMenu(menuName)
'Show the PopUp menu
On Error Resume Next
Application.CommandBars(menuName).ShowPopup
On Error GoTo 0
End Sub
Sub DevelopmentPopUpMenu(menuName As String)
Dim MenuItem As CommandBarPopup
'Add PopUp menu
With Application.CommandBars.Add(name:=menuName, position:=msoBarPopup, _
MenuBar:=False, Temporary:=True)
'First add buttons
With .Controls.Add(type:=msoControlButton)
.caption = "&RebuildDefs"
' .faceId = 71
.OnAction = "'" & ThisWorkbook.name & "'!" & "'RebuildAllDefs ""True""'"
End With
With .Controls.Add(type:=msoControlButton)
.caption = "&ToggleAddIn"
' .faceId = 71
.OnAction = "'" & ThisWorkbook.name & "'!" & "ToggleAddIn"
End With
'Second menues
Set MenuItem = .Controls.Add(type:=msoControlPopup)
With MenuItem
.caption = "&Watch"
With .Controls.Add(type:=msoControlButton)
.caption = "&Start watch"
' .faceId = 71
.OnAction = "'" & ThisWorkbook.name & "'!" & "startWatch"
End With
With .Controls.Add(type:=msoControlButton)
.caption = "&End watch"
' .faceId = 72
.OnAction = "'" & ThisWorkbook.name & "'!" & "DeleteAllwatches"
End With
End With
Set MenuItem = .Controls.Add(type:=msoControlPopup)
With MenuItem
.caption = "&HeartBeat"
With .Controls.Add(type:=msoControlButton)
.caption = "&Start HeartBeat"
' .faceId = 71
.OnAction = "'" & ThisWorkbook.name & "'!" & "heartBeat"
End With
With .Controls.Add(type:=msoControlButton)
.caption = "St&op HeartBeat"
' .faceId = 72
.OnAction = "'" & ThisWorkbook.name & "'!" & "stopHeartBeat"
End With
End With
End With
End Sub

TL;DR - You need to change the tools name and add an & in front of the letter you want to be the hotkey. The shortcut will now be Alt + <first letter following &>.
The above method is the only custom shortcut (a.k.a. Accelerator Key) method that is native to the VBE (if I'm not mistaken). I know this question is old, but it ranks much higher than the actual answer, so I thought I'd leave my results for the next person (which will probably be me again next year).
If you customize the VBE toolbar, you should be able to find a button labeled "Modify Selection" (you might need to click the "Rearrange Commands" button first from the Commands tab for a pop-up window with a working "Modify Selection" button if the button on the Commands tab is grayed out). On the drop-down context menu you'll see a textbox for the tool's name. This is the textbox where you add the & in front of the letter in the name that you want to use as the shortcut key. For effectively the same answer but slightly different procedure/implementation, see this answer: https://stackoverflow.com/a/23954017

Related

CommandBarControl executing .OnAction before click on button

The code in my question in inspired by the solution in the answer provided by this question:
How to add a menu item to the default right click context menu
I have a ListBox object on a form showing a list of Actions. I want the user to be able to right click an item of this list to show a contextual menu where he can either :
open a new form where he can view and edit the action (corresponds to the execution of a double click event on the list item)
delete the item from the list
Private Sub List_actions_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single
'set up commandBar
Dim combo As CommandBarControl
'Since it may have been defined in the past, it should be deleted,
'or if it has not been defined in the past, the error should be ignored
On Error Resume Next
CommandBars("RCActionContextMenu").Delete
On Error GoTo 0
'Make this menu a popup menu
With CommandBars.Add(Name:="RCActionContextMenu", Position:=msoBarPopup)
Set combo = .Controls.Add(Type:=msoControlButton)
combo.BeginGroup = True
combo.Caption = "View action" ' Add label the user will see
combo.OnAction = "List_actions_DblClick" 'Add the name of a function to call
Set combo = .Controls.Add(Type:=msoControlButton)
combo.Caption = "Delete action"
combo.OnAction = DelAction()
End With
If Button = acRightButton Then
DoCmd.CancelEvent
CommandBars("RCActionContextMenu").ShowPopup
End If
End Sub
Public Function DelAction()
If Not IsNull(Me.Controls("RCActionContextMenu").Column(0)) Then
CurrentDb.Execute "DELETE * FROM T_ACTIONS " & _
"WHERE ID = " & List_actions.Column(9) & ";"
MsgBox "Action supprimée", vbInformation, "Information"
End If
End Function
Private Sub List_actions_DblClick(Cancel As Integer)
Dim vStatus As String
'Get the record's index of the action
rowNumber = Me.List_actions.ListIndex + 1
id_action = List_actions.Column(9, rowNumber)
vStatus = List_actions.Column(5, rowNumber)
'Open the action
DoCmd.OpenForm "F_ACTIONS", , , "[ID] = " & List_actions.Column(9)
Form_F_ACTIONS.Effective_date.Visible = Effdatefunction(vStatus)
End Sub
The problem i get is that the DelAction() function is executed before the pop-up is shown and i get a run-time error 2465 stating "Microsoft Access can't find the field 'RCActionContextMenu' referred to in your expression."
I've tried repalcing the row combo.OnAction = DelAction() by combo.OnAction = "DelAction". It results in the conextual menu showing itself but nothing happens when i click on either button.
There are a few problems here.
combo.OnAction = DelAction()
This will call the function, as you have seen. You need to set a string here.
combo.OnAction = "DelAction()"
This still won't work, since DelAction() is in your form module.
Either move the function to a public module, with parameters, or hardcoding the object names there,
combo.OnAction = "DelAction(""MyFormName"", ""List_actions"")"
or try (not sure if this works):
combo.OnAction = "Form_YourFormName_DelAction()"
It's the same with "List_actions_DblClick" - the function needs to be called "from the outside", like from the Immediate window.
If Not IsNull(Me.Controls("RCActionContextMenu").Column(0)) Then
You context menu command bar isn't a control, what you want is the list box:
If Not IsNull(Me.Controls("List_actions").Column(0)) Then
or simply
If Not IsNull(Me!List_actions.Column(0)) Then
After deleting an action, you need to requery the listbox.
CurrentDb.Execute "DELETE * FROM T_ACTIONS " ...
Me!List_actions.Requery

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

Generate a worksheet button with preassigned code

I would like to do more or less as the author has intended here:
http://ccm.net/faq/1105-adding-a-vba-commandbutton-with-its-respective-the-code
unfortunately, although the code is written to the correct sheet in Microsoft Excel Objects, the code does not run once the button is pressed. The _Click() is here:
Sub ButtonTest_Click()
MsgBox "I am supposed to work!" 'but i dont, i actually do nothing
End Sub
and the rest of the code is below:
Sub CreateButton()
Dim Obj As Object
Dim Code As String
Sheets("Sheet1").Select
'create button
Set Obj = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
Link:=False, DisplayAsIcon:=False, Left:=200, Top:=100, Width:=100, Height:=35)
Obj.Name = "TestButton"
'buttonn text
ActiveSheet.OLEObjects(1).Object.Caption = "Test Button"
'macro text
Code = "Sub ButtonTest_Click()" & vbCrLf
Code = Code & "Msgbox ""I am supposed to work!""" & vbCrLf
Code = Code & "End Sub"
'add macro at the end of the sheet module
With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.Name).CodeModule
.insertlines .CountOfLines + 1, Code
end With
End Sub
nothing happens when the button is pressed- to my mind it looks like it should fire the event as author intended, any ideas why it doesn't?
You are creating ActiveX components. Unlike form components you cannot name the underlying macros as you wish. The macros' names must start with the name of the ActiveX component followed by and underscore and the even name.
So, if your ActiveX component is named TestButton (according to this):
Obj.Name = "TestButton"
Then the sub's name to handle the click event must be named:
Sub TestButton_Click()
Hence, you'll have to rename the sub or you must change the name for the ActiveX component to match.
Alternatively, you can also implement form controls. The following three lines of code create a new form control CheckBox and assigns your macro to it (when clicked):
Dim chk As CheckBox
Set chk = ActiveSheet.CheckBoxes.Add(390.75, 216, 72, 72)
chk.OnAction = "ButtonTest_Click"

VBA Excel 2010 - How to assign a macro to a command button that was made with a macro

I have a macro that creates a command button however I am unable to assign any macro to the button in the VBA
have looked at this link but its for a userform (but I'm not good enough to be able to change it to suit what I need)
The code I am currently tring is below, I'm guessing I need to add something to the With Statement but I dont know what it would be
Dim MyR As Range, MyB As OLEObject
Dim MyR_T As Long, MyR_L As Long
Set MyR = Range("I3") 'just an example - you get that from your own script
MyR_T = MyR.Top 'capture positions
MyR_L = MyR.Left '...
'create button
Set MyB = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
Link:=False, DisplayAsIcon:=False)
'set main button properties
With MyB
.Name = "MyPrecodedButton" 'important - code must exist ... see below
.Object.Caption = "Load UseForm"
.Top = MyR_T
.Left = MyR_L
.Width = 130
.Height = 30
.Placement = xlMoveAndSize
.PrintObject = True 'or false as per your taste
End With
So from your own link you have posted, your code would look like this:
Set UF = ActiveWorkbook.VBProject.VBComponents("Name_of_the_userform")
With UF.CodeModule
.InsertLines 2, _
"Private Sub " & MyB.Name & "_Click()" & Chr(13) & _
"****HERE COMES YOUR FUNCTION CALL FOR THE BUTTON****" & Chr(13) & _
"End Sub"
End With
But this only works with activeX Buttons. What it does is quite a hack... so if you have a better solution i would not recommend this one. What it does is this: Every ActiveX Button has a onclick function with the following Syntax: "ButtonName_Click()" If you somewhere in your code put this line, it will be executed on click. now what the code does (as in the link which you have posted), is it writes These functions into the userform code.
Use .onAction method
Something like this
Sheets("someVeryFunnySheetName").buttons("someSeriousButtonName").onAction = "macroName"
Here is one example, if you wana to pass parameter to that macro (axleOutputSHeetCounter is some integer i think)
With chartSheet.Buttons("closeOutputSheet")
.OnAction = "'Module7_Axle.closeOutputSheet """ & axleOutputSheetCounter & """'"
.Characters.text = "Delete sheet"
.Characters.Font.Size = 16
End With
edit: for activeX buttons here you can find question with same issue and working solution

Excel VBA Adding 'paste special as value' icon to right click menu (cell context menu customization)

I wonder how to add new icon to right click menu using VBA code which will be the shortcut to paste special as value Excel functionality (which can be found in Excel 2010, but not in 2007). Adding icon itself isn't the problem, but is there generic method (not VBA macro) which could be associated with that icon ?
Below code which add icon associated with ToggleCaseMacro macro (which isn't defined here) :
Sub AddToCellMenu()
Dim ContextMenu As CommandBar
Dim MySubMenu As CommandBarControl
' Delete the controls first to avoid duplicates.
Call DeleteFromCellMenu
' Set ContextMenu to the Cell context menu.
Set ContextMenu = Application.CommandBars("Cell")
' Add one built-in button(Save = 3) to the Cell context menu.
ContextMenu.Controls.Add Type:=msoControlButton, ID:=3, before:=1
' Add one custom button to the Cell context menu.
With ContextMenu.Controls.Add(Type:=msoControlButton, before:=2)
.OnAction = "'" & ThisWorkbook.Name & "'!" & "ToggleCaseMacro"
.FaceId = 59
.Caption = "Toggle Case Upper/Lower/Proper"
.Tag = "My_Cell_Control_Tag"
End With
End Sub
MSDN page with above code
You just need to add:
ContextMenu.Controls.Add Type:=msoControlButton, ID:=370, Before:=2