 |
|
|
|
 |
How to safely update a document's styles from its template without
using the Organizer (and how to make the Tools + Templates and Add-ins dialog
safe)
|
Article contributed by Dave Rado, Margaret
Aldis, Ian Sharpe and Beth Melton
Overview of updating styles and template strategy
If you want to update the style definitions of a document with the style definitions in its
attached template, you can manually select Tools + Templates and Add-ins,
check the box which says Automatically update document styles, click OK; and then, because
that setting is sticky (and most of the time, undesirable), immediately select Tools
+ Templates and Add-ins again, deselect the Automatically update document styles box, and click OK.
If the attached template is Normal.dot, this doesn't work in Word 97; but it
works for all other attached templates in Word 97; and it works for all templates,
including Normal.dot, in later versions of Word. (It can be made to work
in Word 97, even if the attached template is Normal.dot, with a little
programming this is covered below).
It is important to realise that the only styles that are updated when you
update a document's styles from its template are the ones listed in the template
itself under Styles in use (in the Style
dialog, where it says List). So if a user modifies the definition of
a built-in style in their document, but that style was not listed under Styles in use in the template, then updating their styles from the
template will have no affect on that particular style definition. Because of
this, if you are a template designer, you must ensure that any built-in styles
which you want control over are listed under Style in use.
The best way to add a built-in style to the In use list is to
insert it in the template (first redefining it if required). You could use a
dummy paragraph for the purpose, and delete it again once you have finished
applying your styles. The styles, having been applied once, will remain in the In use list for ever more.
When should styles be updated?
The Automatically update document styles setting is document-specific, and
if left switched on when a particular document is saved, will update that document's styles whenever it is
opened by anyone (until the document is saved again with the setting switched
off).
This is usually undesirable, because, whereas
one would want a document's styles to be updated whenever a style in its template is
redefined while a document is being revised, once the document is live, one would definitely not.
Also if emailing to an external reviewer who does not have access to the template, the setting should emphatically not be switched on.
So in a corporate context, it's best never to save a document with its Automatically update document styles setting switched on. Instead, assuming you have a version control strategy,
store the draft/live status of a document in a document variable (or document
property); and by using an AutoOpen macro to
read the variable or property, update the styles if it's in Draft mode, but
not if it's Live.
In addition, your users may want to update a document's styles using the dialog,
if their style definitions have been mangled. Updating a document's styles from
its template is a lot faster than using the Organizer (and subject to the
qualifications below, seems to be more reliable, as well).
Gotchas to be aware of, and their workarounds
As has already been mentioned, updating styles from the template doesn't work in Word 97 if the attached template is
Normal.dot.
More seriously, in all versions of Word, updating styles can sometimes mangle your
style definitions, especially in the case of numbering styles, where it can
sometimes destroy the link between the styles and their List
Templates.
But the good news
is that updating styles can be made reliable, as follows.
|
1.
|
For it to be reliable, your numbering styles must use named List
Templates. See the links at How to cure Word's List Numbering with a dose of VBA
for more details.
|
|
2.
|
All the styles in the Styles in Use list need to have been
physically applied to text in the template once (but they do not
need to have been applied in documents based on the template). What the
difference is, in terms of the flags stored inside a template file,
between a style that is listed in the In use list but has
never been applied to text, and one that has been applied, is a
mystery; but it seems there is a difference.
Unfortunately, it is all too easy to add a style to the Styles in
Use list without ever applying the style to any text. In the case of
built-in styles, you can do this manually by selecting Format + Style,
where it says List, select All styles, and click Modify
+ OK + Close. Or programmatically, you can add it to the In
use list by running code that defines the style.
In the case of custom styles, you can add them to the In
use list without applying them to text by selecting Format +
Style + New + OK + Close; or programmatically, by defining a new style
without applying it.
Styles (especially numbering styles) that are listed in the In
use list of a template, but have never
physically been applied
to text, will not be stable if you update your styles from the template.
So if in doubt, it is a good idea to insert a dummy paragraph in each of
your templates, cycle it through all the styles in the template's In
use list, delete the dummy paragraph, and save the template. And if
you subsequently need to redefine any of the styles in the template, it is
again a good idea to apply the redefined style to a dummy paragraph.
|
|
3.
|
Sometimes, you have to do the update twice or occasionally even three
times in order preserve your List Template names and their links to your
numbering styles:
Dim oLT As ListTemplate
ActiveDocument.UpdateStyles
ActiveDocument.UpdateStyles
On Error Resume Next
For Each oLT In ActiveDocument.AttachedTemplate.ListTemplates
If Not oLT.Name =
"" Then
If Not ActiveDocument.ListTemplates(oLT.Name).ListLevels(1)
_
.LinkedStyle = oLT.ListLevels(1).LinkedStyle Then
ActiveDocument.UpdateStyles
Exit
For
End If
End If
Next oLT
No theories as to why this might be; it's a bug; but at least there is
a workaround.
You can make the Tools + Templates and Add-ins dialog safe for users
to use by intercepting the Word
command as follows:
Sub FileTemplates()
With Dialogs(wdDialogToolsTemplates)
.Show
If .LinkStyles = 1 Then
ActiveDocument.UpdateStyles
Dim
oLT As
ListTemplate
On Error
Resume Next
For Each oLT In
ActiveDocument.AttachedTemplate.ListTemplates
If
Not oLT.Name = "" Then
If Not ActiveDocument.ListTemplates(oLT.Name).ListLevels(1)
_
.LinkedStyle = oLT.ListLevels(1).LinkedStyle Then
ActiveDocument.UpdateStyles
Exit For
End If
End If
Next oLT
ActiveDocument.UpdateStylesOnOpen
= False
End If
End With
End Sub
[The ActiveDocument.UpdateStylesOnOpen = False line in the above code
sample prevents the user from being able to save the document with the Automatically update document styles setting switched on; and means
they don't have to immediately go back to the dialog every time they
update their styles, simply in order to deselect that setting. If that's not
what you want, though, you can remove that line. But if you do
remove that line, then you will also need to have an AutoOpen
macro that checks whether the setting is switched on, and if it is, that
updates the styles again if need be; otherwise the numbering styles will
sometimes be broken when the document is reopened.]
But unfortunately, the Dialogs(wdDialogToolsTemplates) object is buggy the dialog it displays doesn't show the list of add-ins, and half the
buttons on it are greyed out. This is well worth emailing mswish@microsoft.com
about.
You can get round this as follows:
|
a)
|
Instead of intercepting the FileTemplates command, create the
following macro:
Sub ReplacementToolsTemplatesAndAddins()
'Execute the built-in button
CommandBars.FindControl(ID:=751).Execute
If
Dialogs(wdDialogToolsTemplates).LinkStyles = 1 Then
Dim oDoc
As Document, oLT As ListTemplate
Set oDoc =
ActiveDocument
oDoc.UpdateStyles
On Error Resume Next
For Each oLT In
oDoc.AttachedTemplate.ListTemplates
If
Not oLT.Name = "" Then
If
Not oDoc.ListTemplates(oLT.Name).ListLevels(1) _
.LinkedStyle = oLT.ListLevels(1).LinkedStyle Then
oDoc.UpdateStyles
Exit For
End If
End If
Next oLT
oDoc.UpdateStylesOnOpen = False
End If
End Sub
(Again, remove the ActiveDocument.UpdateStylesOnOpen = False line
if you don't want it.)
|
|
b)
|
Create a new toolbar, name it Hidden, and move the
built-in Templates and Add-ins button to the new
toolbar. This is in order that the above macro can execute the
built-in button (doing so avoids the bugs that you get if you use
Dialogs(wdDialogToolsTemplates)), without the built-in button being
visible to the user.
|
|
c)
|
Go to Tools + Customize, select the Commands
tab; in the left pane, select All macros, in the right
pane select the ReplacementToolsTemplatesAndAddins macro, and drag
it onto the Tools menu, to where the Templates and
Add-ins button used to be. Right-click the new button and
rename it:
Templates and Add-&Ins...
|
|
d)
|
Disable the new toolbar (which makes it invisible to the user), as
follows:
CommandBars("Hidden").Enabled = False
|
|
e)
|
If you've made the above customisations in an add-in, create an
AutoExec macro as follows:
Sub AutoExec()
CommandBars("Hidden").Enabled = False
End Sub
Or if you've customized a template rather than an add-in, create an AutoNew
and AutoOpen macro in the template, containing the same code.
If you have already disabled the Web toolbar, of course, one
could use that for this purpose, rather than creating a new Toolbar
called Hidden. See also: How to stop the web toolbar from jumping up at you whenever you click on a page number in the table of contents.
|
With one qualification, your users should now be able to update their styles from their
template(s) safely.
That one qualification is this: the above macro will safely update
styles if their definitions have been changed in the attached template, and will
safely revert them to the attached template's definitions if they have been
redefined in the document. It will also safely update styles that are
defined in the attached template but not in the document. But if there are
broken list numbering styles in the document, it will sometimes, but not
always, fix those. In other words, it is not a complete substitute
for a Fix numbering macro (although it should greatly
reduce the frequency with which you'll need to run the latter). For
details of the latter, see the links at How to cure Word's List Numbering with a dose of VBA.
|
If you want to be able to update the styles of Word 97 documents that are
attached to Normal.dot
If instead of using the UpdateStyles method, you use
CopyStylesFromTemplate, then you can update your document's styles even
in Word 97, when the attached template is Normal.dot. However, using
CopyStylesFromTemplate is significantly slower than using UpdateStyles; so the
following variation on the
above macro only uses the slower method when necessary, and uses UpdateStyles
when possible:
Sub
ReplacementToolsTemplatesAndAddins()
Dim Word97Normal As Boolean,
oDoc As Document, oLT As
ListTemplate
'Execute the built-in button
CommandBars.FindControl(ID:=751).Execute
If Dialogs(wdDialogToolsTemplates).LinkStyles = 1 Then
Set oDoc = ActiveDocument
If Left$(Application.Version, 1)
= "8" And _
oDoc.AttachedTemplate = NormalTemplate Then
Word97Normal = True
End If
If Word97Normal Then
oDoc.CopyStylesFromTemplate
NormalTemplate
oDoc.CopyStylesFromTemplate
NormalTemplate
Else
oDoc.UpdateStyles
End If
On Error Resume Next
For Each oLT In
oDoc.AttachedTemplate.ListTemplates
If Not oLT.Name
= "" Then
If
Not oDoc.ListTemplates(oLT.Name).ListLevels(1) _
.LinkedStyle = oLT.ListLevels(1).LinkedStyle Then
If Word97Normal Then
oDoc.CopyStylesFromTemplate NormalTemplate
Else
oDoc.UpdateStyles
End If
Exit For
End If
End If
Next oLT
oDoc.UpdateStylesOnOpen = False
End If
End Sub
|





|