OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

macro for finding all cross references and inserting -solved

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API
View previous topic :: View next topic  
Author Message
rebel
General User
General User


Joined: 05 May 2012
Posts: 10

PostPosted: Sat May 05, 2012 4:16 am    Post subject: macro for finding all cross references and inserting -solved Reply with quote

IF anybody could help me I'd sure appreciate it. I have about a 1000 page document with a very large number of cross-references set. I want to insert fields to all the cross-references at the end of the document to use as an index. It will take a VERY long time to go through and insert each cross-reference one at a time which is the only way I've found to do it. Would anyone have a macro that would iterate through each cross-reference which has been set in the document and insert a reference to it in the document?

Last edited by rebel on Wed May 09, 2012 11:35 am; edited 1 time in total
Back to top
View user's profile Send private message
patel
Power User
Power User


Joined: 14 Apr 2012
Posts: 54
Location: Italy

PostPosted: Sat May 05, 2012 6:39 am    Post subject: Reply with quote

can you attach a sample ?
_________________
If your problem has been solved please add "[Solved]" to the beginning of your first post title (edit button).
Back to top
View user's profile Send private message
rebel
General User
General User


Joined: 05 May 2012
Posts: 10

PostPosted: Sat May 05, 2012 12:34 pm    Post subject: Reply with quote

I would but maybe I'm overlooking something. How do I attach a file to a message. I don't see any options for doing it.
Back to top
View user's profile Send private message
JohnV
Administrator
Administrator


Joined: 07 Mar 2003
Posts: 9183
Location: Lexinton, Kentucky, USA

PostPosted: Sat May 05, 2012 12:57 pm    Post subject: Reply with quote

Please make a copy of your document to try this. A the very end of your document, in a new paragraph type "The end" (without parentheses) and press Enter.

Here's what I did. I inserted 2 bookmark of selected words then inserted 2 cross-references to those bookmarks to show the referenced words.

The macro below puts working copies of the cross-references, in the order they appear in the document, at its end. The macro looks for text portions that are text fields and copies those to the end so if you have other text fields that are not cross-references those may get copied also. I have tried to eliminate this problem for text fields that are variables.
Code:
Sub TextPortionEnum
oDoc = ThisComponent
oVC = oDoc.CurrentController.getViewCursor
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
Enum = oDoc.Text.createEnumeration 'Paragraph enumeration
While enum.hasMoreElements
 ThisP = enum.nextElement
 enum1 = ThisP.createEnumeration 'Text portion enumeration
 While enum1.hasMoreElements
 portion = enum1.nextElement
  If portion.string = "The end" then End
  If portion.TextPortionType = "TextField" then
   If portion.TextField.TextFieldMaster.InstanceName = "" then 'Variables have an instance name while cross-references don't.
   oVC.gotoRange(portion,false)
   dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
   oVC.gotoEnd(false)
   dispatcher.executeDispatch(document, ".uno:InsertPara", "", 0, Array())
   dispatcher.executeDispatch(document, ".uno:Paste", "", 0, Array())
   EndIf
 EndIf
 Wend
Wend
End Sub
Back to top
View user's profile Send private message
rebel
General User
General User


Joined: 05 May 2012
Posts: 10

PostPosted: Sat May 05, 2012 2:55 pm    Post subject: Reply with quote

Since I didn't see any other way of doing it I put a small sample at
[url]https://docs.google.com/open?id=0Bzwj_TNIBFRISnJ6WDIxYUZ3MzQ
[/url]

One thing I wasn't thinking about in the first message is that the fields should be sorted. When you go to Insert Cross-references, in the selection window they are all sorted already but you can only select one at a time. Maybe what I want isn't possible but it would make things a whole lot easier. I tried the code given earlier but got an error message that it could not create enumeration.
Back to top
View user's profile Send private message
patel
Power User
Power User


Joined: 14 Apr 2012
Posts: 54
Location: Italy

PostPosted: Sun May 06, 2012 2:12 am    Post subject: Reply with quote

try with this modification

Code:
Sub ref
oDoc = ThisComponent
oVC = oDoc.CurrentController.getViewCursor
document   = ThisComponent.CurrentController.Frame
oText = oDoc.Text
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
Enum = oText.createEnumeration 'Paragraph enumeration
While enum.hasMoreElements
 flag=0
 ThisP = enum.nextElement
 enum1 = ThisP.createEnumeration 'Text portion enumeration
 While enum1.hasMoreElements
 portion = enum1.nextElement
  If portion.string = "The end" then exit sub
 if  portion.TextPortionType = "ReferenceMark" then flag=flag+1
 if flag mod 2 = 1  and len(portion.string) > 0 then
'   print portion.string
   oVC.gotoRange(portion, false)
   dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
   oVC.gotoEnd(false)
   dispatcher.executeDispatch(document, ".uno:Paste", "", 0, Array())
   oText.insertString(oText.getEnd(), CHR$(13), False)
 end if
 Wend
Wend
End Sub

_________________
If your problem has been solved please add "[Solved]" to the beginning of your first post title (edit button).
Back to top
View user's profile Send private message
rebel
General User
General User


Joined: 05 May 2012
Posts: 10

PostPosted: Sun May 06, 2012 4:07 am    Post subject: Reply with quote

It's closer. Instead of simply copying the set reference text I want to insert the field to the reference. The sample.odt linked to in the prior message shows an example of the finished product. This would be the the same as going to Insert | Reference | Cross-references | Insert Reference and Inserting reference to Reference and selecting them one-by-one from the Selection window in the order they're given there. The end result will be creating a sorted index and exporting the file to a pdf so when the field in the index is clicked it will go right to that reference.
Back to top
View user's profile Send private message
patel
Power User
Power User


Joined: 14 Apr 2012
Posts: 54
Location: Italy

PostPosted: Sun May 06, 2012 6:28 am    Post subject: Reply with quote

Can you do it manually ? I don't, maybe it's possible register a macro.
_________________
If your problem has been solved please add "[Solved]" to the beginning of your first post title (edit button).
Back to top
View user's profile Send private message
JohnV
Administrator
Administrator


Joined: 07 Mar 2003
Posts: 9183
Location: Lexinton, Kentucky, USA

PostPosted: Sun May 06, 2012 8:48 am    Post subject: Reply with quote

Alright, instead of using Bookmarks you selected text and did Insert > Cross-reference > Set Reference. Now, at the end of the document, you want to create cross-references to these set references in alphabetic order. Here's the code.
Code:
Sub CrossRefSortedRefMarks
oDoc = ThisComponent
rm = oDoc.getReferenceMarks
Dim myList(rm.getCount-1)
For x = 0 to ubound(mylist)
 mylist(x) = rm.getByIndex(x).Name
Next
ImprovedBubbleSort(myList())
oVC = oDoc.CurrentController.getViewCursor
oVC.gotoEnd(false)
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dim args1(5) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Type" : args1(0).Value = 13
args1(1).Name = "SubType" : args1(1).Value = 0
args1(2).Name = "Name"
args1(3).Name = "Content" : args1(3).Value = ""
args1(4).Name = "Format" : args1(4).Value = 2
args1(5).Name = "Separator" : args1(5).Value = " "
For x = 0 to uBound(myList)
 args1(2).Value = myList(x)
 dispatcher.executeDispatch(document, ".uno:InsertPara", "", 0, Array())
 dispatcher.executeDispatch(document, ".uno:InsertField", "", 0, args1())
Next
End Sub

Sub ImprovedBubbleSort(myList()) 'By B Marcelly - http://www.oooforum.org/forum/viewtopic.phtml?t=20783
Dim k1 As Long, k2 As Long
Dim x1 As Long, x2 As Long
Dim swapping
k1 = LBound(myList())
k2 = UBound(myList())
for x2 = k2 -1 to k1 step -1
  for x1 = k1 to x2
    if StrComp(myList(x1), myList(x1 +1), 0) = 1  then
      swapping = myList(x1)
      myList(x1) = myList(x1 +1)
      myList(x1 +1) = swapping
      x1 = k1
    end if
  next
next
End Sub
Back to top
View user's profile Send private message
patel
Power User
Power User


Joined: 14 Apr 2012
Posts: 54
Location: Italy

PostPosted: Sun May 06, 2012 10:37 am    Post subject: Reply with quote

very good JohnV !!
_________________
If your problem has been solved please add "[Solved]" to the beginning of your first post title (edit button).
Back to top
View user's profile Send private message
rebel
General User
General User


Joined: 05 May 2012
Posts: 10

PostPosted: Sun May 06, 2012 11:25 am    Post subject: Reply with quote

I "think" it is working. It works great on the sample and on a greatly slimmed down copy of the original. But it is taking a very long time to complete on the full 1000+ page document. But I don't really care if it takes a day to just let the computer run as it goes through getting and sorting them as it would still save me weeks or months of manually inserting the fields. I don't know how many there are but it's a lot. I'll let you know how it went whenever it finishes.
Back to top
View user's profile Send private message
rebel
General User
General User


Joined: 05 May 2012
Posts: 10

PostPosted: Mon May 07, 2012 5:09 am    Post subject: Reply with quote

The sort routine given is definitely no good for this scenario. This one taken from the same message as the bubble routine at http://www.oooforum.org/forum/viewtopic.phtml?t=20783 should be used instead:

Sub ShellSort(myList())
Dim k1 As Long, k2 As Long, listSize As Long
Dim x1 As Long, isSorted As Boolean
Dim swapping
listSize = UBound(myList()) +1 -LBound(myList())
k1 = Fix(listSize /2)
do while k1 > 0
k2 = UBound(myList()) - k1
isSorted = true
for x1 = LBound(myList()) to k2
if StrComp(myList(x1), myList(x1 +k1), 0) = 1 then
swapping = myList(x1)
myList(x1) = myList(x1 +k1)
myList(x1 +k1) = swapping
isSorted = false
end if
next
if isSorted then
k1 = Fix(k1 /2)
end if
loop
End Sub

The improvedbubblesort routine was sorting for almost 14 hours and when I checked the value of x2 it still hadn't gotten past the first iteration! At that point I just stopped the macro. Using the shellsort routine, the list array was populated and sorted in less than 45 seconds. Now the slowdown is at the end where it is inserting the fields into the document. I put in a MSGBOX command in the For...Next loop to let me know when every 1000 fields are inserted and each 1000 takes longer and longer to get done. The document has 11220 reference fields. Eventually it should get done though, now that I'm using a new sort routine.
Back to top
View user's profile Send private message
patel
Power User
Power User


Joined: 14 Apr 2012
Posts: 54
Location: Italy

PostPosted: Mon May 07, 2012 9:18 am    Post subject: Reply with quote

You are right, the shellsort is very faster than other
_________________
If your problem has been solved please add "[Solved]" to the beginning of your first post title (edit button).
Back to top
View user's profile Send private message
rebel
General User
General User


Joined: 05 May 2012
Posts: 10

PostPosted: Wed May 09, 2012 11:34 am    Post subject: Reply with quote

It finally finished! I think it took somewhere around 45 hours. The first 1000 reference fields took about 20 minutes to insert into the document, and the last 1000 took about 7 hours. But that looks to be probably about what it would have taken to insert 11220 references manually. After it finished I tried it manually and it took 28 seconds to insert one field whereas it took about 5 seconds for each one at the beginning. And that's on a quad-core, 3Ghz computer.

What would the change be in the code to insert a cross-reference to the page # instead of to the cross-reference name?

Thank you so much for your help! It was greatly appreciated.
Back to top
View user's profile Send private message
JohnV
Administrator
Administrator


Joined: 07 Mar 2003
Posts: 9183
Location: Lexinton, Kentucky, USA

PostPosted: Wed May 09, 2012 1:35 pm    Post subject: Reply with quote

Quote:
What would the change be in the code to insert a cross-reference to the page # instead of to the cross-reference name?
I don't find an available Page # property although it may be hidden somewhere.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group