Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Assigning Shortcut Key Binding to Add-in (MSWord) 1

Status
Not open for further replies.

rustychef

Technical User
Sep 2, 2004
63
US
I have an add-in template I created for MSWord (basically customized search and replace code). It runs from a dot/dotm template file in the MSWord startup folder. Code works just fine.

My problem is with trying to assign a shortcut key to run the "starting" procedure (SRStagsMain).

Im looking for a VBA code solution, not the "macro wizard" or steps on how to customize it through the TOOLS menu.

I have tried using a few examples off the internet, but I still can't get the shortcut key to work in MSWord 2007 (have not tried the binding on 2003)

I have tried using the following code to bind the shortcut key:

Const myProcName = "SRStags.SRStagMain"
Dim myKeyBinding As KeyBinding

For Each myKeyBinding In KeyBindings
If myKeyBinding.Command = myProcName Then
myKeyBinding.Clear
End If
Next myKeyBinding

KeyBindings.Add KeyCategory:=wdKeyCategoryCommand, _
Command:=myProcName, _
KeyCode:=BuildKeyCode(wdKeyControl, wdKeyAlt, wdKeyX)

I have also tried replacing the KeyCategory argument to
KeyCategory:=wdKeyCategoryMacro
and still no success. Also tried it without using the myKeyBinding.Clear part of the code.

When the code executes the KeyBindings.Add, I receive the following error message: Error Number=5346 "Word cannot change the function of the specified key."

Can someone point me in the right direction?

Below is the code for my AutoExec and SRStagsMain procedures, in case something is not set up in there correctly.

Public Sub AutoExec()
On Error GoTo ERR_HANDLE
Dim oCmd As CommandBarButton
Dim oCtrl As CommandBarControl
CustomizationContext = NormalTemplate
KeyBindings.Add wdKeyCategoryCommand, "SRStagMain", _
BuildKeyCode(wdKeyControl, wdKeyAlt, wdKeyX)
For Each oCtrl In CommandBars("Tools").Controls
If oCtrl.Caption = "SRStags" Then
oCtrl.Delete
End If
Next oCtrl
Set oCmd = CommandBars("Tools").Controls.Add(Type:=msoControlButton, Before:=1)
oCmd.TooltipText = "Search and Replace Symbol tags <SHIFT><ALT><S>"
oCmd.Caption = "SRStags"
oCmd.OnAction = "SRStagsMain"
Set oCmd = Nothing
Set oCtrl = Nothing
EXIT_PROCEDURE:
On Error GoTo 0
Exit Sub
ERR_HANDLE:
Select Case Err.Number
Case 5346
On Error GoTo 0
Resume Next
Case Else
MsgBox "An ERROR has occurred in Sub AutoExec() of Module " & _
"modSRStags!" & vbCrLf & vbCrLf & "(" & Err.Number & ") " & _
Err.Description, vbExclamation + vbMsgBoxSetForeground, _
"WARNING! RUNTIME ERROR (" & Err.Number & ")!"
Resume EXIT_PROCEDURE
End Select
End Sub




The function GetSRStagsFolder looks up the working folder path from a text file

Private Sub SRStagsMain()
FiDO GetSRStagsFolder 'Fetch!
End Sub 'SRStagsMain
 
Could you clarify this more?

The procedure - SRStagMain - is in the add-in, and you are trying to change it with an AutoExec?

If it is in the add-in, why are you using:
Code:
CustomizationContext = [b]NormalTemplate[/b]

This would put the keybinding IN normal.dot. Is this what you are trying to do? I am not quite following.

What exactly is the purpose of the AutoExec?

Gerry
 
Gerry

What exactly is the purpose of the AutoExec?
The purpose of the AutoExec() is to execute any code it contains as soon as the application opens (think of it as an AutoExec.bat file when your computer boots)

The procedure - SRStagMain - is in the add-in, and you are trying to change it with an AutoExec?
My AutoExec() and SRStagsMain() are both in the add-in template. Im not trying to modify the SRStagsMain() procedure.

All Im trying to do is to set up the users MSWord application so they can run SRStagsMain from a keyboard shortcut... like a macro. Im trying to bind it to the keyboard sequence <Ctrl><Alt><X>

If it is in the add-in, why are you using:
I was originally trying to do it without using the statement CustomizationContext = NormalTemplate. Then I saw an example with the statement in it, so I thought I'd give that a try, but neither way worked.

This would put the keybinding IN normal.dot. Is this what you are trying to do? I am not quite following.
It doesnt really matter to me if the binding resides in the NormalTemplate or somewhere else. Since the NormalTemplate is always present, I figured it would work just fine there. Thats why I was trying to bind the keyboard shorcut to the code by using the full name of the procedure: ModuleName.ProcName

I have been able to successfully add SRStagsMain to the TOOLS menu, and the users can execute the program from there, but I would be simplier if they could use a keyboard shortcut or button.
 
What exactly is the purpose of the AutoExec?
The purpose of the AutoExec() is to execute any code it contains as soon as the application opens (think of it as an AutoExec.bat file when your computer boots)

But AutoExec (in Normal) fires (normally) BEFORE your add-in is, well added. So I still can not see the purpose of your AutoExec being IN the add-in.

In any case, the add-in MUST not only be installed, but it must be LOADED....AND it must be OPEN. The global file itself. This is NOT the same as installed and loaded.

An add-in that is installed is not loaded.
An add-in that is installed and loaded, is not open.

The add-in file must be open in Word.

If it is, then
Code:
   CustomizationContext = NormalTemplate
   KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyR, wdKeyAlt), KeyCode2:= _
      BuildKeyCode(wdKeyR), KeyCategory:=wdKeyCategoryMacro, _
      Command:="TemplateProject.modUtilities.BrandNew"
This now binds Alt-Q,Q to the procedure Sub BrandNew in the global (add-in). But again, the global file must be open to do the keybinding. Then, for it work (as a shortcut) the global must be installed and loaded - which if you have it in Startup is not an issue.

My add-ins are dynamic - I load them when I need them, so I do not put them in Startup.

Now I do not use 2007, so I am not sure this works there. But it does work for prior versions.

Gerry
 
Gerry,

Thanks for the information. I can see that I left out some information in my first post. My template is in the ...\Application Data\Microsoft\Word\STARTUP folder in a template called SRStags.dot

This has been my first attempt at creating an add-in, and due to other job constraints I didnt have the time to create a coded version in a .NET language, so I looked for something quick and easy and found an example for using a template:

I also wanted something that would minimize user installation errors (and keep me from going computer to computer). Some users have their own macros, so I couldnt just make it a Normal.dot and overwrite their personal copy, and based on the level of computer knowledge of most of the users, setting up something for them to manually configure is out of the question.

I was assuming that the add-in IS installed and IS loaded because on both a 2003 and 2007 MSOffice computers, after the template is placed in the STARTUP folder and MSWord starts, they can select the add-in from the TOOLS menu and it runs just fine.

So, based on the information you gave me in your last post, Im assuming that AutoExec() is firing too fast (before the template is fully loaded).

If thats the case, should I move the code to another location? Like AutoOpen or my SRStagsMain, then check for the existance of the keybinding... if it doesnt exist, create it?

Eventually I'll replace the whole thing with either a proper add-in or a .NET app. But that'll only happen when more pressing issues are accomplished first. :p

Again thank for your inputs, they are helping

Rusty
 
If your .dot file is in Startup then it will be installed and loaded automatically on Startup.

"Eventually I'll replace the whole thing with either a proper add-in or a .NET app"

This is a proper add-in. And it is properly installed and loaded.

Please re-read what I posted.

You can NOT do the keybinding unless the .dot file is OPEN. Having it in Startup installs and loads the add-in procedures yes, but - again - the file is NOT, repeat NOT, open.

I still can not see the point of your AutoExec. Once you do succeed in doing the keybinding, you do not need to do it every time you start Word.

So, the issue is not with the fact AutoExec fires before the add-in is installed and loaded (although that is the case). The issue is that even with the add-in installed and loaded as an add-in, the add-in file is NOT OPEN. It must be open for your keybinding to work.

As for your commandbar stuff, if this is already in the global template (SRStags.dot), then it will be there once SRStags.dot is loaded.

Did you try my suggestion? Here I will write it out for you. Notice the changes from your keybinding.
Code:
Sub MakeTheKeyBind()
[COLOR=red][b]' assuming the .DOT file is loaded[/b]
' but NOT open
' so [b]open it[/b][/color red]
Documents.Open Filename:= "[i]fullPATH[/i]...\Application Data\Microsoft\Word\STARTUP.SRStags.dot"

CustomizationContext = NormalTemplate
KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyControl, wdKeyAlt, wdKeyX), _
KeyCategory:=wdKeyCategoryMacro, _
      Command:="TemplateProject.[i]your_module_name[/i].SRStagMain"
End Sub

Gerry
 
Gerry,

Thank you very much for the clarification

Documents.Open Filename:= "fullPATH...\Application Data\Microsoft\Word\STARTUP.SRStags.dot"

I was confusing the ability to call the procedures in SRStags (loaded) with the .dot file being open for the application.

Thanks
 
Yes, it is a little confusing. Remember though you only need it open to apply the keybinding. Once that is done, you can close it.

Plus, in theory, you only need to do this ONCE. I am still confused as to why you want to do this every time you start up Word (i.e. using AutoExec).

Gerry
 
I am still confused as to why you want to do this every time you start up Word (i.e. using AutoExec)

I have the code in there because as a minimum, I need the following statements to execute so that the "macro" code will at least show up on the TOOLS menu:

Const myProcName = "modSRStags.SRStagsMain"
Set oCmd = CommandBars("Tools").Controls.Add(Type:=msoControlButton, Before:=1)
oCmd.TooltipText = "Search and Replace Symbol tags in XML files"
oCmd.Caption = "SRStags"
oCmd.OnAction = myProcName


in a non-template based add-in, you have code that runs to install and bind your code to shortcuts, menus, etc.

But, by placing mine in a .dot template, then placing that file in the STARTUP folder, the source code is loaded (via the template), but the user doesnt have any way to access the "macro" code.

For this reason, I need something to "fire" my source code at least once so I can bind the "macro" code to a menu, shortcut, etc. Once that is accomplished at least once, now my user can call the "macro" when ever they need it.

YES, its inefficient, and yes its sloppy to have the AutoExec() "fire" everytime the user opens MSWord, but my only other choice was to write additional code in an AutoExit() that would delete the module with the AutoExec() after the bindings were completed.

I found it much simplier, to have the AutoExec() check to see if the bindings exist first, if not run the AutoExec() code, if the bindings are there then exit from the AutoExec()

Im not aware of any other way to be able to run the binding code to add the "macro" to the TOOLS menu.

I know you showed me about the code to open the template to allow shortcut key bindings, but even that statement must first be called before it can execute, hence the need for the AutoExec() (until a proper add-in is constructed.)
 
in a non-template based add-in, "

There is no such beastie. An add-in is a template (.dot) file.

"But, by placing mine in a .dot template, then placing that file in the STARTUP folder, the source code is loaded (via the template), but the user doesnt have any way to access the "macro" code."

Not correct. The user most certain does have access. If the global (the .dot file) is in Startup, then that global is installed/loaded on Startup. If that global has a menu item that points to (fires) a procedure, then that menu item (and the ability to execute the procedure) is present and working. The user can call the procedure whenever they want to - no other actions (binding or otherwise) is needed.

Gerry
 
Just to prove to myself I am correct, I:

created a new .dot file.

put in one procedure (DemoSplit) that simply creates an array using Split and spits out a messageboxe with the array items.

put the procedure as a menu item ("Demo Split") under Tools

put the .dot file (TestStartup.dot) in Startup

closed Word

started Word

There, under Tools is my item Demo Split. Clicking it executes the procedure.

So your: "by placing mine in a .dot template, then placing that file in the STARTUP folder, the source code is loaded (via the template), but the user doesnt have any way to access the "macro" code" is incorrect.

The user does.

However......you ARE correct that keybinding does not work that way. But menu items, icons on toolbars etc. DO.

Keybinding works as I have stated - opening the add-in (global template), doing the keybinding using TemplateProject, closing the add-in.

Once that is done (once), as long as the add-in is loaded (but it does not have to be open), the keybinding functions.

Gerry
 
Not to get into an argument here but how did YOU "put the procedure as a menu item ("Demo Split") under Tools"? YOU did it because you either wrote a snippet of code, or manually added the menu item by using the Tools "customizations" options and assigned it yourself.

Easy enough, I do the same thing for myself.

NOW, lets take away your programming skills, drop your IQ by 20 points or so, give you an unreasonable "fear" for anything outside of your realm of comfort (i.e. creating a macro, using the options menus, assigning a macro to a toolbar, etc), then some techie-geek comes along gives you a file, then they explain how you install it... all the while speaking a foriegn language that you dont understand, and poof, you're an end user.

But seriously, I have plenty of users that easily follow and understand instructions, and I go to them to test installations and usability of something new (after I work out my own kinks), but for the most part, I have found that the more I automate something, the easier my life is in the long run.

If you take a step back for a moment and look at what you wrote in your last post you will see that the ONLY thing automated about your process is the last step: "There, under Tools is my item Demo Split. Clicking it executes the procedure. " (and the "started Word" part doesnt take too much effort)

If I were installing this for ONE or TWO people, I would walk over and perform the same beginning steps that you did ("Just to prove to myself I am correct"), on each of the ONE or TWO workstations. But thats not the case, I have many end-users.

Since you seem to think that your steps are better than using the AutoExec(), come on over, I have 50+ workstations that you can install my new template on (and deal with all the associated issues). Personally, as a quick fix, I would rather have the AutoExec() "firing" constantly than manually install AND CONFIGURE 50+ MS Word templates... even if it isn't the right way to do it.

Once your superior ego calms down, just keep this in mind...

I THANK you for the help you gave me and the understanding that came with it. Im always willing to learn something new. And I truly APPRECIATE the time you took to explain the process.

Thank you
 
Let's slow down here. My point is that you are putting the .dot file in their Startup.

Yes?

No?

If you are, then that is all you need to do. If you have already put the menu item (however you like0 in the .dot file, then it is already there. Your users do not have to do anything. Nor do you have to do with an AutoExec, as it is already there.

The question comes down to: is the .dot file in their Startup, or is it not?

If it is, then the only action you need to do is once, when you create the .dot file.

All of your mentions appear to be that the .dot file IS in their Startup. It is a simple question, and it is either yes, or no.

You cam make all the comments re: ego you want. If that is the way to interpret what I have been trying to say/do...shrug.

Fine.

Ta-ta.

It is very simple. And it has nothing to do with ego, or IQ.

IF the .dot file is in their Startup, you do NOT have to do anything else, as menu items (but NOT keybinding) can be already in place (in the .dot file). Thereis no need to go around doing multiple things like putting themenu item up there. For you, or your users. If it there in the template in Startup, it is there. Period.

If the .dot file is not there in their Startup, then I apologize, as I understood that it was.

In any case, I am sorry to have offended you. I will not respond further.

Gerry
 
YOU did it because you either wrote a snippet of code, or manually added the menu item by using the Tools "customizations" options and assigned it yourself.

Easy enough, I do the same thing for myself. "


Then do it for the template in the Startup and it is done for EVERYONE that has that in Startup.

Gerry
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top