sub crossreference (file, namesection,reference)
dim oDescriptor,ofound
oDescriptor = file.createSearchDescriptor()
With oDescriptor
.SearchString = reference
End With
oFound = file.findFirst(oDescriptor)
if isnull(ofound) then exit sub
dim oField
oField = file.createInstance("com.sun.star.text.textfield.GetReference")
oField.ReferenceFieldPart = com.sun.star.text.ReferenceFieldPart.NUMBER
oField.ReferenceFieldSource = 2
oField.SourceName = "__RefNumPara__5813_2658656130"
dim textcursor as object, oanchor, section as object
textcursor = file.getText().createTextCursor()
section = file.getTextSections.GetByName(namesection)
oanchor = section.getAnchor()
textcursor.gotoRange(oanchor, False)
textcursor.collapseToEnd()
file.getText().insertTextContent(textcursor, oField, false)
end sub
but the problem is that i dont know how to make the search descriptor to return something like "__RefNumPara__5813_2658656130" the reference for the paragraph, probably an enumeration of some sort. Anyone knows how this works?
tf =thiscomponent.textfields.createenumeration
do until tf.hasmoreelements = false
f =tf.nextelement
msgbox f.getpropertyvalue ("SourceName")
loop
Sorry, that's not relevant... I think I get what you want and that's to find the reference to the paragraph which is created when you manually create a field by picking from the list of items that appears in the "Selection" listbox of the insert field dialog.
Enumerating the paragraphs and using MRI for each... the only thing that looks remotely similar is something called the StringValue which ends in something like "/content.xml#id1696954595" but that's not the same number.
Edit2:
Creating a simple file with a field and looking at context.xml it looks like paragraphs have an id number but the number you want is different - and is only there when you have created the field - but you'll have to look at that yourself to make sure.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
problem is that something like "__RefNumPara__5813_2658656130" is only created when you insert a crossreference field via menu.
it is a kind of bookmark.
Say you have
1. first line
2. second line
3. third line
Now manually insert a cross reference for the first.
With the following macro you can find the RefNumPara by the name of the Paragraph.
It will give back a RefNumPara for "first line" but not for "second line" or "third line".
sub search_for_refs
sSearch="first line"
msgbox get_Ref_from_name2(sSearch)
end sub
rem------------this gets the ReferenceMark (if it exists)
function get_Ref_from_name2(sSearch)
oDoc=ThisComponent
oParEnum = oDoc.Text.createEnumeration()
Do While oParEnum.hasMoreElements()
oPar = oParEnum.nextElement()
If oPar.supportsService("com.sun.star.text.Paragraph") Then
oEnum = oPar.createEnumeration()
Do While oEnum.hasMoreElements()
oSect = oEnum.nextElement()
if oSect.string = sSearch then
Do While oEnum.hasMoreElements()
oSect = oEnum.nextElement()
If NOT IsNULL(oSect.bookmark) Then
get_Ref_from_name2 = oSect.bookmark.LinkDisplayName
exit function
End If
loop
end if
loop
end if
loop
get_Ref_from_name2 = ""
end function
So perhaps there is a way to create custom bookmarks for your numbered paras.
Or you could just use heading paragraphs and hyperlinks.
As each paragraph has a stringvalue identifier you could use that... You'd need a field/hyperlink/other method of calling a macro which finds the paragraph with that stringvalue by enumerating the text. The stringvalue to be found could be stored in some hidden text next to the field.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
sub crossreference (file, namesection,reference)
dim oDescriptor,ofound
oDescriptor = file.createSearchDescriptor()
With oDescriptor
.SearchString = reference
End With
oFound = file.findFirst(oDescriptor)
if isnull(ofound) then exit sub
dim textcursor as object
textcursor = file.getText().createTextCursor()
textcursor.gotorange(ofound,false)
textcursor.gotostartofparagraph(false)
textcursor.gotoendofparagraph(true)
dim oRefField as object, oname as string, i as integer
i = 1
oRefField = file.createInstance("com.sun.star.text.ReferenceMark")
oname = "reference " & i
do while file.referencemarks.hasbyname(oname)
i = i +1
oname = "reference " & i
loop
oRefField.setname(oname)
file.Text.insertTextContent(textcursor, oRefField, False)
dim oField
oField = file.createInstance("com.sun.star.text.textfield.GetReference")
oField.ReferenceFieldPart = com.sun.star.text.ReferenceFieldPart.CHAPTER
oField.ReferenceFieldSource = 0
oField.SourceName = oname
dim oanchor, section as object
section = file.getTextSections.GetByName(namesection)
oanchor = section.getAnchor()
textcursor.gotoRange(oanchor, False)
textcursor.collapseToEnd()
file.getText().insertTextContent(textcursor, oField, false)
end sub
Is not what i wanted, but is the closest i could manage to do.
REM ***** BASIC *****
'code goes in a document's Standard library/Module1
'set the text of one of the paragraphs to "The fishermen"
'move the cursor to somewhere else
'run main
'a field will be created at the viewcursor with the same text as the paragraph
'clicking on it will fire the GoToRefPara macro which will go to the required paragraph.
sub Main '
parastring= "The fishermen"
InsertMacroFieldForPara(parastring)
end sub
sub InsertMacroFieldForPara(parastring) 'add a field
en =thiscomponent.gettext.createenumeration
do until en.hasmoreelements = false
p =en.nextelement
if p.string=parastring then
oField = thiscomponent.createInstance("com.sun.star.text.textfield.Macro")
with oField
.hint = p.string
no = endval(p.stringvalue)
.MacroName = "vnd.sun.star.script:Standard.Module1.GoToRefPara?language=Basic&location=document" & "&id=" & no
thiscomponent.getText().insertTextContent(thiscomponent.currentcontroller.viewcursor, oField, false)
end with
exit do
end if
loop
end sub
Sub GoToRefPara()
dim no as string
vc = thiscomponent.currentcontroller.viewcursor
no =endval(vc.textfield.macroname)
lenno = len(no)
paras = thiscomponent.gettext.createenumeration
do until paras.hasmoreelements = false
p =paras.nextelement
if right(p.stringvalue,lenno) = no then
thiscomponent.currentcontroller.select(p)
exit do
end if
loop
End Sub
Function EndVal(st As String) As Long
Dim i As Long, a As Integer, s As String, res As String
res = ""
s = ""
For i = Len(st) To 1 Step -1
s = Mid(st, i, 1)
a = Asc(s)
If a >= 48 And a <= 57 Then
res = s & res
Else
Exit For
End If
Next
EndVal = Val(res)
End Function
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)