Getting all the fields that are inserted in a document until a certain position

I have a document that contains text and also some fields.

I’d like to know how I can retrieve all the fields that are inside the document but only between the beginning of the document to the cursor position ? Then I’d like to put it inside a variable.

I already know how i can retrieve ALL the fields that are used in the document, but what I need here is ONLY the ones that are before the cursor position.

If I can directly get an array containing these fields, it’s great. Otherwise I will do what’s needed to convert the result into an array.

Thanks for your help.

Regards

Well. Now use oText.compareRegionEnds()

Sub findFieldsBeforeCursor
Dim oText As Variant, oViewCursor As Variant, oTextFields As Variant, oTextField As Variant
Dim sMsg As String 
	oText = ThisComponent.getText()
	oViewCursor = ThisComponent.getCurrentController().getViewCursor()
	oTextFields = ThisComponent.getTextFields()
	For Each oTextField In oTextFields
		If oText.compareRegionEnds(oViewCursor, oTextField.getAnchor()) < 0 Then
			sMsg = sMsg & oTextField.getAnchor().getString() & Chr(10)
		EndIf 
	Next oTextField
	MsgBox sMsg
End Sub

What you (the OriginalQuestioner) try to get Is only achievable with acceptable effort if you can assure That the range you try to describe here

actually is inside one Text object (which then would be the body text of the document). If there are nested text objects like cells of TextTable objects or the contents of TextFrame objects, there isn’t a Text object containing your complete supposed range which could apply its method .compareRegionEnds() (or similar method) to decide if a given TextField (the anchor) is inside or not.
The WYSIWYG concept may look nice and familiar, but it’s mostly an illusion or a lie.

Although @JohnSUN was faster, I add my solution :-).
The method .compareRegionEnds is for oDoc.Text, thus it isn’t usable for example for TextTables.

Sub getFieldsOnlyToCursor
	dim oDoc as object, oVCur as object, s$, oField as object, i&
	dim arr(10000) 'some initial count for array with fileds, because dynamic arrays are slow in Basic
	oDoc=ThisComponent
	oVCur=oDoc.CurrentController.ViewCursor
	for each oField in oDoc.TextFields 'enumerate the fields
		if oField.IsFieldUsed then 'check only used fields
			if oDoc.Text.compareRegionEnds(oField.Anchor.End, oVCur.Start)>-1 then 'compare position of cursor and Anchor of field, >-1 means the previous or the same position
				arr(i)=oField 'add field to array
				i=i+1
			end if
		end if
	next
	if i>0 then redim preserve arr(i-1) 'there was some field
	'xray arr
End Sub
1 Like

Thanks for your answer, it actually works great but there’s something still not ok for my needs…

Let me explain :

In the document, I have some fields that act like opening and closing tags. So the doc will look like this :

BEGIN_SECTION_1
Some text here...
BEGIN_SECTION_2 Another text END_SECTION_2
Another text here or maybe we can insert some "real" fields
END_SECTION_2

The idea is that the user will place the cursor where he wants to insert a field.
The macro is supposed to check its position : if the cursor is outside of a “section” then user won’t be able to add any field.

In the other case, the macro will search inside a database, and depending on the section, some fields will be presented to the user. Then he will have to choose one, click, and the field will be inserted.

The last part, I was able to write the code, because I already add the code to insert the sections, and sections are also fields.

My problem here is when I run your code, the array of fields that I get is not in the same order as the fields that are on the page.

In the example I gave you, if my cursor is inside section 2, then I was expecting to retrive the field “BEGIN_SECT_1” and then “BEGIN_SECTION_2”. So I would just get the last item of the array (BEGIN_SECT_2) and I would know that user is inside section 2, and I could run my query to get the available fields.

But when I run your code, the fields are not in this order…
The array contains the list of the fields that are inside the document, from the beginning until the cursor, that’s true, that was my question, but I forgot to say “in the same order as they appear on the page”.

Is it something that can be done ?

It could be done, with ThisComponent.createSearchDescriptor for searching forward/backward. But I think the main problem will be like in HTML → crossed tags:
BEGIN1 … BEGIN2 … END_BEGIN1 … END_BEGIN2.
Or missing or bad tags:
BEGIN1 … BEGIN2 … END_BEGIN2
So the searching will be demanding. And more complicated will be the sorting of tags etc.
Small mentioning:

I see… Thanks for your answer.