Is there a way, using vba, to determine if a footnote ends on the same page it begun on?
If the footnote flows over to the next page Selection.Range.Characters.First.Information(3) returns the number of the beginning page, not the current page.
Is there a way, using vba, to determine if a footnote ends on the same page it begun on?
If the footnote flows over to the next page Selection.Range.Characters.First.Information(3) returns the number of the beginning page, not the current page.
There may be a more efficient way to do this, but this seems to work...
Public Function fFootNoteIsSplit(Optional iFootnote As Integer = 1) As Boolean Dim f As Footnote Dim char As Range Dim iNumFirstLines As Integer If ActiveDocument.Footnotes.Count = 0 Then fFootNoteIsSplit = False End If Set f = ActiveDocument.Footnotes(iFootnote) For Each char In f.Range.Words If char.Information(wdVerticalPositionRelativeToTextBoundary) = 0 Then If iNumFirstLines > 0 Then fFootNoteIsSplit = True Exit For End If Else iNumFirstLines = iNumFirstLines + 1 End If Next End Function
Actually, I'm sure there's a more efficient way than cycling through all of the characters in the footnote's range... just using .Words instead of .Characters (which I've already changed) would give less cycles to the loop, but the essential approach has to be something related to checking the vertical position (at least, I *think* it does).
But without using selection, you can't really move line by line, so .Words seems like it might be as good as it gets, because the footnote might be a single paragraph...
I'm curious if anyone comes up with something else... you always seem to have interesting little problems, MacroShadow![]()
Thank you.
This question I asked on behalf of a co-worker. lol.Originally Posted by Frosty
Actually how did you get a footnote to 'flow' to the next page?
As I add text to the footnote, the footnote line keeps climbing up the page, and the vertical size of the footnote gets bigger. (Word 2010)
A second footnote keeps climbing
I could probalby have a 1/2 page footnote section at that rate.
It would be nice if any footnote or footnotes that required more than a set space would continue on the next page in the footnote position
Paul
A footnote will fill up the entire page, as long as it starts on the same page as its reference. Try inserting your footnote closer to the bottom of the page to begin with.
thanks
I thought that at one time there was a setting as to how much footnote space there was at the bottom of the page, after margins and footers.
Guess not
Seems funny that it'd be sensitve to where the foot note is inserted
Paul
For a simple example, pages and rectangles seems to work:
Sub ScratchMacro() Dim oPage As Page Dim oRect As Rectangle Dim oRng As Word.Range Dim oRngFN As Word.Range Set oRngFN = ActiveDocument.Footnotes(1).Range Set oPage = ActiveDocument.ActiveWindow.Panes(1).Pages(ActiveDocument.Footnotes(1).Range.Information(3)) Set oRect = oPage.Rectangles(3) '1 is main text, 2 is the separator 3 is the footnotes. 'not sure this would always be the case Set oRng = oRect.Range If oRngFN.InRange(oRng) Then Debug.Print "FN is on same page" Else Debug.Print "FN spans multiple pages." End If End Sub
Frosty,
There is one problem with your function. If the footnote spans over multiple columns on the same page it still returns True.
Greg,
Is there a way to turn your macro into a function that will take the footnote number as a parameter (like Frosty's code)?
I tried but couldn't get it to work.
Sub Test() MsgBox ScratchMacro(1) End Sub Function ScratchMacro(lngIndex) As String Dim oPage As Page Dim oRect As Rectangle Dim oRng As Word.Range Dim oRngFN As Word.Range Set oRngFN = ActiveDocument.Footnotes(lngIndex).Range Set oPage = ActiveDocument.ActiveWindow.Panes(1).Pages(ActiveDocument.Footnotes(lngIndex).Range.Information(3)) Set oRect = oPage.Rectangles(3) '1 is main text, 2 is the separator 3 is the footnotes. 'not sure this would always be the case Set oRng = oRect.Range If oRngFN.InRange(oRng) Then ScratchMacro = "Yes, the FN is on same page" Else ScratchMacro = "No, the FN spans multiple pages." End If End Function
That is basically what I tried.
If the footnote is not in the first column (in a multi column layout) it returns: No, the FN spans multiple pages even when the footnote doesn't flow over to the next page.
can you post a sample doc, MacroShadow? I don't even know how your set up is... this is back to your custom footnotes with linked textboxes, right?
I *suspect* you can use my function (at least) and simply check for a reset twice... but it would need to be modified somewhat to assume that the footnotes are always in two columns. Otherwise you need a separate function to test if this is a two-column footnote set up or a one-column footnote setup...
That is not a condition in your original post. It will help if you fully define the scope of what you are after.
This will probably work for 2 columns, but not for 1 or 3:
Sub Test() MsgBox ScratchMacro(1) End Sub Function ScratchMacro(lngIndex) As String Dim oPage As Page Dim oRect As Rectangle Dim oRect2 As Rectangle Dim oRng As Word.Range Dim oRng2 As Word.Range Dim oRngFN As Word.Range Set oRngFN = ActiveDocument.Footnotes(lngIndex).Range Set oPage = ActiveDocument.ActiveWindow.Panes(1).Pages(ActiveDocument.Footnotes(lngIndex).Range.Information(3)) Set oRect = oPage.Rectangles(4) '1 is main text column 1, 2 is main text column 2, 3 is the col 1separator '4 is col1 footnotes, 5 is col2 separator, 6 is col 2 footnotes. Set oRect2 = oPage.Rectangles(6) 'not sure this would always be the case Set oRng = oRngFN.Duplicate Set oRng2 = oRngFN.Duplicate oRng.Collapse wdCollapseStart oRng2.Collapse wdCollapseEnd If oRng.InRange(oRect.Range) And oRng2.InRange(oRect2.Range) Then ScratchMacro = "Yes, the FN is on same page" Else ScratchMacro = "No, the FN spans multiple pages." End If End Function
It will also help if you post what you've tried. This way people can spend their time trying to help you with what you've tried rather than spend it redoing what you, after the fact, inform us that you have already done.
Originally Posted by MacroShadow
I agree with Greg: MacroShadow, you've been posting long enough here that you can give better information sooner, and post the kinds of things you've tried.
You're getting to the point that I got when I started programming. I kept asking my mentor "what about this, what about that" and he continued to patiently teach me. But then, at some point, his responses started becoming "Umm, I don't know-- figure it out. That's the job."
You won't get that response here, but there is a point where you're good enough to put in effort too.
That said... this is considerably more tricky, and this is what I've come up with. It seems to work regardless of the number of columns, or what column the initial footnote reference starts in.
Public Function fFootNoteIsSplit(Optional iFootnote As Integer = 1, Optional oDoc As Document) As Boolean Dim fn As Footnote Dim rngWord As Range Dim iNumFirstLinesInFootnote As Integer Dim iNumColumnsInSection As Integer Dim lLocation As Long On Error GoTo l_err 'if no document passed, use the active document If oDoc Is Nothing Then Set oDoc = ActiveDocument End If 'if no footnotes, then return false and exit If oDoc.Footnotes.Count = 0 Then fFootNoteIsSplit = False MsgBox "No footnotes in this document.", vbInformation, "Footnote Checker" GoTo l_exit End If 'get the footnote Set fn = oDoc.Footnotes(iFootnote) 'see how many columns in the footnote reference's section iNumColumnsInSection = fn.Reference.Sections.First.PageSetup.TextColumns.Count For Each rngWord In fn.Range.Words 'check to see if this word is the first word, or the beginning of a text column If rngWord = fn.Range.Words.First _ Or rngWord.Information(wdVerticalPositionRelativeToTextBoundary) = 0 _ And rngWord.Information(wdHorizontalPositionRelativeToTextBoundary) = 0 Then 'check where it's horizontally located on the page, relative to any previous setting If rngWord.Information(wdHorizontalPositionRelativeToPage) > lLocation Then lLocation = rngWord.Information(wdHorizontalPositionRelativeToPage) 'also, increment our first line counter iNumFirstLinesInFootnote = iNumFirstLinesInFootnote + 1 'if we've got a location that is closer to the left than a previous setting, 'we know we've hit a new page, so the range is split... we're done Else fFootNoteIsSplit = True Exit For End If End If 'if we've gotten more first lines than columns, we know it's split If iNumFirstLinesInFootnote > iNumColumnsInSection Then fFootNoteIsSplit = True Exit For End If Next l_exit: Exit Function l_err: MsgBox "Error in this function-- decide what you want to return" Resume l_exit End Function
Alright-- so I played around with the .Pages and .Rectangles collections a bit. Not to take the original post too off-topic, but I don't think making the assumption on the specific rectangle number can be a good approach to this problem, because you have to make too many assumptions about the layout of the document.
The .Page object is relatively simple to access (although you *have* to be in print layout view, which is a limiter)... but the number of rectangles on a page is too much of a variable.
On a single page, two columns of main story text with a single footnote that also spans two columns... you will have 6 rectangles (as Greg's comments articulate).
However, if the right column of the page is entirely taken up with the footnote (i.e., no main story text), you'll only have 5 rectangles.
Also, if you insert a text box on the page, you'll have a totally different rectangles count. And depending on the .WrapFormat of that text box (inline, top/bottom, tight, etc), the rectangles count will adjust as well. Because the .Rectangles collection seems to be an attempt to return valid "text" areas of that particular page (somewhat analogous to the way a powerpoint slide is laid out).
Granted, I don't know alot about this area of the object model, and Greg knows a lot more-- but it seems that the only way to use the rectangles collection is to iterate through all of them on the page, and then determine whether they are valid areas you're interested in... that's what I've done using the Rectangles approach that Greg started. This seems to work as well, although it has the limitation of requiring Print View/Page Layout to be turned on -- on the other hand, it's much much more readable code and structure.
Public Function fFootNoteIsSplit_Alt1(Optional iFootnote As Integer = 1, _ Optional oDoc As Document) As Boolean Dim r As Rectangle Dim p As Page Dim fn As Footnote Dim rLastFootnoteOnPage As Range If oDoc Is Nothing Then Set oDoc = ActiveDocument End If If oDoc.ActiveWindow.ActivePane.View.Type <> wdPrintView Then MsgBox "You must be in page layout view to use this function" Exit Function End If Set fn = oDoc.Footnotes(iFootnote) Set p = oDoc.ActiveWindow.ActivePane.Pages(1) 'cycle through the main footnote story rectangles For Each r In p.Rectangles If r.RectangleType = wdTextRectangle Then If r.Range.StoryType = wdFootnotesStory Then 'get the range of the last footnote on the page Set rLastFootnoteOnPage = r.Range.Duplicate End If End If Next 'the range of whole footnote doesn't include the paragraph mark, so we add 1 to the .End test If rLastFootnoteOnPage.End = fn.Range.End + 1 Then fFootNoteIsSplit_Alt1 = False Else fFootNoteIsSplit_Alt1 = True End If End Function
Jason,
You very well may have crossed the Rubicon. You may now know alot more about panes, pages, rectangles, and lines than I do.
I know about them, and I know that sometimes there are some neat tricks that you can pull off using them.
Other than that, I pass the hat. You are now the resident expert ;-)
Ha. We'll see. I have no doubt you'll surprise me with something else. I just worry areas of the object model I don't understand like a dog worries a bone. So I played a bit. It's a pretty powerful area, in terms of identifying areas on a particular page. But the limitation of page layout view (and the general concept of pages in word) probably means it has to be use in pretty narrow circumstances.
MacroShadow-- because of all the layout work you're doing, you should really explore the rectangles collection... It might simplify some of your coding.
You know of the countless thousands of hours I've sat working with a Word document on screen, I'll bet that not five minutes of it was spent outside of print layout view.
For some people Normal (or Draft) is normal, but anything other that print layout just freaks me out.