ListTemplate objects and Heading1-9 styles

M

mansky99

Hi all,
I have some general questions about the differences between List Template
objects and the styles Heading1 thru Heading9 and TOC1 thru TOC9 that show up
as Paragraph styles in the Format/Styles dialog box. In Office X there seems
to be only 2 types of styles: character and paragraph, while in Office 2004
there seems to be I think 4 types of styles: character, paragraph, list and
table.

Is this difference correct?

Are ListTemplate objects used by Word in both Office X and Office 2004 to
handle any numbering scheme used in a document regardless of the style
chosen? Or, are ListTemplate objects only created when using built-in styles
in either Office X or Office 2004 ? Is built-in style taken to mean a style
that has NOT been customized by the User?

What I am getting at is trying to programmatically handle in VBA the
following:

A document created from a template that has Heading1, Heading2, ...
Heading9 styles all customized looks scheamtically as :

1.0 Section 1 title

text of paragrah in section 1 ....
1.1 Sub-section title

text of sub-section ....
1.2 Sub-section title

text of sub-section #2 ...

2.0 Section 2 title

...more paragrahs

3.0 Section 3 title

....

A given document can run to over 12 sections and a couple dozen
sub-sections, some nested 2-4 levels deep with multiple paragraphs of text
(in different fonts, pt sizes and colors in each. The entire document can be
50-200 pages long.

When this document is then cut and pasted from into another document that
is a new, blank document, sometimes Word crashes entirely.

If I understand Word correctly, 3 things are copied in the cut-and-paste
operation:

1) the text itself that's in the system clipboard. (Copied using
PasteSpecial)
2) a ListTemplate object (to define the numbering scheme in the original
document)
3) a pointer to that ListTemplate object.

Is this description of a cut-and-paste of a style-based numbered text
correct?

Could the mangling of the pointer to the ListTemplate object be the reason
Word crashes?

If so, can one trap the crash via an Error handling routine? That is, is
On Error triggered when Word itself crashes? Or, would automatically
re-starting the numbering in a document, via a VBA macro, be the recommended
way to avoid the mangled pointer?


Any ideas, or tips would be greatly appreciated!

Thanks for reading!

Ed
 
J

John McGhie

Gidday Ed:

Answers inline...

I have some general questions about the differences between List Template
objects and the styles Heading1 thru Heading9 and TOC1 thru TOC9 that show up
as Paragraph styles in the Format/Styles dialog box. In Office X there seems
to be only 2 types of styles: character and paragraph, while in Office 2004
there seems to be I think 4 types of styles: character, paragraph, list and
table.

Is this difference correct?

Yes, that's correct. In 2007/8 there's also a "Theme", which you can think
of as a 'Document' Style.
Are ListTemplate objects used by Word in both Office X and Office 2004 to
handle any numbering scheme used in a document regardless of the style
chosen?

ALL 'list' numbering creates or uses a List Template. Field-based numbering
does not.
Is built-in style taken to mean a style
that has NOT been customized by the User?

No. A built-in style is one that returns "true" to the BuiltIn property.

BuiltIn Property Example
This example checks all the styles in the active document. When it finds a
style that isn't built in, it displays the name of the style.
For Each sty in ActiveDocument.Styles
If sty.BuiltIn = False Then
Msgbox sty.NameLocal
End If
Next

Basically, these are the styles you will see if you create a new blank
Normal template, then view "All Styles" in the formatting palette.

A Built-In Style is one that is hard-coded into the Style Table of a
freshly-created document, if that document was created from a purely default
Normal template.

There is an "entry" in the style table for it. However, the style may not
actually have been instantiated yet. The place where this will most give
you the s**ts is in the List Number set.

List Number through List Number 9 are built-in styles. But in a blank
Normal template, only List Number through List Number 4 have been
instantiated. So if you attempt to do anything in VBA with List Number 5,
you will blow up, unless you first enumerate the Styles collection and
ensure that it has actually been instantiated.
When this document is then cut and pasted from into another document that
is a new, blank document, sometimes Word crashes entirely.

Which indicates that there are conflicting customisations (usually, circular
references...) caused by "Keep Track of Formatting". You have a mixture of
Paragraph and Character styles in the document. Some of the Paragraph
styles are based on Character styles which are in turn based on Paragraph
styles.

Since the Character style cannot contain a reference to the List Template,
you get a broken pointer and over she goes. That's only "one" way users can
break it :)
If I understand Word correctly, 3 things are copied in the cut-and-paste
operation:

1) the text itself that's in the system clipboard. (Copied using
PasteSpecial)
2) a ListTemplate object (to define the numbering scheme in the original
document)
3) a pointer to that ListTemplate object.

I do not believe that the ListTemplate "object" is copied, only the pointer
to it. I believe that the list template is re-constructed in the target
document, not copied in.
Could the mangling of the pointer to the ListTemplate object be the reason
Word crashes?

It seems to be the usual cause, yes. Not that the pointer gets mangled, so
much as its target disappears, leading to an unresolved pointer.
If so, can one trap the crash via an Error handling routine?

I have never found a way.
That is, is On Error triggered when Word itself crashes?

No. On Error is triggered by VBA, which is a separate thread to Word. If
Word has crashed, the VBA thread it spawned is cleaned up with the rest of
the debris.
Or, would automatically
re-starting the numbering in a document, via a VBA macro, be the recommended
way to avoid the mangled pointer?

The only sure way to stop these crashes is to tell the users not to mangle
their numbering. Which means the users need to understand the entire
concept of numbering, including "lists".

What they often do is apply more than one list template to a list.

Take headings 1 to 9. The user applies a numbering scheme to Heading 1 from
the Outline List Gallery.

Then they decide they want a bullet on Heading 3. The get in with
Format>Bullets and Numbering and apply a Bullet to a Heading 3 paragraph,
from the Bullets List Gallery.

Then they "Update style to match selection".

From then, the document's hosed. VBA/Word prevents you changing the "Type"
of a list template applied by the List Gallery. So now you have an Outline
List Template applied to headings 1, 2, 4-9. You have a Bulleted
(single-level) list template applied to Heading 3. And Word will not
permit either of those list templates to change type.

She's pooched :)

If you want to stop most of the crashes on paste, run the single-line
statement "application.activedocument.convertnumberstotext"

Sub ConvertNumbers()
' Converts all numbers to text
Dim doIt As Long
Dim aSel As Range
Dim alist As List
Dim aPara As Paragraph

Set aSel = Selection.Range
doIt = aSel.End - aSel.Start

If doIt > 1 Then
If aSel.ListParagraphs.Count > 0 Then
aSel.ListParagraphs(1).Range.ListFormat.List.ConvertNumbersToText
End If
Else
doIt = MsgBox("No selection. Do whole document?", vbExclamation +
vbOKCancel)
If doIt = 1 Then
ActiveDocument.ConvertNumbersToText
End If
End If
If doIt > 0 Then MsgBox "All numbering converted to typed text."

End Sub


Run away real fast if you're going to do that to a user's document, because
after that, all their numbering is typed text, and if they want to update
the numbering, they have to type it...

Hope this helps

--
Don't wait for your answer, click here: http://www.word.mvps.org/

Please reply in the group. Please do NOT email me unless I ask you to.

John McGhie, Consultant Technical Writer
+61 4 1209 1410, mailto:[email protected]
McGhie Information Engineering Pty Ltd
http://jgmcghie.fastmail.com.au/
Sydney, Australia. S33°53'34.20 E151°14'54.50
 
M

mansky99

Hi John,
Many thanks for your detailed response!! I think I am (slowly) getting my
arms around the ListTemplate object and how numbering in a document is done
in Word.

I have a few more questions to clarify a few ideas.

You mentioned:

Where is the checkbox "Keep Track of Formatting" located? I'm not
familiar with that option.

In regards to the pointer to the ListTemplate object, I'm trying to learn
what VBA and Word are doing when a User is applying numbering schemas to
their paragraphs. I'm a FORTRAN/C/Perl programmer mainly, so pointers are
very familiar to me. The pointers we're talking about here in regards to
ListTemplates in VBA seem entirely different to those I use in C for example.
I'd like to figure out what additional tests I could add to my PasteSpecial
macro to test ahead of the actual paste operation whether or not the pointer
to the ListTemplate is valid or not, or even if that's possible. Or, after
the paste is completed, to just automatically trash and rebuild the pointer
-if that's possible.

So, the question is where is this pointer stored in the target document
after the paste? Is it in the Last Paragraph mark of the target document?
Does re-start numbering of the target document, as discussed in the Word MVP
website, re-buld this pointer?

Also, given the issues you mentioned with the ListGallery, would it be
better, in the sense of more stable, for me to place all the styles we use
for paragraph numbering (ie. Heading1-Heading9) in a global template and then
use the LinkToListTemplate mathod for these styles so that they can be used
in list numbering?

Finally, where is the option "Update styles to match selection" located?
I'm not familiar with that option either.

Again, many thanks for the detailed answers. The books and websites (Word
MVP especially) I've found are helpful, but necessarily leave out many
details of the full extent of the Object Model behind Word. Having worked on
large-scale software projects myself, I can appreciate the many hacks,
workarounds and plain spaghetti code that Word is probably constructed from.

Ed
 
J

John McGhie

Hi Ed:

Where is the checkbox "Keep Track of Formatting" located? I'm not
familiar with that option.

It was only available in PC Word. It's a mis-feature ("BUG!!") that
instantly began destroying documents in Office 2002. Fortunately, Mac BU
saw it coming, and someone 'forgot' to include it in Office X. The PC guys
tried to fix it in Word 2003. Again, in Mac BU inclusion of this new and
important feature apparently slipped their minds.

Finally someone in PC Office managed to take it out the back and perform a
Percussive Attitude Recalibration on it while the boss was not looking. So
then Mac BU was able to breath a huge sigh of relief and implement the fixed
version in Office 2008. It's on the Edit preferences.
In regards to the pointer to the ListTemplate object, I'm trying to learn
what VBA and Word are doing when a User is applying numbering schemas to
their paragraphs.

If you ever figure it out, maybe you would like to publish two-volume
encyclopaedia for us? If you can find Stuart Stuple's blog on the Microsoft
site, ask him ‹ he designed/wrote most of it...
I'm a FORTRAN/C/Perl programmer mainly, so pointers are
very familiar to me. The pointers we're talking about here in regards to
ListTemplates in VBA seem entirely different to those I use in C for example.

Not really. In .doc format, and in memory, they are integer byte-offsets
from the front of the file to the numbering information or style
information. In the case of list templates, these are structured data
objects (think: COBOL repeating data items...) so I believe you get an
offset to the List Template Table Structure and a row number within the
structure.
I'd like to figure out what additional tests I could add to my PasteSpecial
macro to test ahead of the actual paste operation whether or not the pointer
to the ListTemplate is valid or not, or even if that's possible. Or, after
the paste is completed, to just automatically trash and rebuild the pointer
-if that's possible.

This is an idle daydream I have had for a few decades now. Presumably you
are a more capable coder than I, so you may have more success :)

You can't address the pointer directly. However, you could:

1) Intercept the Copy event

2) Return the paragraphs in the selection

3) Bookmark the whole selection

4) Test each paragraph in the selection for a list format

5) If you find one, For each list format you find:
‹ store the list template by value in an array
‹ encase each of its list paragraphs in a bookmark
‹ Store the names of the paragraph bookmarks and their applicable list
templates in array

6) Then do your copy/paste.

7) Return the outer bookmark as a range,

8) Enumerate the bookmarks within the outer bookmark range

9) re-apply the correct stored list template to each.

At that stage, Word will create a new entry into the List Template table for
your list template from the other document, rather than reset the pointer
from the list paragraphs to one of the target document's list templates and
pooch everything.

Before you go the bookmarks routine, check to see if you can perform a copy
and hold a Range intact. If you can, you will save yourself a whole lot of
work, because you can have multiple ranges in a document and they can be
non-contiguous, whereas bookmarks must be unique and contiguous.

Be certain that your design allows for multiple list templates within the
selection, which may be single- or multi-level, and which may or may not be
non-contiguous ranges of paragraphs. Otherwise you will achieve Very High
Entertainment Value.

There: You should be able to run that up in a little less than a month, and
you'll have it debugged by next year :)

Just in time to convert it to AppleScript for Word 2008. Oh: Word
AppleScript has no events, so try not to use any ... :)
So, the question is where is this pointer stored in the target document
after the paste? Is it in the Last Paragraph mark of the target document?

A binary format Word document is something like a linked list. The
"pointers" are in each paragraph. The target is a data structure within the
OLE store, which is not "in" the last paragraph, it is hidden "below" the
last paragraph mark.

The OLE object store is a complex nested structure that contains anything in
the document or applicable to the document that is not "string text". It's
a real supermarket, and the shelves are not "that" tidy...

In VBA, Equate a Variant with a document, then stop the macro and open the
Locals Window. You can then examine the entire object model of the current
document and see how it all logically fits together. The Locals window is
not implemented in the Mac VBA Editor, you will need to use a PC.

In the XML format, the tags in the text resolve to these pointers when Word
lays the thing out in RAM.
Does re-start numbering of the target document, as discussed in the Word MVP
website, re-buld this pointer?

Which method? There are five. I don't know, but I think the "Restart"
property is a Boolean that simply indicates whether enumeration should
restart within the current list.
Also, given the issues you mentioned with the ListGallery, would it be
better, in the sense of more stable, for me to place all the styles we use
for paragraph numbering (ie. Heading1-Heading9) in a global template and then
use the LinkToListTemplate mathod for these styles so that they can be used
in list numbering?

Yes. Very much so. If you can persuade your users to keep their sticky
paws off the Format>Bullets and Numbering button. But you can't....

You're opening a whole new can of worms. You know that, do you? :)

1) A document makes no further reference to its template after the point of
creation. Unless you force it to.

2) You can force it by setting "Update styles on open" to be True when you
attach the template at document creation.

3) But if you do, you will blow away all your list numbering each time the
user opens the document. The "styles" will be replaced within the document,
which means that the List Numbering "Restarts" will all be set to false. I
think that's a bug, but it's a very destructive one.

If both source and target document were created from the same template, and
the users can be persuaded to apply their numbering using styles ONLY, and
to not fiddle with the numbering using Format>Bullets and Numbering, then
lists will copy and paste between the two documents without damage.

However, the list template is similar to a style, but it is not a style, and
it is not "part" of a style (and a style is not "part" of it. They are
separate objects. The association between them seems to exist only within
the current document. If you copy text, the styles will copy, but not the
list templates. If you update the styles, the styles will update, but their
association to their list templates get broken.
Finally, where is the option "Update styles to match selection" located?
I'm not familiar with that option either.

It's in the bottom half of the Styles section of the Formatting Palette, if
you drop down the disclosure triangle to the right of the style name. They
were thinking of putting a cover over it for 2008, but they decided it was
well-enough hidden to prevent its use as it is.
Again, many thanks for the detailed answers. The books and websites (Word
MVP especially) I've found are helpful, but necessarily leave out many
details of the full extent of the Object Model behind Word.

Get hold of a PC version of Word 2003 and rat around in the Help. The whole
object model is in there as a clickable map. They pooched that too in 2007.

Many of those details are missing because WE don't know them, and Microsoft
has forgotten them. Anything by Bill Coan or Stephanie Krieger is pretty
reliable.
Having worked on
large-scale software projects myself, I can appreciate the many hacks,
workarounds and plain spaghetti code that Word is probably constructed from.

Word's code base is older than many of the developers working on it these
days :)

Hope this has confused you totally...

--
Don't wait for your answer, click here: http://www.word.mvps.org/

Please reply in the group. Please do NOT email me unless I ask you to.

John McGhie, Consultant Technical Writer
+61 4 1209 1410, mailto:[email protected]
McGhie Information Engineering Pty Ltd
http://jgmcghie.fastmail.com.au/
Sydney, Australia. S33°53'34.20 E151°14'54.50
 
M

mansky99

Hi John,
Many thanks again for the detailed answers. I have read this weekend your
"Word's Numbering Explained" article on the Word MVP website from 2000.
Between your answers here and the article on the Word MVP website, together
with the "Restarting list numbering using VBA" page and the macros therein I
think I'm getting some sense of what's going on when paragraphs are
copy-and-pasted from one numbered heading document to another.

Before I tackle the 9-step macro you outlined earlier :) I think I want
to get my Users to a relatively stable place using the PasteSpecial macro I
already have. I suspect I can modify it to perform one, or more, tests to see
if the ListTemplate(s) copied from a source document to the target document,
contain circular references. And to then take corrective action as necessary
in order to prevent Word from throwing an exception at the moment of Pasting,
or Saving As.

To that end, I have one more question for now.

In the Word MVP webpages on Numbering in Word, a MS Knowledge Base article
on 200+ ListTemplates in a document is mentioned, but no specific link, or KB
article no. is given. Do You know the KB article no. of this article? I tried
searching for it at the MS KB site, but was unsuccessful. I was curious about
what's in that KB article.

Many thanks again!


Ed
 
J

John McGhie

Hi Ed:

From memory, that article effectively says "We have discovered a few things
we forgot, like the .doc format blows up if the List Templates object gets
too big. So we tweaked Word to reduce the size of the List Template Object
during the next Save when the object exceeds 200 entries."

That fix has been carried through to all versions of Word. It deletes
unused List Templates and compacts the table.

If you want to start testing before Paste, you have a real problem.

Far better to teach the users to use the correct styles to apply their
numbering and leave the bloody things alone! Otherwise you will write
hundreds of lines of code and still get high entertainment value...

Cheers


Hi John,
Many thanks again for the detailed answers. I have read this weekend your
"Word's Numbering Explained" article on the Word MVP website from 2000.
Between your answers here and the article on the Word MVP website, together
with the "Restarting list numbering using VBA" page and the macros therein I
think I'm getting some sense of what's going on when paragraphs are
copy-and-pasted from one numbered heading document to another.

Before I tackle the 9-step macro you outlined earlier :) I think I want
to get my Users to a relatively stable place using the PasteSpecial macro I
already have. I suspect I can modify it to perform one, or more, tests to see
if the ListTemplate(s) copied from a source document to the target document,
contain circular references. And to then take corrective action as necessary
in order to prevent Word from throwing an exception at the moment of Pasting,
or Saving As.

To that end, I have one more question for now.

In the Word MVP webpages on Numbering in Word, a MS Knowledge Base article
on 200+ ListTemplates in a document is mentioned, but no specific link, or KB
article no. is given. Do You know the KB article no. of this article? I tried
searching for it at the MS KB site, but was unsuccessful. I was curious about
what's in that KB article.

Many thanks again!


Ed

--
Don't wait for your answer, click here: http://www.word.mvps.org/

Please reply in the group. Please do NOT email me unless I ask you to.

John McGhie, Consultant Technical Writer
+61 4 1209 1410, mailto:[email protected]
McGhie Information Engineering Pty Ltd
http://jgmcghie.fastmail.com.au/
Nhulunbuy, Northern Territory, Australia
 

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