PDA

View Full Version : Solved: outline numbering version issue



qr_doc_con
06-06-2011, 04:25 AM
I've setup a module to update the outline number list headings styles in word.

I need to have it working in both word 2003 and 2010 as I have mixture of both versions in the organisation and only want 1 lot of code.

I can set it up so that the code will works for each version seperatly but the final outcome I would like to have is one common source file.

Is there a way to have it so that this will work in both versions from the one module.

here is the code that i'm using


Public Sub outline_headings()
Dim fontRGB As Long
fontRGB = RGB(80, 80, 80) 'set border colour variable based on Red/Green/Blue colour code
On Error Resume Next
Call Heading_Style
ActiveDocument.Styles.Add ("Heading 1")
With ActiveDocument.Styles("Heading 1").Font
.Bold = True ' turns on Bold Text
.Color = fontRGB 'Change font to Grey
.AllCaps = False 'Remove all caps
.Size = 18 ' sets font size
.Name = "arial" 'sets type of font
End With

With ActiveDocument.Styles("Heading 1").ParagraphFormat
.Alignment = wdAlignParagraphLeft 'Align to left
.SpaceBefore = 12 ' sets the paragraph spacing above the text
.SpaceAfter = 6 ' sets the paragraph spacing below the text
.LineSpacing = 12 ' sets line spacing to single
With .Borders(wdBorderBottom) 'selects bottom border
.LineStyle = wdLineStyleSingle 'sets bottom border to single line
.LineWidth = wdLineWidth100pt ' sets line with to 1 point
.Color = fontRGB ' sets colour of line from font varible
End With
End With
ActiveDocument.Styles.Add ("Heading 2")
With ActiveDocument.Styles("Heading 2").Font
.Color = fontRGB 'Change font to Grey
.AllCaps = False 'Remove all caps
.Size = 16 ' sets font size
.Name = "arial" 'sets type of font
End With
With ActiveDocument.Styles("Heading 2").ParagraphFormat
.Alignment = wdAlignParagraphLeft 'Align to left
.SpaceBefore = 12 ' sets the paragraph spacing above the text
.SpaceAfter = 6 ' sets the paragraph spacing below the text
.LineSpacing = 12 ' sets line spacing to single
End With
ActiveDocument.Styles.Add ("Heading 3")
With ActiveDocument.Styles("Heading 3").Font
.Color = fontRGB 'Change font to Grey
.AllCaps = False 'Remove all caps
.Size = 14 ' sets font size
.Name = "arial" 'sets type of font
End With
With ActiveDocument.Styles("Heading 3").ParagraphFormat
.Alignment = wdAlignParagraphLeft 'Align to left
.SpaceBefore = 12 ' sets the paragraph spacing above the text
.SpaceAfter = 6 ' sets the paragraph spacing below the text
.LineSpacing = 12 ' sets line spacing to single
End With
ActiveDocument.Styles.Add ("Heading 4")
With ActiveDocument.Styles("Heading 4").Font
.Color = fontRGB 'Change font to Grey
.AllCaps = False 'Remove all caps
.Size = 12 ' sets font size
.Name = "arial" 'sets type of font
End With
With ActiveDocument.Styles("Heading 4").ParagraphFormat
.Alignment = wdAlignParagraphLeft 'Align to left
.SpaceBefore = 12 ' sets the paragraph spacing above the text
.SpaceAfter = 6 ' sets the paragraph spacing below the text
.LineSpacing = 12 ' sets line spacing to single
End With

' 2010 code to have this working
ListGalleries(wdOutlineNumberGallery).ListTemplates(1).Name = ""
Selection.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
ListGalleries(wdOutlineNumberGallery).ListTemplates(1), _
ContinuePreviousList:=False, ApplyTo:=wdListApplyToWholeList, _
DefaultListBehavior:=wdWord10ListBehavior

' 2003 code to have this working
ListGalleries(wdOutlineNumberGallery).ListTemplates(1).Name = ""
Selection.Range.ListFormat.ApplyListTemplate ListTemplate:=ListGalleries( _
wdOutlineNumberGallery).ListTemplates(5), ContinuePreviousList:=False, _
ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _
wdWord10ListBehavior

End Sub
Sub Heading_Style()
With ListGalleries(wdOutlineNumberGallery).ListTemplates(1).ListLevels(1)
.NumberFormat = "%1.0"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(0)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.25)
.ResetOnHigher = 0
.StartAt = 1
.LinkedStyle = "Heading 1"
End With

With ListGalleries(wdOutlineNumberGallery).ListTemplates(1).ListLevels(2)
.NumberFormat = "%1.%2"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(0.25)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.5)
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = "Heading 2"
End With

With ListGalleries(wdOutlineNumberGallery).ListTemplates(1).ListLevels(3)
.NumberFormat = "%1.%2.%3"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(0.5)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.75)
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = "Heading 3"
End With

With ListGalleries(wdOutlineNumberGallery).ListTemplates(1).ListLevels(4)
.NumberFormat = "%1.%2.%3.%4"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(0.75)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(1)
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = "Heading 4"
End With

End Sub

TrippyTom
06-06-2011, 06:06 AM
After a brief look through your code, it seems to me the only difference is how the version of Word applies listtemplates. In that case, couldn't you have an IF/THEN to check the version and have both sets of code in the appropriate spot?


if 2003 then
(put your 2003 code here)
else
(put your 2007/2010 code here)
end if


Here's a link on how to check version info: http://support.microsoft.com/kb/212719

Frosty
06-07-2011, 08:44 AM
Is this code currently in use? Because the use of ListGalleries in Word 2003 (at least, and probably Word 2010 as well, although I don't have direct experience with failures there yet) is a guaranteed path to numbering failure eventually, unless you are in a very very regulated environment (no outside documents ever, etc). Think of List Galleries as a "most recently used" numbering list which updates a lot more often than you would think.

To have code referencing specific gallery positions which change all the time is going to cause problems.

Other than that, I agree with the Trippy one.

qr_doc_con
06-07-2011, 12:56 PM
Is this code currently in use? Because the use of ListGalleries in Word 2003 (at least, and probably Word 2010 as well, although I don't have direct experience with failures there yet) is a guaranteed path to numbering failure eventually, unless you are in a very very regulated environment (no outside documents ever, etc). Think of List Galleries as a "most recently used" numbering list which updates a lot more often than you would think.

To have code referencing specific gallery positions which change all the time is going to cause problems.

Other than that, I agree with the Trippy one.

Hi frosty,

yes this is currently in use and there can be outside documents at times.

what would you recommend replacing this with as I will eventually have upto 15,000 documents to control that may require reformating at some stage which is why I'm tring to set up some code to help maintain these docments.

there will be a mixture of word 2003 and 2010 in use

Frosty
06-07-2011, 02:37 PM
Sorry, juggling a few things at the moment, so unable to give a complete answer. Couple of quick pointers--

1. Read up on list templates at mvps.org for background. It's long, but gives good details. If you're ultimately trying to develop a strategy to deal with a large amount of documents, you should probably understand numbering and styles to a degree that I suspect you don't at the moment.
http://word.mvps.org/FAQs/Numbering/WordsNumberingExplained.htm

2. Keep your documents in Word 2003 format until you're not in mixed mode anymore. The compatibility pack in 2003 which allows you to read 2010 documents is worse than having 2010 read 2003 documents (over-simplification, but close enough for now).

3. Name your list-templates so you can retrieve the right list-template later (Word will create new ones on the fly... it's always nice, with code, to be able to go back to your named listtemplate, and then reconnect it to your heading styles as a numbering "fix"). The upshot of a numbering fix code is that you will be able to utilize it to change your numbering styles as well.

4. Skip the listgallery entirely, and simply go straight to the listtemplate object itself. Something along the lines of:

Dim oMyListTemplate as ListTemplate

Set oMyListTemplate = ActiveDocument.ListTemplates("CompanyListTemplate1")

Once you've got a pointer to the list template, you can use most of your existing code modifying it and linking to the appropriate styles. The problem with the listgallery is that you have to identify by position (1, 5, etc), and that position will change willy-nilly.

However, you can only get to list-templates in a couple of ways: through the style, through the selection, through the gallery, or identified by name.

I have named my listtemplates for a long time, and although it's not perfect (Word numbering never is), it's always more reliable to identify by name than by any of the other ways.

EDIT: I'm fairly positive this methodology changes if you go exclusively to 2010, but I don't have as deep an understanding of 2010 as I do of 2003.

qr_doc_con
06-12-2011, 05:09 AM
Hi Frosty,

Thanks for the Info earlier.

After reading what you suggested and a bit more research I was able to put something together wich by chance words on both versions of word.

This is what i came up with.
Sub outline_headings()
Dim fontRGB As Long
Dim oLstTemplate As ListTemplate
fontRGB = RGB(80, 80, 80) 'set border colour variable based on Red/Green/Blue colour code
On Error Resume Next
' Sets properties of Heading 1
With ActiveDocument.Styles("Heading 1")
.AutomaticallyUpdate = False
.BaseStyle = "Normal"
.NextParagraphStyle = "Normal"
With .Font
.Bold = True ' turns on Bold Text
.Italic = False ' turns off Italic Text
.Color = fontRGB 'Change font to Grey via variable
.AllCaps = False 'Remove all caps
.Size = 18 ' sets font size
.Name = "arial" 'sets type of font
End With
With .ParagraphFormat
.Alignment = wdAlignParagraphLeft 'Align to left
.SpaceBefore = 12 ' sets the paragraph spacing above the text
.SpaceAfter = 6 ' sets the paragraph spacing below the text
.LineSpacing = 12 ' sets line spacing to single
With .Borders(wdBorderBottom) 'selects bottom border
.LineStyle = wdLineStyleSingle 'sets bottom border to single line
.LineWidth = wdLineWidth100pt ' sets line with to 1 point
.Color = fontRGB ' sets colour of line from font variable
End With
End With
End With
' Sets properties of Heading 2
With ActiveDocument.Styles("Heading 2")
.AutomaticallyUpdate = False
.BaseStyle = "Normal"
.NextParagraphStyle = "Normal"
With .Font
.Bold = True ' turns on Bold Text
.Italic = False ' turns off Italic Text
.Color = fontRGB 'Change font to Grey via variable
.AllCaps = False 'Remove all caps
.Size = 18 ' sets font size
.Name = "arial" 'sets type of font
End With
With .ParagraphFormat
.Alignment = wdAlignParagraphLeft 'Align to left
.SpaceBefore = 12 ' sets the paragraph spacing above the text
.SpaceAfter = 6 ' sets the paragraph spacing below the text
.LineSpacing = 12 ' sets line spacing to single
End With
End With
' Sets properties of Heading 3
With ActiveDocument.Styles("Heading 3")
.AutomaticallyUpdate = False
.BaseStyle = "Normal"
.NextParagraphStyle = "Normal"
With .Font
.Bold = True ' turns on Bold Text
.Italic = False ' turns off Italic Text
.Color = fontRGB 'Change font to Grey via variable
.AllCaps = False 'Remove all caps
.Size = 18 ' sets font size
.Name = "arial" 'sets type of font
End With
With .ParagraphFormat
.Alignment = wdAlignParagraphLeft 'Align to left
.SpaceBefore = 12 ' sets the paragraph spacing above the text
.SpaceAfter = 6 ' sets the paragraph spacing below the text
.LineSpacing = 12 ' sets line spacing to single
End With
End With
' Sets properties of Heading 4
With ActiveDocument.Styles("Heading 4")
.AutomaticallyUpdate = False
.BaseStyle = "Normal"
.NextParagraphStyle = "Normal"
With .Font
.Bold = True ' turns on Bold Text
.Italic = False ' turns off Italic Text
.Color = fontRGB 'Change font to Grey via variable
.AllCaps = False 'Remove all caps
.Size = 18 ' sets font size
.Name = "arial" 'sets type of font
End With
With .ParagraphFormat
.Alignment = wdAlignParagraphLeft 'Align to left
.SpaceBefore = 12 ' sets the paragraph spacing above the text
.SpaceAfter = 6 ' sets the paragraph spacing below the text
.LineSpacing = 12 ' sets line spacing to single
End With
End With
Set oLstTemplate = ActiveDocument.ListTemplates.Add(OutlineNumbered:=True)
oLstTemplate.Name = "ListNumberTemplate"
With oLstTemplate.ListLevels(1)
.NumberFormat = "%1.0"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(0)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.25)
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = "Heading 1"
End With
With oLstTemplate.ListLevels(2)
.NumberFormat = "%1.%2"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(25)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.5)
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = "Heading 2"
End With
With oLstTemplate.ListLevels(3)
.NumberFormat = "%1.%2.%3"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(50)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.75)
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = "Heading 3"
End With
With oLstTemplate.ListLevels(4)
.NumberFormat = "%1.%2.%3.%4"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(75)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.75)
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = "Heading 4"
End With
End Sub

once again thanks for you help

Frosty
06-12-2011, 09:53 AM
Looks good... a couple of quick comments.

1. Why do you have the On Error Resume Next? About the only thing that might error out on you is trying to name the list template if it already exists. In that case, you probably want to deal with the error, rather than ignore it (i.e., set oListTemplate = ActiveDocument.ListTemplates("ListNumberTemplate")) -- and if it doesn't exist, that's when you create/update. On Error Resume Next on a long routine like this is going to cause you a headache at some point, guaranteed. If you're going to use it, use it for a specific area and know why you're doing it.

2. Structure-wise, when you come back to this code, it's going to make it a lot simpler if you separate out all of the functionality you've got going on. How you structure is a bit individual, but if I were to structure this code I'd probably do something along the lines of
(pseudo code)

'the main routine
Public Sub DefineMyListNumberingAndStyle()
Dim oListTemplate As ListTemplate
Dim sListTemplateName As String
'put the name right at the top, in case you later
'decide to have more than 1-- easier to change the code
sListTemplateName = "ListNumberTemplate"

On Error Resume Next
Set oListTemplate = ActiveDocument.ListTemplates(sListTemplateName)
'there will be an error if it didn't exist
If Err.Number <> 0 Then
Set oListTemplate = ActiveDocument.ListTemplates.Add(OutlineNumbered:=True)
oListTemplate.Name = sListTemplateName
End If
'reset the error trapping
On Error GoTo 0

'either way, you now have your list template at this point
'so define the heading styles
DefineHeadingStyles

'and your list template
DefineListTemplate oListTemplate

'and combine them
CombineListTemplateWithHeadingStyles oListTemplate
End Sub
'do all of your heading style definition here, or just 4
Public Sub DefineHeadingStyles()
With ActiveDocument.Styles("Heading 1")
End With
With ActiveDocument.Styles("Heading 2")
End With
With ActiveDocument.Styles("Heading 3")
End With
With ActiveDocument.Styles("Heading 4")
End With
End Sub
'pass in the list template, muck with the definitions here
Public Sub DefineListTemplate(oListTemplate As ListTemplate)
With oListTemplate.ListLevels(1)
End With
With oListTemplate.ListLevels(2)
End With
With oListTemplate.ListLevels(3)
End With
With oListTemplate.ListLevels(4)
End With
End Sub
'can use this as a "fix" function too
Public Sub CombineListTemplateWithHeadingStyles(oListTemplate As ListTemplate)
Dim i As Integer

'connect all the levels
For i = 1 To 9
oListTemplate.ListLevels(i).LinkedStyle = "Heading " & CStr(i)
Next
End Sub

Of course, there are many many ways to structure code. But separating out your functionality will pay dividends when you come back to it 6 months later and don't remember what was supposed to do what.

EDIT: code typo