Sluggish code or expected behaviour?

J

Jean-Guy Marcil

Hi there,

I have a client who want a report his employees uses to have a facility
whereby they can switch to landscape or back to portrait at the click of a
button.

The difficulty is that there are 3 header/footer (the template is built with
three basic sections), but luckily, they are all of the primary type...
Otherwise, what a nightmare it would have been!

There is
a Title page section (No landscape there...)
a main section (Can be landscape)
an annex section (Can be landscape)

So I have the code to go to landscape covering most situations (Where is the
cursor located?, Is there a page/section break already? etc,) I just have to
add a little option to let users decides if they want to use the current
page or add a new page with a landscape orientation.

Then, all I will need to do is "reverse engineer" my own code to give users
the possibility of returning a section to a portrait orientation...

So here is the thing:

I have a template. I did not want to bloat it or mess it up, so I created a
document from the said template and experimented with my landscape code in
that document VBA project modules.
The code is included below....

At the end of the day I noticed that the code was running a bit slower... I
figured that I kept adding all kinds of checks all day, it was to be
expected. But when I hit over 20 seconds, and then nearly 60 seconds.... I
thought this was not normal.

It was sporadic though. Sometimes if I quit Word and started over it was OK,
other times I noticed that I could make things worse by undoing everything
after each run of the code, then it would be an exponential time increase...
Finally my document bloated from 900 Kb (Lots of logos and graphics) to 2.5
MB in one save...
That stank of corruption. So I created a new document, transferred the code
and everything was back to 2-3 seconds.

The question is:
Is there something in my code that is causing this, so that if users fool
around with lots of orientation changes my code will corrupt their document
or
Was it simply because I tried out all kinds of code with this document,
sometimes causing Word to crash. Did I create the corruption because of the
nature of the work I was doing (So my users will not have to worry about
that kind of corruption)

One time I noticed that the line

PageCount = ActiveDocument.Content _
.Information(wdNumberOfPagesInDocument)

took a really long time to process...

Again, is it because of that particular property being flaky, or was it due
to document corruption? Should I use

PageCount = Selection.Information(wdNumberOfPagesInDocument)

instead?

Thanks.

'_______________________________________
Sub FormatPaysage()

'To be added:
'Code to give users the option of either adding a landscape
'section after the current page or to turn the current page
'into a landscape orientation
'Now the code just adds a landscape section after the current page

Dim PageRange As Range

'To get page number where cursor is
Dim StartPage As Long
'To get section number following current section to be added
Dim CurSection As Long
'To get total number of page in document
Dim PageCount As Long
'To flag if current page is last in document
Dim IsLastPage As Boolean
'If user wants to add a page or not after the last one
Dim NotAddPage As Boolean
'This variable will control where and how the landscape section
'is added if user or environement dictates it
Dim AdjustSection As Long
'This is used to flag if current page already has a section
'break at the end
Dim AddSectionBreak
'This is used to flag if current page has a page break at the end
Dim RemovePageBreak As Boolean
'This is to indicate which Autotext to use in the header
Dim AutoTextHeader As String
'This is to flag whether we are dealing with the first
'section of the Annexe
Dim FirstAnnexe As Boolean
'To store the First annexe section numnber
Dim FirstAnnexeSectionNumber As Long

'Variables needed for the message box in case cursor
'is on last page
Dim LastPageOrNot As String
Dim Style As Variant
Dim Title As String
Dim Response As Variant

LastPageOrNot = "Voulez-vous ajouter une page en format paysage " _
& " à la toute fin du document?" & vbCrLf & _
"Si vous répondez ""Non"", il n'y aura pas de " _
& "page ""Portrait"" après celle-ci."
Style = vbYesNo + vbExclamation + vbDefaultButton1
Title = "Dernière page"

'initialize variables
AddSectionBreak = False
RemovePageBreak = False
NotAddPage = False
IsLastPage = False
FirstAnnexe = False
AdjustSection = 1
PageCount = ActiveDocument.Content _
.Information(wdNumberOfPagesInDocument)
StartPage = Selection _
.Information(wdActiveEndPageNumber)

'Evaluate if currently on last page
If StartPage = PageCount Then
IsLastPage = True
Response = MsgBox(LastPageOrNot, Style, Title)
If Response = vbNo Then
NotAddPage = True
'So that changes are not carried back one section
AdjustSection = 0
Else
AddSectionBreak = True
End If
End If

'Get starting range and move cursor if at very end of document
'otherwise next line generates an error
Selection.Collapse
If Selection.Start = ActiveDocument.Content.End - 1 Then
Selection.MoveLeft Unit:=wdCharacter, Count:=1
End If
Set PageRange = Selection.Bookmarks("\Page").Range

'Check if finishes with section break if not on last page
If Not IsLastPage Then
If Not HasBreak(PageRange.Duplicate, "^b") Then
AddSectionBreak = True
'Check if current page finishes with page break
'It is assumed that if the last two characters of the page range
'have a section break,
'then there is no page break, this is why this test is embedded here,
'(it will not be necessary if HasSectionBreak is true)
If HasBreak(PageRange.Duplicate, "^m") Then
RemovePageBreak = True
End If
End If
End If

'Add first section break
With PageRange
'Remove page break if present
If RemovePageBreak Then
With .Duplicate
.MoveEnd Unit:=wdCharacter, Count:=-1
.Collapse Direction:=wdCollapseEnd
.Expand Unit:=wdCharacter
.Delete
End With
End If
.Collapse Direction:=wdCollapseEnd
.InsertBreak Type:=wdSectionBreakNextPage
End With

'If user does not want to add an extra page at the end of the document,
'do not add a section break...
If Not NotAddPage Then
'If page already has a section break at the end, only add a ¶
With PageRange
If AddSectionBreak Then
.InsertParagraphAfter
.Paragraphs(1).Style = "corps 10/20"
.Collapse Direction:=wdCollapseEnd
.InsertBreak Type:=wdSectionBreakNextPage
Else
.MoveEnd Unit:=wdCharacter, Count:=-1
.InsertParagraphAfter
.Paragraphs(1).Style = "corps 10/20"
.MoveEnd Unit:=wdCharacter, Count:=2
.Collapse Direction:=wdCollapseEnd
End If
End With
End If

'Get section number after the one we just inserted
CurSection = PageRange.Sections.Item(1).Index

'Evaluate which Autotext to use for the Header
FirstAnnexeSectionNumber = FirstAnnexeHeader
If CurSection > FirstAnnexeSectionNumber Then
AutoTextHeader = "Paysage2"
'If we are changing the first section of the Annexe in landscape,
'we will loose the bookmark "PremierAnnexe",
'so it has to be replaced
ElseIf CurSection = FirstAnnexeSectionNumber Then
AutoTextHeader = "Paysage2"
'To replace the bookamrk
'Code to be produced
Else
AutoTextHeader = "Paysage1"
FirstAnnexe = True
End If


'Unlink following section so as to preserve its header/footer
With ActiveDocument.Sections(CurSection)
With .Headers(wdHeaderFooterPrimary)
.LinkToPrevious = False
End With
With .Footers(wdHeaderFooterPrimary)
.LinkToPrevious = False
End With
End With

'Make target section Landscape
With ActiveDocument.Sections(CurSection - AdjustSection).PageSetup
.Orientation = wdOrientLandscape
.TopMargin = InchesToPoints(1.18)
.BottomMargin = InchesToPoints(0.79)
.LeftMargin = InchesToPoints(1.28)
.RightMargin = InchesToPoints(2.26)
.Gutter = InchesToPoints(0)
.HeaderDistance = InchesToPoints(0.49)
.FooterDistance = InchesToPoints(0.64)
.PageWidth = InchesToPoints(11)
.PageHeight = InchesToPoints(8.5)
End With

'Unlink target section from previous one so as to preserve the
'previous section's header/footer (It may be redundant if the target
'section is the last one of the document... but it does not matter,
'we can unlink again...)
'Also, add new Header/footer
With ActiveDocument.Sections(CurSection - AdjustSection)
With .Headers(wdHeaderFooterPrimary)
.LinkToPrevious = False
.Range.Delete
Set PageRange = .Range
ActiveDocument.AttachedTemplate. _
AutoTextEntries(AutoTextHeader).Insert _
Where:=PageRange, RichText:=True
PageRange.InsertParagraphAfter
PageRange.Collapse wdCollapseEnd
ActiveDocument.AttachedTemplate. _
AutoTextEntries("Paysage-Pied").Insert _
Where:=PageRange, RichText:=True
End With
With .Footers(wdHeaderFooterPrimary)
.LinkToPrevious = False
.Range.Delete
End With
End With

'Go to new landscape section
'To be skipped if users wants to change current section to landscape
Application.Browser.Next

Set PageRange = Nothing

End Sub
'_______________________________________

'_______________________________________
Function HasBreak(RangeToCheck As Range, SearchStr As String) As Boolean

'Check if last character in range is a section/page break

Selection.Find.ClearFormatting

With RangeToCheck
.MoveStart Unit:=wdCharacter, Count:=.Characters.Count - 2

With .Find
.Text = SearchStr
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.Execute
If .Found Then
HasBreak = True
Else
HasBreak = False
End If
End With

End With

Selection.Find.ClearFormatting
Selection.Find.Text = ""

Application.Browser.Target = wdBrowsePage

Set RangeToCheck = Nothing

End Function
'_______________________________________

'_______________________________________
Function FirstAnnexeHeader() As Long
'To find the section number containing the Bookmark "PremierAnnexe"
'so as to know which Autotext to use

Dim StRange As Range
Dim MyBkm As Bookmark

FirstAnnexeHeader = 0

For Each StRange In ActiveDocument.StoryRanges
If StRange.StoryType = wdPrimaryHeaderStory Then
While Not (StRange.NextStoryRange Is Nothing)
Set StRange = StRange.NextStoryRange
For Each MyBkm In StRange.Bookmarks
If MyBkm.Name = "PremierAnnexe" Then
FirstAnnexeHeader = StRange.Sections _
.Item(1).Index
Exit For
End If
Next MyBkm
If FirstAnnexeHeader <> 0 Then Exit For
Wend
End If
Next StRange

Set StRange = Nothing

End Function
'_______________________________________

TIA

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
P

Peter Hewett

Hi Jean-Guy Marcil

Can't see anything obviously wrong - but since it don't work all that means is that I'm
blind!

Are there large logos in the header/footers? Inserted multiple times and unlinked that
could cause bloat. Also are the correct sections getting unlinked? You're not unlinking
additional sections that should be linked, causing bloat?

And of course when you do it manually on a reasonable size document and use your code on
the same reasonable size document do you end up with exactly the same document/file size?

I'd do simple tests to create the following documents both programmatically and manually
and compare the results:

1. Title page, Portrait main section, Landscape main section, Portrait main section
2. Title page, Portrait annex section, Landscape annex section, Portrait annex section
3. Title page, Portrait main section, Landscape main section, Portrait main section,
Portrait annex section, Landscape annex section, Portrait annex section

Oh, boy-oh-boy what fun's in store.

Cheers - Peter


Hi there,

I have a client who want a report his employees uses to have a facility
whereby they can switch to landscape or back to portrait at the click of a
button.

The difficulty is that there are 3 header/footer (the template is built with
three basic sections), but luckily, they are all of the primary type...
Otherwise, what a nightmare it would have been!

There is
a Title page section (No landscape there...)
a main section (Can be landscape)
an annex section (Can be landscape)

So I have the code to go to landscape covering most situations (Where is the
cursor located?, Is there a page/section break already? etc,) I just have to
add a little option to let users decides if they want to use the current
page or add a new page with a landscape orientation.

Then, all I will need to do is "reverse engineer" my own code to give users
the possibility of returning a section to a portrait orientation...

So here is the thing:

I have a template. I did not want to bloat it or mess it up, so I created a
document from the said template and experimented with my landscape code in
that document VBA project modules.
The code is included below....

At the end of the day I noticed that the code was running a bit slower... I
figured that I kept adding all kinds of checks all day, it was to be
expected. But when I hit over 20 seconds, and then nearly 60 seconds.... I
thought this was not normal.

It was sporadic though. Sometimes if I quit Word and started over it was OK,
other times I noticed that I could make things worse by undoing everything
after each run of the code, then it would be an exponential time increase...
Finally my document bloated from 900 Kb (Lots of logos and graphics) to 2.5
MB in one save...
That stank of corruption. So I created a new document, transferred the code
and everything was back to 2-3 seconds.

The question is:
Is there something in my code that is causing this, so that if users fool
around with lots of orientation changes my code will corrupt their document
or
Was it simply because I tried out all kinds of code with this document,
sometimes causing Word to crash. Did I create the corruption because of the
nature of the work I was doing (So my users will not have to worry about
that kind of corruption)

One time I noticed that the line

PageCount = ActiveDocument.Content _
.Information(wdNumberOfPagesInDocument)

took a really long time to process...

Again, is it because of that particular property being flaky, or was it due
to document corruption? Should I use

PageCount = Selection.Information(wdNumberOfPagesInDocument)

instead?

Thanks.

'_______________________________________
Sub FormatPaysage()

'To be added:
'Code to give users the option of either adding a landscape
'section after the current page or to turn the current page
'into a landscape orientation
'Now the code just adds a landscape section after the current page

Dim PageRange As Range

'To get page number where cursor is
Dim StartPage As Long
'To get section number following current section to be added
Dim CurSection As Long
'To get total number of page in document
Dim PageCount As Long
'To flag if current page is last in document
Dim IsLastPage As Boolean
'If user wants to add a page or not after the last one
Dim NotAddPage As Boolean
'This variable will control where and how the landscape section
'is added if user or environement dictates it
Dim AdjustSection As Long
'This is used to flag if current page already has a section
'break at the end
Dim AddSectionBreak
'This is used to flag if current page has a page break at the end
Dim RemovePageBreak As Boolean
'This is to indicate which Autotext to use in the header
Dim AutoTextHeader As String
'This is to flag whether we are dealing with the first
'section of the Annexe
Dim FirstAnnexe As Boolean
'To store the First annexe section numnber
Dim FirstAnnexeSectionNumber As Long

'Variables needed for the message box in case cursor
'is on last page
Dim LastPageOrNot As String
Dim Style As Variant
Dim Title As String
Dim Response As Variant

LastPageOrNot = "Voulez-vous ajouter une page en format paysage " _
& " à la toute fin du document?" & vbCrLf & _
"Si vous répondez ""Non"", il n'y aura pas de " _
& "page ""Portrait"" après celle-ci."
Style = vbYesNo + vbExclamation + vbDefaultButton1
Title = "Dernière page"

'initialize variables
AddSectionBreak = False
RemovePageBreak = False
NotAddPage = False
IsLastPage = False
FirstAnnexe = False
AdjustSection = 1
PageCount = ActiveDocument.Content _
.Information(wdNumberOfPagesInDocument)
StartPage = Selection _
.Information(wdActiveEndPageNumber)

'Evaluate if currently on last page
If StartPage = PageCount Then
IsLastPage = True
Response = MsgBox(LastPageOrNot, Style, Title)
If Response = vbNo Then
NotAddPage = True
'So that changes are not carried back one section
AdjustSection = 0
Else
AddSectionBreak = True
End If
End If

'Get starting range and move cursor if at very end of document
'otherwise next line generates an error
Selection.Collapse
If Selection.Start = ActiveDocument.Content.End - 1 Then
Selection.MoveLeft Unit:=wdCharacter, Count:=1
End If
Set PageRange = Selection.Bookmarks("\Page").Range

'Check if finishes with section break if not on last page
If Not IsLastPage Then
If Not HasBreak(PageRange.Duplicate, "^b") Then
AddSectionBreak = True
'Check if current page finishes with page break
'It is assumed that if the last two characters of the page range
'have a section break,
'then there is no page break, this is why this test is embedded here,
'(it will not be necessary if HasSectionBreak is true)
If HasBreak(PageRange.Duplicate, "^m") Then
RemovePageBreak = True
End If
End If
End If

'Add first section break
With PageRange
'Remove page break if present
If RemovePageBreak Then
With .Duplicate
.MoveEnd Unit:=wdCharacter, Count:=-1
.Collapse Direction:=wdCollapseEnd
.Expand Unit:=wdCharacter
.Delete
End With
End If
.Collapse Direction:=wdCollapseEnd
.InsertBreak Type:=wdSectionBreakNextPage
End With

'If user does not want to add an extra page at the end of the document,
'do not add a section break...
If Not NotAddPage Then
'If page already has a section break at the end, only add a ¶
With PageRange
If AddSectionBreak Then
.InsertParagraphAfter
.Paragraphs(1).Style = "corps 10/20"
.Collapse Direction:=wdCollapseEnd
.InsertBreak Type:=wdSectionBreakNextPage
Else
.MoveEnd Unit:=wdCharacter, Count:=-1
.InsertParagraphAfter
.Paragraphs(1).Style = "corps 10/20"
.MoveEnd Unit:=wdCharacter, Count:=2
.Collapse Direction:=wdCollapseEnd
End If
End With
End If

'Get section number after the one we just inserted
CurSection = PageRange.Sections.Item(1).Index

'Evaluate which Autotext to use for the Header
FirstAnnexeSectionNumber = FirstAnnexeHeader
If CurSection > FirstAnnexeSectionNumber Then
AutoTextHeader = "Paysage2"
'If we are changing the first section of the Annexe in landscape,
'we will loose the bookmark "PremierAnnexe",
'so it has to be replaced
ElseIf CurSection = FirstAnnexeSectionNumber Then
AutoTextHeader = "Paysage2"
'To replace the bookamrk
'Code to be produced
Else
AutoTextHeader = "Paysage1"
FirstAnnexe = True
End If


'Unlink following section so as to preserve its header/footer
With ActiveDocument.Sections(CurSection)
With .Headers(wdHeaderFooterPrimary)
.LinkToPrevious = False
End With
With .Footers(wdHeaderFooterPrimary)
.LinkToPrevious = False
End With
End With

'Make target section Landscape
With ActiveDocument.Sections(CurSection - AdjustSection).PageSetup
.Orientation = wdOrientLandscape
.TopMargin = InchesToPoints(1.18)
.BottomMargin = InchesToPoints(0.79)
.LeftMargin = InchesToPoints(1.28)
.RightMargin = InchesToPoints(2.26)
.Gutter = InchesToPoints(0)
.HeaderDistance = InchesToPoints(0.49)
.FooterDistance = InchesToPoints(0.64)
.PageWidth = InchesToPoints(11)
.PageHeight = InchesToPoints(8.5)
End With

'Unlink target section from previous one so as to preserve the
'previous section's header/footer (It may be redundant if the target
'section is the last one of the document... but it does not matter,
'we can unlink again...)
'Also, add new Header/footer
With ActiveDocument.Sections(CurSection - AdjustSection)
With .Headers(wdHeaderFooterPrimary)
.LinkToPrevious = False
.Range.Delete
Set PageRange = .Range
ActiveDocument.AttachedTemplate. _
AutoTextEntries(AutoTextHeader).Insert _
Where:=PageRange, RichText:=True
PageRange.InsertParagraphAfter
PageRange.Collapse wdCollapseEnd
ActiveDocument.AttachedTemplate. _
AutoTextEntries("Paysage-Pied").Insert _
Where:=PageRange, RichText:=True
End With
With .Footers(wdHeaderFooterPrimary)
.LinkToPrevious = False
.Range.Delete
End With
End With

'Go to new landscape section
'To be skipped if users wants to change current section to landscape
Application.Browser.Next

Set PageRange = Nothing

End Sub
'_______________________________________

'_______________________________________
Function HasBreak(RangeToCheck As Range, SearchStr As String) As Boolean

'Check if last character in range is a section/page break

Selection.Find.ClearFormatting

With RangeToCheck
.MoveStart Unit:=wdCharacter, Count:=.Characters.Count - 2

With .Find
.Text = SearchStr
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.Execute
If .Found Then
HasBreak = True
Else
HasBreak = False
End If
End With

End With

Selection.Find.ClearFormatting
Selection.Find.Text = ""

Application.Browser.Target = wdBrowsePage

Set RangeToCheck = Nothing

End Function
'_______________________________________

'_______________________________________
Function FirstAnnexeHeader() As Long
'To find the section number containing the Bookmark "PremierAnnexe"
'so as to know which Autotext to use

Dim StRange As Range
Dim MyBkm As Bookmark

FirstAnnexeHeader = 0

For Each StRange In ActiveDocument.StoryRanges
If StRange.StoryType = wdPrimaryHeaderStory Then
While Not (StRange.NextStoryRange Is Nothing)
Set StRange = StRange.NextStoryRange
For Each MyBkm In StRange.Bookmarks
If MyBkm.Name = "PremierAnnexe" Then
FirstAnnexeHeader = StRange.Sections _
.Item(1).Index
Exit For
End If
Next MyBkm
If FirstAnnexeHeader <> 0 Then Exit For
Wend
End If
Next StRange

Set StRange = Nothing

End Function
'_______________________________________

TIA

HTH + Cheers - Peter
 
C

Cindy M -WordMVP-

Hi Jean-Guy,

Like Peter, I don't see anything "at a glance" that would be causing this. As
you're working a lot with sections, however, that's where I'd watch out. With
fields and tables (the other things that get corrupted quite easily), with VBA
and ranges you can actually stick things into "section breaks" - something the
user can't do. So you really have to watch out with MoveLeft, MoveRight and
those kinds of things, because the actual RANGE may not be equal to what you'd
think when you look at the screen display...
It was sporadic though. Sometimes if I quit Word and started over it was OK,
other times I noticed that I could make things worse by undoing everything
after each run of the code, then it would be an exponential time increase...
Finally my document bloated from 900 Kb (Lots of logos and graphics) to 2.5
MB in one save...
That stank of corruption. So I created a new document, transferred the code
and everything was back to 2-3 seconds.

The question is:
Is there something in my code that is causing this, so that if users fool
around with lots of orientation changes my code will corrupt their document
or
Was it simply because I tried out all kinds of code with this document,
sometimes causing Word to crash. Did I create the corruption because of the
nature of the work I was doing (So my users will not have to worry about
that kind of corruption)

Cindy Meister
INTER-Solutions, Switzerland
http://homepage.swissonline.ch/cindymeister (last update Sep 30 2003)
http://www.word.mvps.org

This reply is posted in the Newsgroup; please post any follow question or
reply in the newsgroup and not by e-mail :)
 
J

Jean-Guy Marcil

Bonjour,

Dans son message, < Peter Hewett > écrivait :
In this message, < Peter Hewett > wrote:

|| Hi Jean-Guy Marcil
||
|| Can't see anything obviously wrong - but since it don't work all that
means is that I'm
|| blind!
||
|| Are there large logos in the header/footers? Inserted multiple times and
unlinked that
|| could cause bloat. Also are the correct sections getting unlinked?
You're not unlinking
|| additional sections that should be linked, causing bloat?
||
|| And of course when you do it manually on a reasonable size document and
use your code on
|| the same reasonable size document do you end up with exactly the same
document/file size?
||
|| I'd do simple tests to create the following documents both
programmatically and manually
|| and compare the results:
||
|| 1. Title page, Portrait main section, Landscape main section, Portrait
main section
|| 2. Title page, Portrait annex section, Landscape annex section,
Portrait annex section
|| 3. Title page, Portrait main section, Landscape main section, Portrait
main section,
|| Portrait annex section, Landscape annex section, Portrait annex section
||
|| Oh, boy-oh-boy what fun's in store.

You don't say! :p

It turned out OK, practically no difference between the manually and macro
produced documents. Thanks for the suggestion.

I've discovered another little glitch and hate the solution... I have been
weaning myself from using the Selection object and was proud that this
lengthy code relied exclusively on the range object. My solution forced me
to used the selection object :-(

Glitch:
It seemed that most of the time, if I used the code a second time shortly
after the first time, it ran OK, but no Autotext was inserted in the header
of the landscape page. No error generated either. And from that point on, I
could never get the autotext to appear anywhere in the document unless I did
it manually.

I tried 4 methods (See below) and only the selection one was reliable... Any
ideas? Also strange, the first method would work, but instead of finishing
with a header containing only the Autotext (as desired and expected from the
code), I ended with garbage as well that seemed to come from some text left
over from the ".Range.Text = AutoTextHeader" statement and some text from
the footer of the PREVIOUS section.... Weird, uh?


<snip>
'Unlink target section from previous one so as to preserve the
'previous section's header/footer (It may be redundant if the target
'section is the last one of the document... but it does not matter,
'we can unlink again...)
'Also, add new Header/footer
With ActiveDocument.Sections(CurSection - AdjustSection)
With .Headers(wdHeaderFooterPrimary)
.LinkToPrevious = False
.Range.Delete
End With
With .Footers(wdHeaderFooterPrimary)
.LinkToPrevious = False
.Range.Delete
End With
With .Headers(wdHeaderFooterPrimary)
'________________________________________
'Method 1
' .Range.Text = AutoTextHeader
' .Range.InsertAutoText
'________________________________________

'________________________________________
'Method 2
' Set PageRange = .Range
' PageRange.Collapse wdCollapseEnd
'
ActiveDocument.AttachedTemplate.AutoTextEntries(AutoTextHeader).Insert _
' PageRange, True
'________________________________________
End With

'________________________________________
'Method 3
'
ActiveDocument.AttachedTemplate.AutoTextEntries(AutoTextHeader).Insert _
' Where:=.Headers(wdHeaderFooterPrimary).Range, _
' RichText:=True
'________________________________________
End With
'________________________________________
'Method 4
Application.Browser.Next

Application.ScreenUpdating = False

With ActiveDocument
.ActiveWindow.View.SeekView = wdSeekPrimaryHeader
.AttachedTemplate.AutoTextEntries(AutoTextHeader).Insert _
Selection.Range, True
.ActiveWindow.View.SeekView = wdSeekMainDocument
End With

Application.ScreenRefresh
Application.ScreenUpdating = True
'________________________________________
<\snip>

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
J

Jean-Guy Marcil

Bonjour,

Dans son message, < Cindy M -WordMVP- > écrivait :
In this message, < Cindy M -WordMVP- > wrote:

|| Hi Jean-Guy,
||
|| Like Peter, I don't see anything "at a glance" that would be causing
this. As
|| you're working a lot with sections, however, that's where I'd watch out.
With
|| fields and tables (the other things that get corrupted quite easily),
with VBA
|| and ranges you can actually stick things into "section breaks" -
something the
|| user can't do. So you really have to watch out with MoveLeft, MoveRight
and
|| those kinds of things, because the actual RANGE may not be equal to what
you'd
|| think when you look at the screen display...
||

Thanks, very true.

Usually, during testing, I add a "Range.Select" statement, then stop the
code and look in the document to see what is selected, even delete the
selection to see what's gone and compare it to what I expected to be gone...
Once I am satisfied that the range object points to what I want, I remove
the ".select" line.

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
P

Peter Hewett

Hi Jean-Guy Marcil

Sorry it's 5.30 am here and I need to go to bed!

I've tried messing around with linked headers/footers a number of times and in very
complex situations not always pleased with the results. The one thought I came away from
the experience with is to do things in reverse order, if that makes sense. I don't know
how your code doing it, but I mean work from the back of the document to the front:

- insert section break after page
- unlink after section
- reset different first page/odd/even pages if/as necessary
- insert section break before page
- unlink current page section
- reset different first page/odd/even pages if/as necessary
- change page layout
- delete and update header/footers

Good luck - Peter


Bonjour,

Dans son message, < Peter Hewett > écrivait :
In this message, < Peter Hewett > wrote:

|| Hi Jean-Guy Marcil
||
|| Can't see anything obviously wrong - but since it don't work all that
means is that I'm
|| blind!
||
|| Are there large logos in the header/footers? Inserted multiple times and
unlinked that
|| could cause bloat. Also are the correct sections getting unlinked?
You're not unlinking
|| additional sections that should be linked, causing bloat?
||
|| And of course when you do it manually on a reasonable size document and
use your code on
|| the same reasonable size document do you end up with exactly the same
document/file size?
||
|| I'd do simple tests to create the following documents both
programmatically and manually
|| and compare the results:
||
|| 1. Title page, Portrait main section, Landscape main section, Portrait
main section
|| 2. Title page, Portrait annex section, Landscape annex section,
Portrait annex section
|| 3. Title page, Portrait main section, Landscape main section, Portrait
main section,
|| Portrait annex section, Landscape annex section, Portrait annex section
||
|| Oh, boy-oh-boy what fun's in store.

You don't say! :p

It turned out OK, practically no difference between the manually and macro
produced documents. Thanks for the suggestion.

I've discovered another little glitch and hate the solution... I have been
weaning myself from using the Selection object and was proud that this
lengthy code relied exclusively on the range object. My solution forced me
to used the selection object :-(

Glitch:
It seemed that most of the time, if I used the code a second time shortly
after the first time, it ran OK, but no Autotext was inserted in the header
of the landscape page. No error generated either. And from that point on, I
could never get the autotext to appear anywhere in the document unless I did
it manually.

I tried 4 methods (See below) and only the selection one was reliable... Any
ideas? Also strange, the first method would work, but instead of finishing
with a header containing only the Autotext (as desired and expected from the
code), I ended with garbage as well that seemed to come from some text left
over from the ".Range.Text = AutoTextHeader" statement and some text from
the footer of the PREVIOUS section.... Weird, uh?


<snip>
'Unlink target section from previous one so as to preserve the
'previous section's header/footer (It may be redundant if the target
'section is the last one of the document... but it does not matter,
'we can unlink again...)
'Also, add new Header/footer
With ActiveDocument.Sections(CurSection - AdjustSection)
With .Headers(wdHeaderFooterPrimary)
.LinkToPrevious = False
.Range.Delete
End With
With .Footers(wdHeaderFooterPrimary)
.LinkToPrevious = False
.Range.Delete
End With
With .Headers(wdHeaderFooterPrimary)
'________________________________________
'Method 1
' .Range.Text = AutoTextHeader
' .Range.InsertAutoText
'________________________________________

'________________________________________
'Method 2
' Set PageRange = .Range
' PageRange.Collapse wdCollapseEnd
'
ActiveDocument.AttachedTemplate.AutoTextEntries(AutoTextHeader).Insert _
' PageRange, True
'________________________________________
End With

'________________________________________
'Method 3
'
ActiveDocument.AttachedTemplate.AutoTextEntries(AutoTextHeader).Insert _
' Where:=.Headers(wdHeaderFooterPrimary).Range, _
' RichText:=True
'________________________________________
End With
'________________________________________
'Method 4
Application.Browser.Next

Application.ScreenUpdating = False

With ActiveDocument
.ActiveWindow.View.SeekView = wdSeekPrimaryHeader
.AttachedTemplate.AutoTextEntries(AutoTextHeader).Insert _
Selection.Range, True
.ActiveWindow.View.SeekView = wdSeekMainDocument
End With

Application.ScreenRefresh
Application.ScreenUpdating = True
'________________________________________
<\snip>

HTH + Cheers - Peter
 
J

Jean-Guy Marcil

Bonjour,

Dans son message, < Peter Hewett > écrivait :
In this message, < Peter Hewett > wrote:

|| Hi Jean-Guy Marcil
||
|| Sorry it's 5.30 am here and I need to go to bed!
||
|| I've tried messing around with linked headers/footers a number of times
and in very
|| complex situations not always pleased with the results. The one thought
I came away from
|| the experience with is to do things in reverse order, if that makes
sense. I don't know
|| how your code doing it, but I mean work from the back of the document to
the front:
||
|| - insert section break after page
|| - unlink after section
|| - reset different first page/odd/even pages if/as necessary
|| - insert section break before page
|| - unlink current page section
|| - reset different first page/odd/even pages if/as necessary
|| - change page layout
|| - delete and update header/footers
||
|| Good luck - Peter

Go to bed!

I almost do it in reverse, the difference is that I do it by batch. Add all
the section breaks, then, working in reverse, handle the header/footers:
- insert section break after page
- insert paragraph mark
- insert section break paragraph mark
- unlink after section
- unlink current page section
- change page layout
- delete and update header/footers

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 

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