Unable to run macro from Application.Onkey - vba

I am unable to run macro from Application.Onkey option. The following message is displayed upon pressing TAB key: "Cannot run the macro "C:\...\Desktop\test.xlsm!abc'. The macro may not be available in this workbook or all macros may be disabled."
However, upon pressing Enter key, selection goes 1 row below (as it always does) instead of running the same macro.
I have enabled all macros from Trust Settings and checked "Trust access to the VBA project object model". The file have been saved with xlsm extension.
All of the following macros are in thisWorkbook:
Private Sub Workbook_Open()
Test1
End Sub
Sub Test1()
Application.OnKey "{TAB}", "abc"
Application.OnKey "{ENTER}", "abc"
End Sub
Sub abc()
MsgBox "TAB"
End Sub
Can anyone help me with this one?

To make your code running, move Sub Test1 and abc to a module.
Then if you have 2 Enter keys on your keyboard, press the one on the numeric keypad (the smaller one) and your code should work. To use the big one, use ~ like this:
Sub Test1()
Application.OnKey "{ENTER}", "abc" 'The small one
Application.OnKey "~", "abc" 'The huge one
End Sub
Application.OnKey MSDN

I assume your macro abc() is in "Ten_skoroszyt" ("ThisWorkbook") module, it should be transfered to separate (new) module.

Related

How to assign keyboard shortcuts to multiple VBA macros

I've currently got a list of about 10 macros that each do something different. I basically would like to include VBA code in each of them (or as a separate list) which has the keyboard shortcut to activate each.
I know you can assign a shortcut when you create a macro in the options, but once you've saved the macro as an add-in and closed the file, you can no longer change the shortcut.
I've also tried the application.onkey function, but that only seems to work for 1 macro and I don't see how to add to the list.
Hopefully this makes sense but please ask for clarification if needed
Thanks,
Thomas
This is the code I'm using for the only Application.OnKey that works:
Sub Workbook_Open()
Application.OnKey "^+{\}", "IF_Error_Wrap"
End Sub
Sub Workbook_BeforeClose()
??????
End Sub
You need to repeat the OnKey line for each assignment, and be sure to clear the shortcuts when the file closes using BeforeClose like this:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnKey "^+{\}"
End Sub
If it's an add-in, you could alternatively, and probably more safely, use the Workbook_AddinUninstall() event to clear the keys.

Run a Macro in Excel 2010 using Enter Key, Whether Worksheet has Changed or Not, when Pressed in Particular Range

The short version of the question: How can I make a macro run in Excel 2010 when the user hits the numeric [Enter] key within a given range of cells, and whether or not they've changed the spreadsheet since the last running of the macro?
LONGER VERSION: I have a macro in Excel 2010, and I currently have a button on the sheet that the user presses to run it. The user enters 4 cells of data (in A2:D2) and runs the macro to populate several tables on several sheets with the data. The user may enter several hundred sets of data in a single sitting, and currently leaves the mouse hover over the button, enters the data, and clicks the mouse without moving it to hit the button. I'd like to simplify it by having a press of the numeric [Enter] key run the macro so they can leave their hand on the numeric key area.
I've found this question, but the answer was to use Worksheet_Change and the user didn't need the Enter Key. I also found this question, which used on the [Enter] key, but also required the worksheet to change to be of use.
My user may use the same data multiple times, so I'd like them to be able to press the [Enter] key multiple times. Currently the macro finishes by selecting A2, the first cell with data, so the user can enter new data or press it again to run it again. I want it to run from anywhere in the range of A2:D2, selecting A2 when complete (as it does now), and if [Enter] is pressed while any other cell is selected, or a cell on any other sheet is selected, I want it to move down a cell as it currently does, without running any macro.
Useful names/numbers/things:
Data range will always be in Sheet 1, cells A2:D2.
Macro to be run is named "InsertIntoTables()" and takes no parameters.
Currently no other application-wide macros or events are being used.
The macro already handles empty or improperly-filed cells in my range.
If there is anything else necessary to provide an answer, I'm happy to supply it.
This is just to get you started. Say clicking the button with the mouse runs InsertIntoTables(). I am assuming that InsertIntoTables() is in a standard module. (this makes it easy to call from another sub)
First run:
Sub NumericEnter()
Application.OnKey "{ENTER}", "InsertIntoTables"
End Sub
After this has been run:
touching the numeric keypad ENTER key will have the same effect as mouse-clickng the button
the normal ENTER key will not be affected
To restore the numeric keyboard ENTER key, run this:
Sub ClearEnter()
Application.OnKey "{ENTER}", ""
End Sub
What you must complete:
The numeric keypad ENTER key will call your sub no matter which worksheet is active. YOU must add the logic to detect which sheet is active and take appropriate actions. You must select which ever cell you want when your sub completes. You must remember to run the restore sub before quitting.
EDIT#1:
I have two worksheets; Sheet1 and Sheet2.Sheet1 is the sheet in which I want to use the "special" ENTER key.
I placed the following in a standard module:
Sub NumericEnter()
Application.OnKey "{ENTER}", "InsertIntoTables"
End Sub
Sub ClearEnter()
Application.OnKey "{ENTER}", ""
End Sub
Sub InsertIntoTables()
MsgBox "Inserting"
End Sub
I placed the following in the Sheet1 code area:
Private Sub Worksheet_Activate()
Call NumericEnter
End Sub
Private Sub Worksheet_Deactivate()
Call ClearEnter
End Sub
I placed the following in the workbook code area:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call ClearEnter
End Sub
Private Sub Workbook_Open()
Sheets("Sheet2").Activate
Sheets("Sheet1").Activate
End Sub
The purpose of the Workbook_Open() macro is to insure we start with Sheet1 active and the "special" ENTER key active.
EDIT#2:
Use this instead:
Sub ClearEnter()
Application.OnKey "{ENTER}"
End Sub
Reference:
Tims answer

VBA Center Across Selection Hotkey

I am trying to create a hotkey shortcut for the "Center Across Selection" functionality. The "Merge Cells" functionality looks nice and all, but is horrid to use in practice because of the problems it creates with Macros and such. So, naturally, center across selection is the go-to tool. I use the keyboard to navigate in Excel, so it would be very nice to have a custom shortcut to make this selection easier and faster, since it is used often.
I have some code for this, which I believe should work, but for some reason, it is not:
In PERSONAL.XLSB - Module 1
Private Sub WorkBook_Open()
Application.OnKey "^q", "center_across_selection"
End Sub
In PERSONAL.XLSB - Module 3
Sub center_across_selection()
With Selection
'converts centered text to regular format
If .HorizontalAlignment = xlCenterAcrossSelection Then
.HorizontalAlignment = xlGeneral
'converts regular text to centered across selection
Else
Selection.HorizontalAlignment = xlCenterAcrossSelection
End If
End With
End Sub
Then, once I save this, exit out of the workbook (and all other workbooks as well), reopen the workbook, and try to use the Ctrl+Q shortcut, nothing happens to my cells! Please help me find where I am going wrong.
Move Private Sub WorkBook_Open() from MODULE 1 to the workbook code area.
You've implemented the macro in a standard module; Workbook_Open means to handle the Workbook object's Open event, but a standard module doesn't do that (the ThisWorkbook class/Excel object module does, as shown in Gary's (well, his student's anyway) answer).
So either you move the macro to ThisWorkbook's code-behind, or you rename the macro to Excel4-compatible Auto_Open:
Private Sub Auto_Open()
Application.OnKey "^q", "center_across_selection"
End Sub
Note that this Auto_Open macro will run regardless of the state of Application.EnableEvants when the workbook is opened.

Why does this code work with F1 and not CTRL-M (for example)

I found this code online, and it works like a charm:
Sub Auto_Open()
Application.OnKey "{F1}", "WorkbooksHandler"
End Sub
Sub WorkbooksHandler()
On Error Resume Next
If ActiveWorkbook.Sheets.Count <= 16 Then
Application.CommandBars("Workbook Tabs"). _
ShowPopup 500, 225
Else
Application.CommandBars("Workbook Tabs"). _
Controls("More Sheets...").Execute
End If
On Error GoTo 0
End Sub
I press F1 and it opens a dialogue with all the sheets. I can select the sheet I want and it goes there.
If I change the code just slightly, and use:
Sub Auto_Open()
Application.OnKey "^{m}", "WorkbooksHandler"
End Sub
Now control-m opens with dialogue showing me the sheets, but when I click on the sheet I want excel doesn't navigate there. Why should the trigger make any difference, and make the execution not work?
Edit: By the way, the code also works fine when I run it manually with F5 as well, just not with the onkey control-m.
The problem appears to be that the Control key, when used with OnKey persists through the whole command even though you've no doubt released the key. This has no effect on most things that you do, but inexplicably effects the More Sheets popup. Take this code
Sub Auto_Open()
Application.OnKey "^m", "WorkbooksHandler"
End Sub
Sub WorkbooksHandler()
SendKeys "{RIGHT}"
End Sub
All that does is press the right arrow key. But it has the effect of pressing Ctrl+Right which takes you to the edge of you worksheet (for a blank worksheet). So the Control part of ^m is sticking around through the execution of WorkbooksHandler.
This happens manually also. Hold down the control key, right click on the sheet navigation buttons, select More Sheets, select a sheet. It doesn't move to that sheet when you have Control held down.
I tried all manner of SendKeys, OnTime, and DoEvents, but couldn't trick Excel into releasing the Control key. I'll bet you could find a Windows API that would do the trick, but it's probably easier to simply pick a key combination that doesn't use Control.
Make sure
Sub WorkbooksHandler()
On Error Resume Next
If ActiveWorkbook.Sheets.Count <= 16 Then
Application.CommandBars("Workbook Tabs"). _
ShowPopup 500, 225
Else
Application.CommandBars("Workbook Tabs"). _
Controls("More Sheets...").Execute
End If
On Error GoTo 0
End Sub
is pasted in Modules,
Then
Compile and Run the Auto_Open() manually then try the shortcut

VBA. What is incorrect in this code?

Searching found code like this
Sub Workbook_Activate()
Application.OnKey "+^{RIGHT}", "YourMacroName"
End Sub
However, when I tried, I got
How to create procedure?
I did this
Sub YourMacroName()
Selection.Copy
Sheets("V").Select
End Sub
Sub Workbook_Activate()
Application.OnKey "+^{RIGHT}", "YourMacroName"
End Sub
Got the same error
What would be correct code? Or where would be tutorial for dummies? Found some examples, but they does not work
I see my tags were modified to excel and excel-vba. But I do not use excel. Use Kingsoft Office
Changed Application.OnKey "+^{RIGHT}", "YourMacroName" to .OnKey Key:="^+M", Procedure:="YourMacroName"
and got
Then changed to OnKey Key:="^+M", Procedure:="YourMacroName" (removed .) and got error Named argument not found. And get selected Key:=
In "ThisWorkbook", you will run code that is triggered by an event. I suggest you also put it in Workbook_Open instead of Workbook_Activate as you only need to store the shortcut once.
So, in the VB Editor, open the "Project Explorer" if it is not (CTRL+R) and find "ThisWorkbook" in the folder "Microsoft Excel Objects".
Here the code should look like this
Private Sub Workbook_Open()
' CTRL + SHIFT + RIGHT
Application.OnKey "+^{RIGHT}", "YourMacroName"
End Sub
Since, inside a Module (In the Project Explorer, right click on the folder "Modules" and select Insert > Module), put the macro "YourMacroName"
Sub YourMacroName()
Selection.Copy
Sheets("V").Select
End Sub
Oh, and you should probably rename your procedure "YourMacroName" for something more obvious...