I want to write a macro to select a specific text with a specific style.
Now my problem is in search description I can set SearchStyles to True, then a style is searched. Or i can set it to False, then a text is searched, so search for style AND text is not possible
My Idea was to search for text and then sort out all but the correct style:
oDoc = ThisComponent
' Prepare the Search-Descriptor
oSearchDesc = oDoc.createsearchDescriptor()
oSearchDesc.SearchRegularExpression = True
oSearchDesc.SearchWords = True
oSearchDesc.SearchCaseSensitive = True
oSearchDesc.SearchString = "[ABCDEFGH][♯♭b#]"
oFoundall = oDoc.FindAll(oSearchDesc)
' drop wrong style
i = 0
Do While i < oFoundall.Count
oFound = oFoundall(i)
If oFound.CharStyleName = "Placeholder" then
i=i+1
Else
oFoundall.Remove(i)
End If
Loop
' highlight match
oDoc.getCurrentController().Select(oFoundall)
But oFoundall.Remove(i) throws an error,it seems that oFoundall is no collection. What is the right instruction remove one item from oFoundall?
Thanks and Regards
Last edited by bassklampfe on Sat Jul 20, 2019 9:01 am, edited 2 times in total.
Do it like you would do in the user interface. Search for one thing and then for the other thing within the first result.
menu:find>replace...
Search for whatever and hit [Find All]. Now you have a selection of all matching snippets. Now search within the current selection for something else.
Keep variable oFoundall, prepare another searchdescriptor and then call oFoundall.FindAll(new_descr)
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Well, I didn't mention, but the Style im searching, is a Character Style, not a Paragraph Style. Sorry.
If didn't make FindAll to find a Character Style at all, maybe then I would find another solution based on this....
Each found snippet can include sections with more than one character style. You have to loop through the search results and through the uniquely formatted snippets of each result. I am not familiar with the Writer API but it may be possible to use something like
e = oFound.createEnumeration()
while e.hasMoreElements()
snip = e.nextElement()
if snip.CharacterStyleName = someCharStyle then ...
wend
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Last edited by Zizi64 on Sun Jul 14, 2019 9:35 pm, edited 2 times in total.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
dim ofoundnew()
for i = 0 to oFoundall.Count -1
If oFoundall(i).CharStyleName = "Placeholder" then
redim preserve ofoundnew(c)
ofoundnew(c) = oFoundall(i)
c=c+1
End If
next
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
' drop wrong style
i = 0
Print oFoundall.Count
Do While i < oFoundall.Count
oFound = oFoundall.getByIndex(i)
If oFound.CharStyleName = "Placeholder" then
Print "The character ' " & oFound.getString & "' has character style ' Placeholder' . It will not be removed"
Else
The Print "The character ' " & oFound.getString & "' will be removed"
oFound.setString("")
End If
i=i+1
Loop
Has one big issue: oFound.setString("") destroys the document content. I want to modify the found content lateron, but keep all other text.
Because ofoundnew is a StarBasic type of array. It may be possible to create a new instance of an UNO object (c.s.s.text.TextRanges?) and append snippets to it.
The Calc component can produce an UNO collection of multiple ranges from scratch:
oBasket = createUnoService("com.sun.star.sheet.SheetCellRanges")
for each range in someRanges()
oBasket.addRangeAddress(range.getRangeAddress())
next
oController.select(oBasket)
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
for i = 0 to oFoundall.Count -1
If oFoundall(i).CharStyleName = "Placeholder" then
oFoundall(i).charoverline = 2
end if
next
Dim sAttributes(0) As New com.sun.star.beans.PropertyValue
SAttributes(0).Name = "CharOverline"
SAttributes(0).Value =2
oSearchDesc.SetSearchAttributes(SAttributes())
oSearchDesc.SearchString =""
oFoundall = oDoc.FindAll(oSearchDesc)
oDoc.getCurrentController().Select(oFoundall)
for i = 0 to oFoundall.Count -1
oFoundall(i).charoverline = 0
next
(its clunky but...)
Last edited by JeJe on Sun Jul 14, 2019 4:25 pm, edited 1 time in total.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
For the first: I'd never execute Macros from downloaded files.
So, I renamed it to .ZIP, extracted and examined the content.
Set the macro security to medium, and just open the file without enabling the macros. Then you can check the macro code with the built-in IDE.
Has one big issue: oFound.setString("") destroys the document content. I want to modify the found content lateron, but keep all other text.
A part of your code:
oFoundall.Remove(i)
Do you want to remove the searched characters, those have not the character style "Placeholder", does not?
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
Print "The character ' " & oFound.getString & "' will be removed"
And install and use an object inspesction tool like the Xray.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
oFound.setString("") destroys the document content.
The oFound.setString("") will remove one character only. Tested in my LibreOffice 6.1.6
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
Do you want to remove the searched characters, those have not the character style "Placeholder", does not?
This shall not remove the found text from the document, but the found item from the list of found items. But it seems, the list of found Items cannot be manipulated or reconstructed.
Just to give you an idea, the whole workflow of the script shall be as follows:
build a list (with FindAll or on an other way) of items matching specific criteria
Highlight all matching items using select()
Show a dialog to ask the user, what to do with the selected items
Depending on the choice in the dialog do different things with the selected items
I'm busy this week, I will come back when I make progress
I'm back again
I developed some strategies, but im still struggling with the methods available. oFoundall is of type com.sun.star.text.TextRanges. But I don't manage to create an empty, new TextRanges object.
My attempt was
To slightly extend my solution, you'd make note of the existing attribute/attributes (overlining if that is chosen) for each item and reaply them at the end. You just need a unique attribute or combination of attributes that you won't find in your document.
An alternative would be instead of selecting the ranges, to just mark them in some other obvious way - such as underlining (as the spellchecker does), overlining, or background color.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Just to inform you, I now do an attribute search (CharColor is the unique Style of the CharacterStyle in question) and get exactly what I need.
This is the starting of my code:
Sub SelectPlaceholder
'
' set global vars
'
Dim oDoc As Object
oDoc = ThisComponent
'
' find the character style Placeholder
'
Dim oStyleFamilies,oCharStyles,oCharStylePlaceholder as object
oStyleFamilies = oDoc.getStyleFamilies()
oCharStyles = oStyleFamilies.getByName("CharacterStyles")
oCharStylePlaceholder=oCharStyles.getByName("Placeholder")
'
' build the seach
'
Dim oSearchDesc As Object
Dim srchAttributes(0) As New com.sun.star.beans.PropertyValue
oSearchDesc = oDoc.createsearchDescriptor()
srchAttributes(0).Name = "CharColor"
srchAttributes(0).Value = oCharStylePlaceholder.CharColor
oSearchDesc.SearchStyles = True
oSearchDesc.SetSearchAttributes(srchAttributes)
'
' do the search
'
Dim oFoundall As Object
oFoundall = oDoc.FindAll(oSearchDesc)
'
' highlight match
'
oDoc.getCurrentController().Select(oFoundall)
'
' do further processing
'
....
end sub
The only issue left is, the FIRST element found is NOT highlighted by oDoc.getCurrentController().Select(oFoundall) this seems to be a bug in OO?
Any solution/workaround for this?
bassklampfe wrote:
The only issue left is, the FIRST element found is NOT highlighted by oDoc.getCurrentController().Select(oFoundall) this seems to be a bug in OO?
Any solution/workaround for this?
Seems to be a bug in all versions of OO and LO I could test.
As the cursor always collapses to the end of the first item (if the Foundall has more than 1 item) we could move the Viewcursor to the left by the length of the first item: