PDA

View Full Version : Sort Footnotes



Zack Barresse
09-10-2013, 05:31 PM
Posting solely out of curiosity, I have no actual need here, so my priority is very low. I was helping someone with some Word code to do some finding and replacing as desired. The thread is over at TSG (here (http://forums.techguy.org/business-applications/1108005-editing-whole-bible-accounting-all.html#post8769881)) if anyone's curious). The way it worked was it looked for words and replaced them, the first instance having underlined formatting applied and a footnote on that page added.

I ended up adding a loop to check all the footnotes to see how many were on that page. And that was after a couple hours of searching the internet for help. I got the numbering to work but they order how they were found on the page, not necessarily which came first. This leads me to the question: is there a way to sort footnotes, or at least re-arrange them? I tried changing their reference but it deleted it.

Thought I'd ask. I attached the Word document I was testing it with. First page footnotes work just fine, but second page shows what I'm talking about. I don't even know if this is a good way of doing it. :think:

10573

SamT
09-10-2013, 06:48 PM
I'm sorry. YOU don't have permission to make attachments. :crying:

The only way I can think of in the code on TSG (here (http://forums.techguy.org/business-applications/1108005-editing-whole-bible-accounting-all.html#post8769881)), would have been to have ReplaceAllWords get a 2d Array (main Excel list)from the excel sheet and pass it to ReplaceWords. As you replace a word place it in array(n, 3) with (n,1) = ExcelList(i), (n, 2) = ExcelList(i, 1), and (n, 3) = ExcelList(i, 2), then sort the n3 array by (n, 1)

Is it posssible to search a Doc for underlined Words and put them in an array? Loop thru that array and find the match in the main list array for the page footnotes.

Alternately, since there are hundreds of replacements to perform, it might have been feasible to loop thru the doc page and find a match for each word in the main list array. A word Doc page contains what? Three or four hundred words? The main Excel list probably has that many rows.

The Glossary Footnotes would just be the main list Array.



This leads me to the question: is there a way to sort footnotes, or at least re-arrange them?

You can always "Set MyCollection = Doc.Footnotes," but what would you sort them on? For a two word footnote like the TSG problem, you can split the collection into an array, and sort the array alphabetically.

Are Doc.Ranges indexedlike Excel Range Cells? Sort on the index.

Zack Barresse
09-10-2013, 07:13 PM
That's a good idea, putting the footnotes into an array by page. You could add the Reference property in one dimension and the page number in the next perhaps? We can then sort the array that way. Sounds reasonable enough when I say it.

On the other hand, I didn't know if this was even the most efficient way to go about it. I'm not fluent with the Word object model.

Since the OP was going to have the Bible in a document, it'll be in the thousands of pages. I was really worried about performance. Even on 2 pages of less than a dozen sentences I could visibly watch it run.

I'm not sure about document Range objects. The whole object model confuses the hell outta me. :bug:

SamT
09-11-2013, 05:04 AM
I just now thought about it in terms of a spreadsheet with ~30 columns x ~100 rows with a page of text in each Cell. XL's Replace could probably complete the task in a few seconds per WordToReplace. At ~400 WTR's =~ .5 to 3 hours, just to Replace. Assume Word is about the same with Replace, but ran on the entire Document..

Then: Go thru the WTRlist Array on each Page looking for the first occurrence, do the sort FoonoteArray, and move to the next Page.

That would reduce the per Page code to
Dim FootnoteArray(100, 3) 'Large fixed size, faster than Redim Preserve
For i = 0 to Ubound(WTRList)
Find WTRList(i)
If Found is Nothing Then Next i
Found.Underline
Add To FootnoteArray
Next i
Handle Footnote Array
Next Page

Zack Barresse
09-11-2013, 06:49 AM
Oh, and sample file attached this time. I didn't realize I messed it up lol.

I'll play around with it. I like your idea. Thanks Sam!

SamT
09-11-2013, 04:11 PM
Why can't I see your attachments? I see others' just fine?!?

Zack Barresse
09-11-2013, 04:26 PM
I edited my first post. Do you see it in there?

SamT
09-11-2013, 04:52 PM
Nope. Do You see it?

Paul_Hossler
09-11-2013, 05:00 PM
@ZB--



The whole object model confuses the hell outta me. :bug:


It's designed that way so that only Greg and Gerry can understand it. :devil2:

BTW, I see the attachment in #1 also

Paul

Zack Barresse
09-11-2013, 05:06 PM
Yup. I just edited it to be 'inline'. I think that's part of the new forum software, since attachments are now integrated better. Can you see it now?

Zack Barresse
09-11-2013, 05:16 PM
It's designed that way so that only Greg and Gerry can understand it. :devil2:
No kidding!

BTW, I see the attachment in #1 also
Hmm, I'm not sure if that's more disturbing since Sam can't see it.

SamT
09-11-2013, 05:38 PM
Oh, In Post number 1 :doh:

Yeah, it's there

fumei
09-11-2013, 06:24 PM
Hey there are plenty of others who grasp the object model; Paul (macropod) and Jason (Frosty) for two...

and actually, I do not think I would qualify anymore. Greg and Jason are up on 2010, and I am not.

Zack Barresse
09-11-2013, 07:50 PM
I'll always throw Tony in there too. :)

fumei
09-11-2013, 08:28 PM
For sure. Darn I forgot about him. Have not heard anything from that direction in a while.

Paul_Hossler
09-12-2013, 05:20 AM
Of course there's a lot of very knowledgeable and helpful members of the forums (didn't mean to slight anyone)

It was just that Greg&Gerry alliterates nicely

Paul

SamT
09-12-2013, 06:15 AM
Hey, what you using big words like aliteraturatates around here for?

gmaxey
09-12-2013, 01:27 PM
Surely the Greg mentioned in this thread isn't me. I often find myself over my head in a parking lot puddle. The word object model certainly bewilders me!

Zach, I don't think you can "sort" footnotes per se. I think the trick is to create them in the order they need to be in.

It isn't pretty, but the following code does appear to work with your sample text. How it would do with the entire bible, well that is yet to be seen.

All that remains is to format the footnote reference as hidden text.


Option Explicit
Dim m_oCol1 As Collection
Dim m_oCol2 As Collection
Sub ReplaceAllWords()
Set m_oCol1 = New Collection
Call ReplaceWords("God", "Elohim")
Call ReplaceWords("heaven", "shamayim")
Call ReplaceWords("earth", "aretz")
Call ReplaceWords("waters", "mayim")
Call ReplaceWords("good", "tov")
UnlineAndFN
Call FixFootnotes("elohim", "Elohim:God")
Call FixFootnotes("shamayim", "shamayim:heaven")
Call FixFootnotes("aretz", "aretz:earth")
Call FixFootnotes("mayim", "mayim:waters")
Call FixFootnotes("tov", "tov:good")
End Sub

Sub ReplaceWords(ByVal LookFor As String, ByVal ReplaceWith As String)
Dim oRng As Word.Range
m_oCol1.Add UCase(ReplaceWith), UCase(ReplaceWith)
Set oRng = ActiveDocument.Range
With oRng.Find
.Text = LookFor
.Replacement.Text = ReplaceWith
.MatchWholeWord = True
.MatchCase = False
.Execute Replace:=wdReplaceAll
End With
End Sub
Sub FixFootnotes(ByVal LookFor As String, ByVal ReplaceWith As String)
Dim oRng As Word.Range
m_oCol1.Add UCase(ReplaceWith), UCase(ReplaceWith)
Set oRng = ActiveDocument.StoryRanges(wdFootnotesStory)
With oRng.Find
.Text = LookFor
.Replacement.Text = ReplaceWith
.MatchWholeWord = True
.MatchCase = True
.Execute Replace:=wdReplaceAll
End With
End Sub

Sub UnlineAndFN()
Dim wdDoc As Document
Dim wdRng As Word.Range
Dim lngIndex As Long
Dim oWord As Word.Range
Dim strWord As String
Dim lngCounter As Long

Set wdDoc = ActiveDocument
Set wdRng = ActiveDocument.Range
With wdDoc
For lngIndex = 1 To .ComputeStatistics(wdStatisticPages)
Set m_oCol2 = New Collection
Set wdRng = wdRng.GoTo(What:=wdGoToPage, Name:=lngIndex)
Set wdRng = wdRng.GoTo(What:=wdGoToBookmark, Name:="\page")
lngCounter = 1
With wdRng
For Each oWord In wdRng.Words
strWord = UCase(Trim(oWord.Text))
oWord.Collapse wdCollapseStart
oWord.MoveEnd wdCharacter, Len(strWord)
If oWord.Characters.Last = Chr(160) Then oWord.MoveEnd wdCharacter, -1
On Error Resume Next
m_oCol1.Add strWord, strWord
If Err.Number <> 0 Then
On Error GoTo 0
On Error Resume Next
m_oCol2.Add strWord, strWord
If Err.Number = 0 Then
oWord.Font.Underline = 1
On Error GoTo 0
ActiveDocument.Footnotes.Add oWord, CStr(lngCounter), LCase(strWord)
lngCounter = lngCounter + 1
End If
Else
m_oCol1.Remove m_oCol1.Count
End If
Next oWord
End With
Next lngIndex
End With
Set wdRng = Nothing: Set wdDoc = Nothing:
End Sub

Zack Barresse
09-12-2013, 06:58 PM
Holy crap! I will definitely test that out! I'll not claim to understand your code whatsoever, but it certainly looks like a damn work of art. You da man. :)

gmaxey
09-13-2013, 06:00 AM
Zach,

"Word of art!" Ha. Cobble job is more accurate. I put it together based roughly on your original code and I'm sure it is probably full of holes.

Basically the process is this:

1. Find and replace all of the word pairs. Use range rather than selection and replace all in one go. Added the replace with word as both value and key in a collection.
2. Then process each page one after the other.
3. Process each Word on each page one after the other. The tricky part is isolating what you and I think of as a word compared to what Word thinks is a word. I've used a rather crude process to trim the white space from the words. Would have to test and give this more thought in a real production run.
4. Attempt to add that word as the value and key to the original colloection. If it errors then it was one of the replace words. If it doesn't then is is an irrevelent word so we remove it form the collection. This way it won't error the next time encountered.
5. Now we attempt to add the revelent word to a second collection as both value and key. If doesn't error that means this is the first time processed so we underline it and add the footnote. If it does error then we skip it.

The potential problems with this approach is when you have full pages of text and the addition of footnotes will rearrange the subsequent pages and text. I'm not sure how the code will stand up and perform in this situation.