PDA

View Full Version : [SOLVED:] Activedocument.Footnotes.Reference.Text



dorogoi
03-29-2010, 02:22 PM
Hi Everyone,

I have a bit of a problem for which I'd like some input from the community. I have created a VBA macro in Word (2000, 2003, 2007 respond in the same manner) that requires me to obtain pre-existing reference mark values of footnotes and endnotes. When I attempt to obtain the actual text of the reference mark using "ActiveDocument.Footnotes.Reference.Text" I am given a square(!) -- presumably because Word cannot store/display the proper reference mark text -- whereas I am expecting a footnote numeral (e.g. "1" or "i" or "a").

Has anyone else experienced this, and does a work-around exist?

Here is an example that gives me a square instead of the proper "1" text value:


Call ActiveDocument.Footnotes.Add(Selection.Range, , "Footnote text")
MsgBox ActiveDocument.Footnotes.Item(1).Reference.Text

Thanks for any insight!

lucas
03-29-2010, 02:58 PM
I think it's a range.

MsgBox ActiveDocument.Footnotes.Item(1).Range.Text

dorogoi
03-29-2010, 03:18 PM
I think it's a range.

MsgBox ActiveDocument.Footnotes.Item(1).Range.Text
Thanks for the quick reply.

.Range will return the text of the footnote, not the reference mark number of the footnote.

Paul_Hossler
03-29-2010, 04:32 PM
Is this it?


ActiveDocument.Footnotes (1).Range.FootnoteOptions.StartingNumber


Paul

dorogoi
03-29-2010, 04:49 PM
Is this it?


ActiveDocument.Footnotes (1).Range.FootnoteOptions.StartingNumber

Paul


Thanks for the ideas, but, unfortunately, no, that's not it. This will only provide the ordinal value of the first reference.

For each foot/endnote in the Footnotes or Endnotes collection, it is supposed to be able to return its "reference mark".

I.e. If footnotes are using roman numerals, and one is iterating through each footnote item in the footnotes collection, the footnotes object's ".reference.text" is ~supposed~ to return "i", "ii", "iii" etc. If the footnotes are using lower case letters it should return "a", "b", "c". A programmer should not have to "calculate" the proper value.

I am getting a lovely yet completely useless square.

dorogoi
03-29-2010, 04:51 PM
Is there anyone out there that isn't receiving a square in the msgbox?

macropod
03-29-2010, 05:40 PM
Hi dorogoi,

Try something along the lines of:

Sub Test()
Dim oRng As Range
Set oRng = Selection.Range
With oRng
.Start = .End
.Footnotes.Add oRng, , "Footnote text"
.MoveEnd wdCharacter, 1
MsgBox "The footnote you just inserted is # " & .Footnotes(1).Index & "."
End With
End Sub

Paul_Hossler
03-29-2010, 06:29 PM
Not sure if it means anything, but I think the box that is being displayed ...



MsgBox ActiveDocument.Footnotes.Item(1).Reference.Text


... is part of the internal Word document structure. It might the the 'marker' for a Foot note (ASCII 2 I think)

I did a little test. Put 3 footnotes in a doc (lower case roman numeals), and looped thru them

#1 - was .Index 1
#2 - was .Index 2
#3 - was .Index 3

Then I added a new footnote before #1, and they renumbered 1-4 as expected

Looped through again

New one - was .Index 1
#1 - was .Index 2
#2 - was .Index 3
#3 - was .Index 4


I think you're right --MS made it pretty hard to retreive the footnote number. I guess it's because it has to calculate them on the fly

Hopefully some much more experienced person has something better, because the only thing I can up with is UGLY


Option Explicit
Sub ListFootnotes()
Dim iNumber As Long
Dim oFootnote As Footnote
For Each oFootnote In ActiveDocument.Footnotes
With oFootnote
iNumber = .Range.FootnoteOptions.StartingNumber + .Index - 1
Select Case .Range.FootnoteOptions.NumberStyle
'only format I did
Case wdNoteNumberStyleLowercaseRoman
'brute force
Select Case iNumber
Case 1
MsgBox .Index & " -- " & .Range.Text & " -- " & "I"
Case 2
MsgBox .Index & " -- " & .Range.Text & " -- " & "ii"
Case 3
MsgBox .Index & " -- " & .Range.Text & " -- " & "iii"
Case 4
MsgBox .Index & " -- " & .Range.Text & " -- " & "iv"
Case 5
MsgBox .Index & " -- " & .Range.Text & " -- " & "v"
End Select
Case wdNoteNumberStyleUppercaseRoman
Case wdNoteNumberStyleUppercaseLetter
Case wdNoteNumberStyleSymbol
Case wdNoteNumberStyleLowercaseLetter
Case wdNoteNumberStyleArabic
End Select
End With
Next
End Sub



Lots and lots of luck :thumb

Paul

macropod
03-29-2010, 06:44 PM
MS made it pretty hard to retreive the footnote number.Somehow I don't think so - check out the code in my last post. Not exactly difficult IMHO.

lucas
03-29-2010, 07:22 PM
Is there anyone out there that isn't receiving a square in the msgbox?

Using you code from post #1, I get no square

I get an empty msgbox

macropod's code at post 7 gives me the number of the last footnote added.

Paul_Hossler
03-30-2010, 05:43 AM
Absolutely correct - Mac's works to give the last foot note added

I was (possibly) misunderstanding the OP's comment ...



that requires me to obtain pre-existing reference mark values of footnotes and endnotes.


... to mean that they were looking for the reference number for ANY footnote, not just the last one added.

Can the code be generalized to work with any pre-existing footnotes?

Paul

dorogoi
03-30-2010, 08:39 AM
Thanks Macropos, Paul_Hossler, and lucas for the great input.

Firstly, the code I posted is to quickly and easily demonstrate that the .Reference.Text property is not working as intended/expected. Believe it or not, I was able to retrieve the reference mark value when I first started my project. I am not sure what the difference is yet, but I suspect it is possible to determine.

Secondly, the heart of the matter. My intent is to convert an existing document's (created by a third party) foot/endnotes to regular text at the end of the document, maintaining the original reference marks precisely (i.e. superscript mark in-paragraph and at the beginning of the footnote text). There is potential for foot/endnote marks to be interlaced, upper/lower case letters/roman numerals and numbers -- with manual edits (renumbering) as well.

It becomes very complicated when the numbering rule for footnotes is different than that of endnotes...especially when it can be per page, section etc etc. Reassigning reference marks is not an option, so I either need to create a routine that will A) precisely calculate the reference mark via its .Index, and the document's ActiveDocument.Footnotes.NumberRule, and ActiveDocument.Footnotes.NumberStyle properties, or b) use the handy-but-mostly-broken .Reference.Text property.

.NumberRule is going to be the hard part as I will have to determine when the number resets, not my idea of fun.

And all of the above does not take into account if there is a manually assigned value (i.e. maybe the original author skipped numbers 10 through 19 for some reason).

Paul: I suspect you are correct. I believe that the "square" that I see is either a pointer of sorts, or perhaps an internal reserved value indicating that it should, indeed, be calculated on the fly. Yes, it is an ASCII value of 2 that I have here as well. If I assign .reference.text a string value of anything (i.e. "1"), it replaces the in-paragraph reference mark with a non-superscript value (i.e. 1) and deletes the foot/endnote entirely. If I assign it Chr(2), it replaces the in-paragraph mark with a square and deletes the foot/endnote. This indicates to me that its currently assigned Chr(2) value is special in some way.

It still doesn't make sense, as most everything is calculated on the fly in any programming language, what is so unusual about this? (except that I need it to function properly)

I just did some testing. Oddly enough, if the reference mark is a "custom mark", .Reference.Text returns the proper value (i.e. I created a footnote with a "$" as its mark, and it was properly returned via the .Reference.Text property).

Paul_Hossler
03-30-2010, 11:17 AM
This indicates to me that its currently assigned Chr(2) value is special in some way.


Word uses a lot of special 'markers' that are not displayed or only partial displayed. For example, the paragraph mark symbol displays as a single character, but there's a lot of information there (style, section information, header/footer, etc.)

On the Document (not VBE) side, if you look for Edit in the Help, and then go to "Find and Replace Text or other Items" you can see some of the internal values (you can search for them, but there are rules: wild cards on/off / In find box / In replace box)

^2 is a Footnote, ^19 and ^21 are Fields,^5 is a Comment, ^14 is a column break. Some have ^letter equivalents, but internally I think Word marks things with a ASCII 2 or ACSII 19.

Paul

Paul_Hossler
03-30-2010, 12:55 PM
Little more experimenting -- simple doc with 6 footnotes

ran little macro

First msgbox was index (1-6) and the text of the correspnding footnote
Second msg box was the square and the number 2 (the ascii value of the square)



Option Explicit
Sub ListFootnotes()
Dim oFootnote As Footnote
For Each oFootnote In ActiveDocument.Footnotes
With oFootnote
MsgBox .Index & " - " & .Range.Text
'this displays box and '2' the value of the footnote marker
MsgBox .Reference.Text & " -- " & Asc(.Reference.Text)
End With
Next
End Sub


Interesting

Hope you get it figured out

Paul

macropod
03-30-2010, 02:44 PM
Hi dorogoi,

My intent is to convert an existing document's (created by a third party) foot/endnotes to regular text at the end of the document, maintaining the original reference marks precisely (i.e. superscript mark in-paragraph and at the beginning of the footnote text).
For converting endnotes, you could use code like:

Sub UnLinkEndNotes()
Dim eRng As Range, eNote As Endnote, i As Integer
With ActiveDocument
For Each eNote In .Endnotes
With eNote
i = .Index
With .Reference.Characters.Last
.InsertBefore i
.Style = "Endnote Reference"
End With
.Range.Cut
End With
Set eRng = .Range
With eRng
.InsertAfter vbCr & i & " - "
.Start = .End
.Paste
.Style = "Endnote Text"
End With
Next
For Each eNote In .Endnotes
eNote.Delete
Next
End With
End Sub
With minor changes, the code can process footnotes instead. Nonetheless, footnotes will be inserted at the end of the document - programatically inserting them at the foot of each page is problematic, especially because Word uses the current printer driver to work out where the automatic page breaks should occur. Change printers and you could end up with page breaks occuring in a different position.

There is potential for foot/endnote marks to be interlaced, upper/lower case letters/roman numerals and numbers -- with manual edits (renumbering) as well.Provided you convert the footnotes and endnotes separately, the fact they're interspersed within the document shouldn't matter. A limitation of the above macro, though, is that it doesn't handle the different numbering schemes that usually entails - for whichever references require it, you would need to do a bit of post-processing on the reference numbers to convert them to, say, roman numerals. The fact the macro preserves the corresponding Style names makes this fairly easy to do. An alternative is to change the footnotes to endnotes before running the macro, then process them all as a single set. I do note, though, your desire not to do this.

And all of the above does not take into account if there is a manually assigned value (i.e. maybe the original author skipped numbers 10 through 19 for some reason).With Word, that's not a problem - simply because any re-starts & skipped ranges will be ignored by the macro. Usually, you can only re-start on a Section by Section basis. Again, the macro could be modofied to process each Section independently and to put the notes at the end of the Section rather than at the end of the document. What you might need to deal with, though, is footnote/endnote cross-references. I suggest dealing with those by converting them to plain text (eg by selecting them and pressing Ctrl-Shift-F9) before running the above macro.

macropod
03-30-2010, 04:50 PM
Hi dorogoi,

Here's an enhanced version of the macro, that faithfully replicates the referencing type (eg roman numerals):

Sub UnLinkEndNotes()
Application.ScreenUpdating = False
Dim eRng As Range, eNote As Endnote, eRef As String
With ActiveDocument
For Each eNote In .Endnotes
With eNote
With .Reference.Characters.First
.Collapse
.InsertCrossReference wdRefTypeEndnote, wdEndnoteNumberFormatted, eNote.Index
eRef = .Characters.First.Fields(1).Result
.Characters.First.Fields(1).Unlink
End With
.Range.Cut
End With
Set eRng = .Range
With eRng
.InsertAfter vbCr & eRef & " - "
.Start = .End
.Paste
.Style = "Endnote Text"
End With
Next
For Each eNote In .Endnotes
eNote.Delete
Next
End With
Set eRng = Nothing
Application.ScreenUpdating = True
End Sub
To get the reference type, I (simply?) inserted a cross-reference to the endnote and captured the cross-reference text before unlinking it.

dorogoi
03-31-2010, 02:53 PM
With minor changes, the code can process footnotes instead. Nonetheless, footnotes will be inserted at the end of the document - programatically inserting them at the foot of each page is problematic, especially because Word uses the current printer driver to work out where the automatic page breaks should occur. Change printers and you could end up with page breaks occuring in a different position. This is not a problem, all the references will be at the end of the document.


Provided you convert the footnotes and endnotes separately, the fact they're interspersed within the document shouldn't matter. A limitation of the above macro, though, is that it doesn't handle the different numbering schemes that usually entails - for whichever references require it, you would need to do a bit of post-processing on the reference numbers to convert them to, say, roman numerals. The fact the macro preserves the corresponding Style names makes this fairly easy to do. An alternative is to change the footnotes to endnotes before running the macro, then process them all as a single set. I intend to process both separately (then assign a different color to the reference marks in case the author haphazardly decides to use the same numbering style for both foot and endnotes, so I suspect that it won't be an issue.



Usually, you can only re-start on a Section by Section basis. Again, the macro could be modofied to process each Section independently and to put the notes at the end of the Section rather than at the end of the document. I don't think this will be necessary, but I know exactly what you mean. If numbering is restarted, there is no way to easily discriminate once the notes are at the end of the document. I wonder if I can pre-pend a (Section X or Page X) to each reference...but I'm not worried about that.


What you might need to deal with, though, is footnote/endnote cross-references. I suggest dealing with those by converting them to plain text (eg by selecting them and pressing Ctrl-Shift-F9) before running the above macro. I am not sure to what you are referring. The resultant text appears to be plain text, which should be sufficient.

There's a bit of tweaking I have to do, so I'm off to go testing. I'll be back in a little bit.

Thank you very much macropod, and everyone that offered a helping hand.

Paul_Hossler
03-31-2010, 06:04 PM
Please post the result so I can see how you did it

Paul

macropod
03-31-2010, 08:13 PM
What you might need to deal with, though, is footnote/endnote cross-references. I suggest dealing with those by converting them to plain text (eg by selecting them and pressing Ctrl-Shift-F9) before running the above macro.
I am not sure to what you are referring. The resultant text appears to be plain text, which should be sufficient.If the author insert a footnote (or endnote), then inserts a cross-reference to it, the cross-reference fields will still be in the document after the macro has done its thing. Once you do a print preview or print the document, though, all those now-invalid cross-references will update and you'll have a document littered with 'Error! Reference source not found.' messages instead.

dorogoi
04-06-2010, 01:32 PM
If the author insert a footnote (or endnote), then inserts a cross-reference to it, the cross-reference fields will still be in the document after the macro has done its thing. Once you do a print preview or print the document, though, all those now-invalid cross-references will update and you'll have a document littered with 'Error! Reference source not found.' messages instead.

Ah, right. That makes sense. I'm quite sure that the source text will never include a Word cross-reference, so I'm not worried about it at all.

Here's my final VB code that color codes footnotes green, and endnotes as red in the unlikely event that the author uses the same .numberstyle for both:


Sub VBAXFootnote()
' VBAXFootnote Macro
' Macro created 31/03/2010 by None
Application.ScreenUpdating = False
Dim eRng As Range
Dim fRng As Range
Dim eNote As Endnote
Dim fNote As Footnote
Dim eRef As String
'Foot Notes
With ActiveDocument
For Each fNote In .Footnotes
With fNote
With .Reference.Characters.First
.Collapse
.InsertCrossReference wdRefTypeFootnote, wdFootnoteNumberFormatted, fNote.Index
eRef = .Characters.First.Fields(1).Result
Selection.Start = fNote.Reference.Start - Len(eRef)
Selection.End = fNote.Reference.Start
Selection.Font.ColorIndex = wdGreen
.Characters.First.Fields(1).Unlink
End With
.Range.Cut
End With
Set eRng = .Range
With eRng
.InsertAfter vbCr & eRef
Selection.Start = .End - Len(eRef) - 1
Selection.End = .End
Selection.Font.Superscript = True
Selection.Font.ColorIndex = wdGreen
.Start = .End
.Paste
.Style = "Endnote Text"
End With
Next
For Each fNote In .Footnotes
fNote.Delete
Next
End With
Set eRng = Nothing
'End Notes
With ActiveDocument
For Each eNote In .Endnotes
With eNote
With .Reference.Characters.First
.Collapse
.InsertCrossReference wdRefTypeEndnote, wdEndnoteNumberFormatted, eNote.Index
eRef = .Characters.First.Fields(1).Result
Selection.Start = eNote.Reference.Start - Len(eRef)
Selection.End = eNote.Reference.Start
Selection.Font.ColorIndex = wdRed
.Characters.First.Fields(1).Unlink
End With
.Range.Cut
End With
Set eRng = .Range
With eRng
.InsertAfter vbCr & eRef
Selection.Start = .End - Len(eRef) - 1
Selection.End = .End
Selection.Font.Superscript = True
Selection.Font.ColorIndex = wdRed
.Start = .End
.Paste
.Style = "Endnote Text"
End With
Next
For Each eNote In .Endnotes
eNote.Delete
Next
End With
Set eRng = Nothing
Selection.Range.Start = 1
Selection.Range.End = 1
Application.ScreenUpdating = True
End Sub


A big thank you to everyone that helped.

macropod
04-06-2010, 04:13 PM
Hi dorogoi,

Rather than explicitly changing the font colour for each footnote/endnote, you'd do better to modify the Styles. You only need to do that once per document and allows your footnotes and endnotes to acquire the desired attributes via the Style definitions. In that regard, however, I note you've applied the "Endnote Text" Style to both footnotes and endnotes - the former really should use the "Footnote Text" Style.

I also note that you're explicitly superscripting all footnotes and endnotes. That will mess up any formatting involving the use of superscripting & subscripting in the footnotes and endnotes. Again, if you're after a small font, simply format the Style to suit.

dorogoi
04-07-2010, 06:49 PM
Hi dorogoi,

Rather than explicitly changing the font colour for each footnote/endnote, you'd do better to modify the Styles. You only need to do that once per document and allows your footnotes and endnotes to acquire the desired attributes via the Style definitions. In that regard, however, I note you've applied the "Endnote Text" Style to both footnotes and endnotes - the former really should use the "Footnote Text" Style.

I also note that you're explicitly superscripting all footnotes and endnotes. That will mess up any formatting involving the use of superscripting & subscripting in the footnotes and endnotes. Again, if you're after a small font, simply format the Style to suit.

I see. I wasn't aware I could create a style that would take care of the complexity of my need (superscripted and colored reference mark with the note text in regular "Endnote Text" style.

Why do you suggest that I should apply footnote style to references that were footnotes? Is it to differentiate each type of note from each other?

With regards to the superscripting, I'm only superscripting (and coloring) the reference mark, not the text of the note. This is a direct requirement for the program. Without going into ungodly detail, the intention of the program is to prepare a given Word document for importation into another -very- inflexible desktop publishing application (with a name that sounds like it's a very fast subatomic particle). During importation of a Word document, it will convert all foot/endnote reference marks into Roman Numerals without regard for its source. Converting said notes to plain text with this macro prior to importation permits its original numbering scheme to survive unscathed.

macropod
04-07-2010, 08:36 PM
Hi dorogoi,

Why do you suggest that I should apply footnote style to references that were footnotes?Answer:
to differentiate each type of note from each otherLikewise for the reference marks, which use the 'EndNote Reference' and 'FootNote Reference' Styles, respectively. Format those Styles appropriately (they're superscripted by default) and there's no need to mess around with colouring on a per-reference basis.

Accordingly, your code could be:

Sub UnLinkNotes()
'Code by macropod @ http://www.vbaexpress.com/forum/showthread.php?t=31231
Application.ScreenUpdating = False
Dim nRng As Range, eNote As Endnote, fNote As Footnote, nRef As String
With ActiveDocument
.Styles("Footnote Reference").Font.Color = wdColorGreen
For Each fNote In .Footnotes
With fNote
With .Reference.Characters.First
.Collapse
.InsertCrossReference wdRefTypeFootnote, wdFootnoteNumberFormatted, fNote.Index
nRef = .Characters.First.Fields(1).Result
.Characters.First.Fields(1).Unlink
End With
.Range.Cut
End With
Set nRng = .Range
With nRng
.InsertAfter vbCr & nRef & " "
.Paragraphs.Last.Range.Style = "Footnote Text"
.Paragraphs.Last.Range.Words.First.Style = "Footnote Reference"
.Start = .End
.Paste
End With
Next
For Each fNote In .Footnotes
fNote.Delete
Next
.Styles("Endnote Reference").Font.Color = wdColorRed
For Each eNote In .Endnotes
With eNote
With .Reference.Characters.First
.Collapse
.InsertCrossReference wdRefTypeEndnote, wdEndnoteNumberFormatted, eNote.Index
nRef = .Characters.First.Fields(1).Result
.Characters.First.Fields(1).Unlink
End With
.Range.Cut
End With
Set nRng = .Range
With nRng
.InsertAfter vbCr & nRef & " "
.Paragraphs.Last.Range.Style = "Endnote Text"
.Paragraphs.Last.Range.Words.First.Style = "Endnote Reference"
.Start = .End
.Paste
End With
Next
For Each eNote In .Endnotes
eNote.Delete
Next
End With
Set nRng = Nothing
Application.ScreenUpdating = True
End Sub

selfpub
10-01-2017, 06:07 AM
macropod,
First off, thanks a lot for the codes you provided.

I now have a slightly different problem: a Word 2003 file with each chapter in a separate section and endnotes at the end of each section, numbered from 1 in each.
The file will be exported to PDF, and I'd like the endnotes to be clickable (just like in your subroutines, just this time the endnotes are at the end of each section).
Could you please help with some code to achieve this?
Thank you.

macropod
10-01-2017, 02:10 PM
Nothing in this thread concerns making footnote references or endnote references clickable; indeed the code does just the opposite. Hence your problem is entirely different and you should start a new thread.