Can I Use VBA to register global templates?

L

Laura

Does anyone know how to use VBA to write a windows registry key that tells
Word where a global template is located?

My Problem:
I have several workgroup templates that contain references to one global
template which contains a ton of code I use again and again from my workgroup
templates.

As I create the templates, I use "Tools, References" to set the references.
At that point I am logged in as myself and my global template is in the
default word startup folder (in the user profile).

(I want to keep the folder in the default location so I am not affecting
other people who may also be programming for Word and expect to put their
templates there.)

WHAT IS HAPPENING: Several different people may log onto any given computer.
As they do, a login script copies their templates into place for them. WHEN
THIS HAPPENS, sometimes my reference gets broken. It seems it is not looking
to the current startup folder for the global template -- rather it looks to
the other person's location. Internet research tells me when Word looks for
referenced, it looks in a location listed in a registry key for that template
first.

I tried using vba to look for broken refs and fix them, but this isn't
working because my templates crash with a "can't find project or library"
compile error due to other code in them, before they can even run the "fix
references" code.

I BELIEVE the problem is that the windows registry key for the global
templates is still listing the template in the previous users profile and it
is either an old version of the template, or not in a "trusted" location and
won't load due to macro security.

If I could run a line of code in an autoopen macro in my global template
that sets that windows registry key to the current users Word startup
directory I THINK that would fix the problem. But I have no idea what they
key is or how to write to the registry.

Sorry so long! Please help...!!!!
 
G

Graham Mayor

This is a tricky one

By default the startup folder is

C:\Documents and Settings\<UserName>\Application Data\Microsoft\Word\STARTUP

however if the location is changed for the user, that location is written to
the registry key

HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Options\STARTUP-PATH

where 11.0 is the Word version - here 2003.

Only one startup path will be active for a given user.

Rather than mess around with the registry, wouldn't it be simpler just to
load your global template from its present location? eg

On Error GoTo LoadAddin:
AddIns("D:\path\add-in name.dot").Installed = True
Exit Sub
LoadAddin:
If Err.Number = 5941 Then
AddIns.Add FileName:= _
"D:\path\add-in name.dot", Install:=True
End If


--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
 
L

Laura

Graham,

Thanks for your reply.
Would I put the AddIns("D:\path\add-in name.dot").Installed = True code in
my startup template, or the templates referencing it?

So far, all I have done to "load" my startup templates is drop them in the
startup folder. I have never used the AddIns("D:\path\add-in
name.dot").Installed = True line of code. I'm going to try putting this in
my startup templates autoexec to see if it helps.

If it goes in the Workgroup templates though, the problem is they crash with
a compile error before any code can run because they see my references to the
startup template and say "can't load library."

BTW: I am only using the default word startup location for each user. The
problem seems to occur after a second person logs in on the machine. I'm not
sure exactly how it happens, but it often breaks my reference. If I look
under file/options/startup the location is as it should be, but it seems the
vba code is looking in the old users path for the template. That's why I was
thinking that if I forced the startup path into the registry it would look in
the right place (I read that it looks there before looking in the actual
startup dir.) But you're right -- messing with the registry is not really
something I want to do...

Again, thanks so much for your help!

Laura
 
G

Graham Mayor

Without having your installation and code to test, I would put the code in
the template that calls your add-in. Then if users start by double clicking
a file from Explorer you can be sure that it will have run and that it will
have made the add-in code available from wherever it is stored.

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
 
L

Laura

Graham Mayor said:
Without having your installation and code to test, I would put the code in
the template that calls your add-in. Then if users start by double clicking
a file from Explorer you can be sure that it will have run and that it will
have made the add-in code available from wherever it is stored.

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
 
F

fumei via OfficeKB.com

"Would I put the AddIns("D:\path\add-in name.dot").Installed = True code in
my startup template, or the templates referencing it?"

In the file that uses it.

Global templates can be anywhere. They do not have to be in any of the Word
"known" folder locations, nor in the Word registry settings. The only
purpose in having a global template in Startup is to have it load
automatically, on Startup. The ONLY reason.

Any Word document can call/load a global template. Global templates can be
added, and removed, dynamically.

Say you have a template (.dot) file. The user goes File > New and selects
the template in order to clone a new document from it. In THAT template file,
there can be an instruction to load a global template.

Global template are, and should be used as, code containers. Nothing more.

So say the template the user is cloning needs code from a code
container/global template. In the template file - say YaddaYadda.do - you
could have::

Sub Document_New()
Application.AddIns.Add _
FileName:="C:\temp\Temp3\TestAdd1.dot", Install:=True
End Sub

Now any document cloned from YaddaYadda.dot will add, AND load, the file
TestAdd1.dot as an Addin (global template), or code container. The file
location of that loaded addin can be anywhere you like.

Say you have a bunch of templates:

blahblah.dot
yipeee.dot
gottaHaveIt.dot
financialCrap.dot

Say, they are all different, BUT, some code, some procedures, are common to
them. They all need Sub AbsolutelyRequired(), Sub IChokeWithoutThis(), Sub
Whatever(), Function ProperFormatCellText() As String.....

Those can be placed into a code container, a global - say, MeMeMe.dot. Each
of those different templates, when cloning a new document, can Add, and load,
the code container, the addin.

Sub Document_New()
Application.AddIns.Add _
FileName:="X:\Blah\MoreStuff\temp\Temp3\CompanyAddins\MeMeMe.dot",
Install:=True
End Sub

Voila. The Addin is added, and loaded.

For memory efficiency, you could also have a procedure in the originating
template that UNloads the global.
 
F

fumei via OfficeKB.com

Just to expand further, you can add a global into the Addin list, load it,
run a procedure, then unload it, AND delete it from the Addin list...all with
one procedure. Like this:

Sub AddLoadRunDelete()
With Application
.AddIns.Add _
FileName:="c:\temp\temp3\testadd1.dot", Install:=True
.Run MacroName:="FromNewAddin"
.AddIns("C:\temp\temp3\testadd1.dot").Delete
End With
End Sub

This:

1. adds the "global" - but really, it is a code container - testadd1.dot as
an Addin

2. Installs (loads) it

3. executes a procedure in it - Sub FromNewAddin

4. unloads it and deletes it from the list.

You could also just unload it, and keep it in the Addin list with

.AddIns("C:\temp\temp3\testadd1.dot").Installed = False
 
F

fumei via OfficeKB.com

I guess my point is this.

A global template (IMO, a code container) can be anywhere on the network. It
does NOT have be in any file location known to Word. It does NOT have to
known to the registry.

There are, in fact, advantages to not putting one into any place known to
Word. It makes it (and therefore its code) accessible to any user with Read
permission on the folder that has the file. Which means access to the global
file itself can be controlled at the OS level. It means the global is
accessible (again as long as the user has Read permission) regardless of
local user settings, with no need for putting it in Startup, or Workgroup
templates, or UserTemplates.

Note: if a global is Added with Addins.Add, and it already is added, there
is no error.
 
L

Laura

fumei via OfficeKB.com said:
Just to expand further, you can add a global into the Addin list, load it,
run a procedure, then unload it, AND delete it from the Addin list...all with
one procedure. Like this:

Sub AddLoadRunDelete()
With Application
.AddIns.Add _
FileName:="c:\temp\temp3\testadd1.dot", Install:=True
.Run MacroName:="FromNewAddin"
.AddIns("C:\temp\temp3\testadd1.dot").Delete
End With
End Sub

This:

1. adds the "global" - but really, it is a code container - testadd1.dot as
an Addin

2. Installs (loads) it

3. executes a procedure in it - Sub FromNewAddin

4. unloads it and deletes it from the list.

You could also just unload it, and keep it in the Addin list with

.AddIns("C:\temp\temp3\testadd1.dot").Installed = False
 
L

Laura

Sorry, Somehow I posted a reply that was all your comments but not mine.
(Gads, if I can't handle posting a comment, how am I gong to work with VBA!)

ANYHOW -- Fumei -- I tried this and it seems to be working!!!! Mostly...

What I did:
1) Created an "addin" template with some procedures in it and saved it to a
non trusted location.
2) created a document template that has the Addins.add code in its AutoNew
procedure.
3) created a document based on that doc tmplt and it runs fine with no
security warnings (yaaay) and when I look in the VBE the "reference" is
there. (double Yaaay.)

HOWEVER -- If I try to run a macro that calls code from the addin it gives
me a compile error, and if I put an AutoOpen sub in the doc template that
calls code in the "addin" it still chokes all over it with a compile error,
variable not defined, can't load object. YET -- If I open the doc template
and set the reference to the addin the old way (tools, references) then the
AutoOpen and other macro works fine...

I don't know what I'm doing wrong.

This is the code in the doc template:

++++++++++++++++
Sub AutoNew()
Application.AddIns.Add FileName:="C:\Program Files\Microsoft
Office\OFFICE11\LauraStartup.dot", _
Install:=True
End Sub

Sub RunAMacro()
mymacros.listbookmarks
End Sub
++++++++++++++++

MyMacros is a module in the "global" template and "listbookmarks" is a
procedure in it. That is the line of code it chokes on.

BTW, Fumei--I loved your sample procedure/template names. May be the first
time I've smiled since this little nightmare began...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top