PDA

View Full Version : [SOLVED:] To Exist or Not to Exist (The case of existing Header/Footers)



gmaxey
10-01-2013, 08:32 AM
My thought is that every basic Word document contains a minimum of six header/footers. 3 headers (first page, even page, primary page) and 3 footers (first page, even page, and primary page). Whether they appear in the document/display content is determined by the Page Layout>Page Setup>Layout>Headers and Footers settings applied to the section.

In VBA the HeaderFooter object has a property "Exists" which seems to have no relationship to whether a header/footer exists or not as they seem to always exist. Am I missing something or should perhaps this property more accurately be called "Displayed?"


Sub ScratchMacro()
'A basic Word macro coded by Greg Maxey
'Each section appears to "always" have different header/footers.
'Whether they display content or not depends on the Page Layout>Setup _
"Different first page" and "Different Odd & Even Pages" settings.
'Starting with a new blank document from a clean normal.dotm.
Dim oHF As HeaderFooter
'The two default primary header/footers.
Set oHF = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary)
Set oHF = ActiveDocument.Sections(1).Footers(wdHeaderFooterPrimary)
'The remaining four. If they didn't exist then shouldn't this code error?
Set oHF = ActiveDocument.Sections(1).Headers(wdHeaderFooterEvenPages)
Set oHF = ActiveDocument.Sections(1).Footers(wdHeaderFooterEvenPages)
Set oHF = ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage)
Set oHF = ActiveDocument.Sections(1).Footers(wdHeaderFooterFirstPage)
'Our firstpage footer
If oHF.Exists Then
oHF.Range.Text = "I exist so here is my text."
Else
'That doesn't exist.
oHF.Range.Text = "I didn't exist but here is my text anyway."
End If
'I don't think ".Exists" really has much bearing on whether they exist or not ;-)
'Show the text
ActiveDocument.Sections(1).PageSetup.DifferentFirstPageHeaderFooter = True
End Sub

fumei
10-01-2013, 01:40 PM
Greg, that is correct. I have posted this a number of times, and with essentially the exact same code to demonstrate it. Exist ONLY reflects whether FirstPage andor OddEven is checked in Page Setup. The six objects ALWAYS exist, as you have -again - demonstrated, as text content can be returned even if "Exist" returns a False.

I know you are a coder, and not a professional document creator, but the fact that the six headerfooter objects always exist is - ahem - a feature. Well, the Exist property is not, and I never use it because it is in real world tems, useless. But objects themselves always existing is a feature. It permits the insertion of content into the objects without the objects even showing in the document. Or even being set in Page Setup.

That is, you can put content into FirstPage, OddEven, with only ONE page being in the document. When pages are increased automatically by the addition of material, the appropriate headers and footers (assuming they are set via page setup, or by code) will appear - also automatically. No user additions or modifications required.

It by this method that, if you designed this properly, major grief can be avoided with headerfooters and new Setions.

But yup, Exist only has to do with whether FirstPage, OddEven are checked. Technically speaking it is not a display issue. It is a property set issue. If there is only one page, then obviously OddEven is not displayed, but if is is SET as checked, then Exist returns True. But all six headers exist, all the time.

This is one reason I object when people state six headerfooters "may" be in a section. Not true. There is no "may". They are ALWAYS there.

I have written a number of times that I think the Exist property is badly misnamed, and frankly should be retired because it has, number of times, confused people.

gmaxey
10-01-2013, 02:15 PM
Gerry,

Thanks. How do I convince you that I didn't bootleg your code? ;-)
Actually I saw something posted the other day by a heavily medaled contributor in the MSDN support forum that made me think I could be wrong.

fumei
10-01-2013, 02:34 PM
Oh, not to worry. I know you did it as your own thing, otherwise I doubt you would have posted. You are not one to waste your time.

Can you post a link to that MSDN post. I would like see that. As your code has proved...all six are always there. It has been that way for a very very long time. If the MSDN-er posted otherwise, they are simply wrong. Although, I have seen threads by quite knowledgeable people regarding Exist. As stated, I have posted the actual situations to a number of threads - even by those who should know better.

gmaxey
10-01-2013, 04:57 PM
Gerry,

Sure http://social.msdn.microsoft.com/Forums/office/en-US/1b8a4590-0fa3-4ba2-afc2-5dd38c5b1fe4/what-is-a-story-in-ms-word. I'm not saying the poster is adamant concerning the point. There was no reply.

fumei
10-01-2013, 08:28 PM
Ah Hans does know his stuff, for sure, but in fact this is not the first time I have responded to him posting about Exists. I am not sure why this concept has such persistence as it can clearly - and easily - be proved incorrect.

fumei
10-01-2013, 08:36 PM
It also does not make any sense.

If all six headerfooter objects in a section did NOT exist - the "may" or "can have" - that would mean when you create a new section you would be forced to CREATE headerfooter objects for that new section. This is clearly not the case.

gmaxey
10-02-2013, 06:10 AM
Gerry,

I concur. When there was no response I just figured he didn't see my post or didn't want to enter the fray ;-)

EricFletcher
10-02-2013, 09:28 AM
I'm with you on how this sloppy nomenclature has confused people. The very fact that you can easily create a supposedly empty document that "magically" displays all 6 different header/footer type shows it even more convincingly than Greg's code IMHO.

The trick is to add a couple of manual page breaks so you have at least 3 pages to be able to set up the header/footers—and of course to use Page Setup to manage the section layout options. You can then delete the manual page breaks; the header/footers for pages >1 will appear as content is added to warrant their display.

I've often used this as an eye-opening intro to page layout training classes: people are astonished when the header/footers appear, so I have their attention when I then go on to explain why it works and how to manage it.

Frosty
10-02-2013, 02:49 PM
Yes, .Exists should be called .IsDisplayed.

It is actually a helpful property, in that it is a shortcut to checking the .PageSetup.DifferentFirstPageHeaderFooter and .PageSetup.OddAndEvenPagesHeaderFooter properties, which are only available on the document object.

If you have a function where you've passed the HeaderFooter object (as "hf" or something else), but need to check those properties, .Exists can be more "friendly" (even with a bad name) than having to do hf.Parent.PageSetup.DifferentFirstPageHeaderFooter.

That said -- I also discovered something interesting while looking at this ... despite .OddAndEvenPagesHeaderFooter be a property off the section object, it is actually a document setting. Two section document, modifying section one also affects section 2. This appears true through the user interface as well as from code.

The only caveat with headers/footers being accessed via code, is what I'm sure everyone who already participated in this thread already knows -- accessing the .Range object of a header footer via code actually "creates" the story range as soon as you modify. And the only way to "uncreate" that story range, even if empty, is by clicking in the header (or doing the VBA equivalent, using .SeekView).

Note: most effective to run the following code on a "clean" winword process, by doing Start > Run > winword /a -- otherwise however you've modified your normal template may not have an effective change to the story ranges.



Sub Demo()
With ActiveDocument
MsgBox "Story Ranges Count: " & .StoryRanges.Count
.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = ""
MsgBox "Story Ranges Count: " & .StoryRanges.Count & vbCr & _
"Now we'll jiggle the handle a bit"
End With
With ActiveDocument.ActiveWindow.View
.SeekView = wdSeekCurrentPageHeader
.SeekView = wdSeekMainDocument
End With
MsgBox "Story Ranges Count: " & ActiveDocument.StoryRanges.Count
End Sub

(Hey gentleman -- I've been absolutely swamped for what feels like years)

fumei
10-02-2013, 05:53 PM
Eric, that is exactly what I do as well. For a document that has continuing sections like chapter, with same Odd page the document title (same for all sections - chapters) and Even being the chapter title, I make a new section by code, not manually. That way all the appropriate headers are done immediately. The code then removes the page breaks but this of course retains the header footer for what will come later.

And yes, it never failed to impress students when text added to make new pages caused automatic proper headers.

That said -- I also discovered something interesting while looking at this ... despite .OddAndEvenPagesHeaderFooter be a property off the section object, it is actually a document setting. Two section document, modifying section one also affects section 2. This appears true through the user interface as well as from code.

Yes this is true, and I do not know of another sort of doubling up. It is a section object, but a document setting. I have always thought this was a little sloppy in terms of the object model. I fail to see why you could NOT have different setting for each section. True, I have no doubt it would make it even worse for people to handle section headers. I believe it is for that reason that Microsoft keeps it as a document setting. It is bad enough for people to grasp things. If it was truly independent for each section most would tear their hair out even more.

I doubt this will ever change. I know I have tried to educate regarding the existing model and even in class with clear demonstrations it was often one of the most difficult for students to understand.

fumei
10-02-2013, 05:59 PM
BTW, it IS possible to make seem like Different and OddEven are different for each section, but it is fussy and you really have to get it perfect. Otherwise any changes completely screw things up. But it IS possible.

fumei
10-02-2013, 06:07 PM
"Yes, .Exists should be called .IsDisplayed."

Hmmmm. What if they are NOT displayed - it is a single page so there is no OddEven displayed for example - but the SETTING is set to true. So I am not sure IsDisplayed would be appropriate.





I am just being contrary....

IsSet might be good. It is not going to happen.

fumei
10-02-2013, 06:12 PM
Finally, yeah, that "creation" of the storyrange when you modify an "empty" header is seriously annoying.

gmaxey
10-03-2013, 06:32 AM
Jason,

Yes and interesting that only OddAndEvenPagesHeaderFooter behaves this way. The DifferentFirstPageHeaderFooter appears to be an independent section property.

Again starting with a clean new document (or as you described):


Sub ScratchMacro()
'A basic Word macro coded by Greg Maxey
Dim oRng As Word.Range
Dim oSec As Section
Debug.Print ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Exists 'True
Debug.Print ActiveDocument.Sections(1).Headers(wdHeaderFooterEvenPages).Exists 'False
Debug.Print ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Exists 'False
Set oRng = ActiveDocument.Range
oRng.Text = "XXXXXXXXXXXXXXXXXX"
oRng.Collapse wdCollapseEnd
Set oSec = ActiveDocument.Sections.Add(oRng)
oSec.PageSetup.DifferentFirstPageHeaderFooter = True
oSec.PageSetup.OddAndEvenPagesHeaderFooter = True
'Go back and re-evaluate section 1:
Debug.Print ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Exists 'True
Debug.Print ActiveDocument.Sections(1).Headers(wdHeaderFooterEvenPages).Exists 'True
Debug.Print ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Exists 'False
End Sub

Mark90
10-04-2013, 04:01 AM
The trick is to add a couple of manual page breaks so you have at least 3 pages to be able to set up the header/footers—and of course to use Page Setup to manage the section layout options. You can then delete the manual page breaks; the header/footers for pages >1 will appear as content is added to warrant their display.

I've often used this as an eye-opening intro to page layout training classes: people are astonished when the header/footers appear, so I have their attention when I then go on to explain why it works and how to manage it.

Eric, a friend showed this to me recently, and as you say it was quite a shock. I'm confused though, where do you think Hans' confusion on the matter comes from? Still a newbie, so conflicting information on a topic is making my head spin.

fumei
10-04-2013, 01:27 PM
Mark90, if I may...

I am not sure I would call Hans' post as being confused, it is more that it is incorrect. He states that a section "may have" the six headerfooter objects. This is incorrect. There is no "may", as that implies a possibility. It may...or it may not. No. There is no "may have" because there is ALWAYS the six headerfooters. A section can not have less. They are always there.

I think that Hans' comment can CAUSE confusion.