LibreOffice Writer Macro to run on Selected Text Only

I am using Ubuntu 14.04 and LibreOffice 6.4. I have created a macro with several Find and Replace commands. But that applies to entire document. I want a macro by running which the macro will affect only on the selected text. Means I will select certain text then will run macro. I wish after running the macro, the find and replace commands in the macro should work on selected text only.

1 Like

Hallo
It might be easier to help you if you show the actual macro code!

Formatted code (short example):

REM ***** BASIC *****
sub KrutiDevToUnicode
rem ----------------------------------------------------------------------
rem define variables
dim document as object

dim dispatcher as object

rem ----------------------------------------------------------------------

rem get access to the document

document = ThisComponent.CurrentController.Frame

dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------

dim args1043(21) as new com.sun.star.beans.PropertyValue

args1043(0).Name = "SearchItem.StyleFamily"

args1043(0).Value = 2

args1043(1).Name = "SearchItem.CellType"

args1043(1).Value = 0

args1043(2).Name = "SearchItem.RowDirection"

args1043(2).Value = true

args1043(3).Name = "SearchItem.AllTables"

args1043(3).Value = false

args1043(4).Name = "SearchItem.SearchFiltered"

args1043(4).Value = false

args1043(5).Name = "SearchItem.Backward"

args1043(5).Value = false

args1043(6).Name = "SearchItem.Pattern"

args1043(6).Value = false

args1043(7).Name = "SearchItem.Content"

args1043(7).Value = false

args1043(8).Name = "SearchItem.AsianOptions"

args1043(8).Value = false

args1043(9).Name = "SearchItem.AlgorithmType"

args1043(9).Value = 0

args1043(10).Name = "SearchItem.SearchFlags"

args1043(10).Value = 65536

args1043(11).Name = "SearchItem.SearchString"

args1043(11).Value = "yka"

args1043(12).Name = "SearchItem.ReplaceString"

args1043(12).Value = "लां"

args1043(13).Name = "SearchItem.Locale"

args1043(13).Value = 255

args1043(14).Name = "SearchItem.ChangedChars"

args1043(14).Value = 2

args1043(15).Name = "SearchItem.DeletedChars"

args1043(15).Value = 2

args1043(16).Name = "SearchItem.InsertedChars"

args1043(16).Value = 2

args1043(17).Name = "SearchItem.TransliterateFlags"

args1043(17).Value = 1073744896

args1043(18).Name = "SearchItem.Command"

args1043(18).Value = 3

args1043(19).Name = "SearchItem.SearchFormatted"

args1043(19).Value = false

args1043(20).Name = "SearchItem.AlgorithmType2"

args1043(20).Value = 1

args1043(21).Name = "Quiet"

args1043(21).Value = true

dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args1043())

rem ----------------------------------------------------------------------

dim args1027(21) as new com.sun.star.beans.PropertyValue

args1027(0).Name = "SearchItem.StyleFamily"

args1027(0).Value = 2

args1027(1).Name = "SearchItem.CellType"

args1027(1).Value = 0

args1027(2).Name = "SearchItem.RowDirection"

args1027(2).Value = true

args1027(3).Name = "SearchItem.AllTables"

args1027(3).Value = false

args1027(4).Name = "SearchItem.SearchFiltered"

args1027(4).Value = false

args1027(5).Name = "SearchItem.Backward"

args1027(5).Value = false

args1027(6).Name = "SearchItem.Pattern"

args1027(6).Value = false

args1027(7).Name = "SearchItem.Content"

args1027(7).Value = false

args1027(8).Name = "SearchItem.AsianOptions"

args1027(8).Value = false

args1027(9).Name = "SearchItem.AlgorithmType"

args1027(9).Value = 0

args1027(10).Name = "SearchItem.SearchFlags"

args1027(10).Value = 65536

args1027(11).Name = "SearchItem.SearchString"

args1027(11).Value = "”k"

args1027(12).Name = "SearchItem.ReplaceString"

args1027(12).Value = "ष"

args1027(13).Name = "SearchItem.Locale"

args1027(13).Value = 255

args1027(14).Name = "SearchItem.ChangedChars"

args1027(14).Value = 2

args1027(15).Name = "SearchItem.DeletedChars"

args1027(15).Value = 2

args1027(16).Name = "SearchItem.InsertedChars"

args1027(16).Value = 2

args1027(17).Name = "SearchItem.TransliterateFlags"

args1027(17).Value = 1073744896

args1027(18).Name = "SearchItem.Command"

args1027(18).Value = 3

args1027(19).Name = "SearchItem.SearchFormatted"

args1027(19).Value = false

args1027(20).Name = "SearchItem.AlgorithmType2"

args1027(20).Value = 1

args1027(21).Name = "Quiet"

args1027(21).Value = true

dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args1027())

end sub

In other words, do you want to replace all yka with लां and all k with ष only in the preselected fragment? Do you always select only one solid fragment, or can you select several fragments by holding Ctrl?

Yes, I want to replace all occurences of a letter. I want to usr one solid fragment at a time.

Okay, try this subroutine:

Sub ReplaceInSelection
Dim OriginalStrings As Variant, TargetStrings As Variant
Dim oFind As Variant, oFound As Variant
Dim oSelections As Variant, oCompare As Variant 
Dim i As Long, j As Long, k As Long
	OriginalStrings = Array("yka", "k")
	TargetStrings = Array("लां", "ष")

	oFind = ThisComponent.createReplaceDescriptor()
	oFind.SearchCaseSensitive = True
	oSelections =ThisComponent.getCurrentSelection
	oCompare = ThisComponent.getText()
	For i = LBound(OriginalStrings) To UBound(OriginalStrings)
		oFind.setSearchString(OriginalStrings(i))
		oFound = ThisComponent.findAll(oFind)
		If Not IsNull(oFound) Then
			For j =0 To oFound.getCount()-1
				For k = 0 To oSelections.getCount()-1
					If Len(oSelections.getByIndex(k).getString()) >= Len(OriginalStrings(i)) Then
						If oCompare.compareRegionStarts(oFound(j), oSelections.getByIndex(k)) <= 0 And _
								oCompare.compareRegionEnds(oFound(j), oSelections.getByIndex(k)) >=0 Then
							oFound(j).setString(TargetStrings(i))
						EndIf 
					EndIf 
				Next k
			Next j
		EndIf 
	Next i
End Sub
1 Like

There are hundreds of find and replace commands in the macro. I just posted two because the original was too large.

@AniruddhaMohod Well, I started from your code - in the description of the problem, the number of replacements was not mentioned.

If we are talking about a dozen replacements, then you can use the above code - just add the strings you want to find to the OriginalStrings array, and add the corresponding replacement strings to the TargetStrings array.

If we are really talking about hundreds of replaced strings, then most likely you need a completely different approach to solving the problem. It is a pity that you did not tell about your problem enough for understanding from the very beginning.

@AniruddhaMohod Do you need keep up the formatting or not?
And is it possible to use one regular expression for your searching like (aa|bb|c)?


If the answers are No&Yes, the fastest way should be with string replacements in Python like in @karolus example, but I think the more practical for hundreds replacements is to have the items in one array p=[ ["bc", "+1"], ["op", "#"] ]


Here is Basic macro with the method “com.sun.star.util.TextSearch”, mostly it is very fast method for strings in Basic. The searched regular expression has the form: (aa)|(bb)|(c).

Sub findReplaceNoFormatting
	dim oDoc as object, p(), s$, oSel as object
	p=array( array("bc", "+1"), array("op", "#") ) 'the replacements: array(Find, Replace)
	s=joinArray(p) 'regular expression like (aa)|(bb)|(c)
	oDoc=ThisComponent
	oSel=oDoc.CurrentController.Selection.getByIndex(0) 'current selection (no multiselection)
	oSel.String=replString(oSel.String, s, p) 'replace whole string in selection
End Sub

Function replString(s$, sreg$, p()) as string 'replace in string
	on local error goto bug
	dim oSearch as object, oParam as object, oFound as object, iCount%, i%, a&, b&, iStart&, sRepl$
	oSearch=CreateUnoService("com.sun.star.util.TextSearch")
	oParam=CreateUnoStruct("com.sun.star.util.SearchOptions")
	With oParam
	  .algorithmType=com.sun.star.util.SearchAlgorithms.REGEXP
	  .searchString=sreg 'string to find in form: (aa)|(bb)|(c)
	End With
	oSearch.setOptions(oParam)
	oFound=oSearch.searchForward(s, 0, len(s)) 'search the string from Start
	iStart=1
	do while oFound.subRegExpressions>0 'some occurence
		a=oFound.startOffset(0) 'start position in string
		b=oFound.endOffset(0) 'end position in string
		for i=1 to oFound.subRegExpressions-1
			if oFound.startOffset(i)>-1 then 'get replacement from array
				sRepl=p(i-1)(1) 'replacement
				exit for
			end if
		next i
		s=mid(s, iStart, a) & sRepl & mid(s, b+1) 'new string
		oFound=oSearch.searchForward(s, b-1, len(s)) 'search string
	loop	
	replString=s	
	exit function
bug:
	bug(Erl, Err, Error, "replString")
End Function

Function joinArray(p) as string 'create regular expression from 1st values in array
	on local error goto bug
	dim p1(ubound(p)), i&
	for i=lbound(p) to ubound(p)
		p1(i)=p(i)(0) 'p1() has the 1st values from p()
	next i
	joinArray="(" & join(p1, ")|(")  & ")" 'output string like: (aa)|(bb)|(c)
	exit function
bug:
	bug(Erl, Err, Error, "joinArray")
End Function

Sub bug(sErl$, sErr$, sError$, sFce$) 'show the error message
	msgbox(sErr & ": " & sError & chr(13) & "Line: " & sErl & chr(13), 16, sFce)
End Sub

This may be helpful to contributors wanting to help:
Legacy Kruti Dev representation
To the OP: Please give relevant information. Most users and contributors in this English forum won’t know anything concerning the transformation of old workarounds for the representation of Hindi scripts to the current Unicode representation.
Attach an example of a text document (.odt) containing parts in KrutiDev. There may be need for experimental steps!
Not knowing anything about the background, users trying to help may waste many hours without a functional result.
There must be a transcription table! Give a link to one! (Best as a spreadsheet.)
Thousands of recorded macros won’t help. One well designed Custom Routine should do.

Kruti Dev to Unicode Macro Code.odt (159.0 KB)

Ohoho… Well, try this

Sub ReplaceInSelection

There was incorrect code here that didn’t do what it was supposed to -
I removed it so that future readers of the thread wouldn’t use it by mistake.

End Sub

Is the order of searched/replaced items proper? 2nd is k, 4th is kk, 5th is kkW, 6th kkS. If it will search k and replace it, then it is not possible to search and replace correctly kk nor kkW nor kkS. There is strange numbering in ODT, args1043, args1029-1042, args1026-1023, args1019-1018, args1016-1017, args962 … Are these argsNumbers for proper order?

@KamilLanda I just reduced 43910 lines to 120 without changing the sequence of replacements. I did not have the patience to analyze the correctness of the code - I simply repeated the sequence of replacements from the original KrutiDevToUnicode procedure. Yes, you’re right, it was necessary to at least pre-sort the table of replacements in descending order of string lengths…

image

This part will not work correctly if there is at least one "”k" in the text. All 934 pairs should be checked for compatibility and for duplicates.

2 Likes

… and in this process, made it possible to grasp, analyze and fix problems in the code. It’s simply unmanageable with nearly 50 thousand lines.

This code works more than 95â„…. But the problem in this code is it also converts the the text which is in English and which is not in kruti dev font. There are several kruti dev fonts like Kruti Dev 055, Kruti Dev 010 etc. I want the code should not disturb the English text. So I feel that if you select the text in kruti dev font and then run the macro and if the macro will affect only on the selected text it will be more useful.

Why? Why didn’t you put it in the body of your question? @Lupp was right

Also heed the advice of @Lupp

Yes, not the text with the code of your macro, but a sample of the transcoded text - this is necessary to check the correct operation of the code before publishing it.

Please carefully check this conversion table and make the necessary corrections (or confirm it is correct) - TrueType_To_Unichar.ods (51.4 KB)

This macro do not run on Tables in Writer and in Calc

This macro do not work in table and in calc.

After about 15 months you come back to this “solved” thread.
Unfortunately I don’t understand what you want to tell.
And there still is no TextDocument (.odt) to help with a better understanding and for experiments. Or did I miss one?
I took the time (rather a lot of time) to analyse your huge recorded “macro” with the help of a spreadsheet, and found that you had recorded 934 replacements. You must have spent a full week of work with the project. Now you can tell us that the question is actually answerdd (“problem solved”). Otherwise you should add useful information and the mentioned example.