Libreoffice Writer macro to delete every first line on all pages except first page

I am using Ubuntu 22.04 and LibreOffice 24.8.4.2. With the help of Chat GPT I get following code

Sub DeleteFirstLineOnEachPageExceptFirst()
    Dim oDoc As Object
    Dim oViewCursor As Object
    Dim oText As Object
    Dim oPageCursor As Object
    Dim i As Integer
    Dim totalPages As Integer

    ' Get the active document
    oDoc = ThisComponent
    oViewCursor = oDoc.CurrentController.getViewCursor()
    oText = oDoc.Text

    ' Create a page cursor to move between pages
    oPageCursor = oDoc.Text.createTextCursorByRange(oText.Start)

    ' Count the total number of pages
    totalPages = oDoc.CurrentController.PageCount

    ' Move to the second page
    For i = 2 To totalPages
        ' Move to the start of the page
        oPageCursor.gotoPage(i)
        
        ' Move to the first paragraph of the page
        oViewCursor.gotoRange(oPageCursor, False)
        oViewCursor.gotoStartOfParagraph(False)
        oViewCursor.gotoEndOfParagraph(True)

        ' Delete the selected first line
        oViewCursor.String = ""
    Next i
End Sub

But it is giving error on line
oPageCursor.gotoPage(i)

I don’t have knowledge of any programming language. Can anybody suggest a solution for this.

I want to delete the first dashed line on every page in the given document.
Civil 01-04-2024.odt (42.9 KB)

1 Like

:thinking:

That macro was created by recording the macro. After that I referred to Andrew Pitonyak’s books.

Instead of designing a complicated macro-based solution, you should consider restructuring your document by giving it logical consistency.

Your document appears to have a highly repetitive pattern and this calls for dedicated styles (which would also allow for automated entry). Instead of that, it is an horrible mess of direct formatting.

I don’t see the usefulness of your dotted line. It immediately follows the bottom border of a table. Visually, it is redundant. It could be much better replaced by increased Spacing Above of a dedicated style for “Case No.: …”. This extra spacing can automatically be suppressed at top of pages through a Compatibility configuration setting.

Obviously, you need the following paragraph styles:

  • case identification (first paragraph, ended by a paragraph break, not a line break)
  • party names, already highlighted in bold in its Font tab
  • attorney name
  • date (in the table)
  • Table Contents (default style) for otherwise not specific text in table
  • decision
  • court, aligned right

You also need character styles to highlight words in paragraphs. Writer already provide Strong Emphasis (=bold) for case number in first paragraphs and various highlighting in the tables.

Styles give a very easy centralised control on your formatting.

The only thing you can’t do is to force the “title paragraphs” to be kept on the same page as the table (because a table can only be kept with its next paragraph – mainly used for bottom caption).

The alternative is to enter your title paragraphs in a merged first row of the table and designated this new first row as a heading row (which can then be repeated at top of every page in case your table spans several pages). But this means more work when you create a new table.

try:

Sub delete1line 'delete all 1st lines from 2nd page to last page
	dim oDoc as object, oVCur as object, iPage&, i&, s$, undoMgr as object, oPos as object
	const cUndo="delete 1st lines"
	oDoc=ThisComponent
	oDoc.lockControllers
	oVCur=oDoc.CurrentController.ViewCursor 'visible cursor
	oPos=oVCur.start 'remember the position of visible cursor
	iPage=oDoc.CurrentController.PageCount
	undoMgr=oDoc.UndoManager 'undo manager
	undoMgr.enterUndoContext(cUndo) 'only one step in Undo
	for i=2 to iPage
		with oVCur
			.jumpToPage(i)
			.jumpToStartOfPage() 
			.gotoStartOfLine(false) 'start of 1st line
			.goDown(1, true) '1 step down
			.gotoStartOfLine(true) 'start of 2nd line to delete all 1st line without empty space instead of deleted line
			.String=""
		end with
	next i
	undoMgr.leaveUndoContext(cUndo)
	oVCur.gotoRange(oPos, false) 'cursor to initial position
	oDoc.unlockControllers
End Sub
2 Likes

We have to cut the paper from the dashed line and paste it every day. Therefore the dashed lines are useful

Then don’t bother to remove the line and cut also at top of page.

So it seems like some extra-very-super-hard IQ test: “How to delete the dashed lines although the dashed lines are useful”???

No it isnt… but we are not smart enough ( …except @AniruddhaMohod ) :face_with_raised_eyebrow:

Please note thousands of people use this macro and it is demand of several perople that the first dashed line is not necessary.

What is the use of dashed line at the top of page why we should take efforts to cut the top of page.

If the dashed lines at the top of every page goes to previous page then it is also very useful.

Because it is much simpler than writing a complex macro. You’re already clipping your sheet at dashed lines, giving you strips of paper. Cutting once more is fairly a smaller deal than designing a reliable macro and debugging it.

Since you’re cutting below the bottom border of the table (where the dashed line is visually redundant), you can remove altogether all dashed lines. There is also an advantage: if your sheet is not exactly aligned (or you’re using hand scissors), the office cutter will not leave partials bits of the dashed line and the strip will be neater.

You’re contradicting yourself. From previous posts, I understood that this top dashed line was the very first element in the page. No data is above it. This is precisely why you want to remove it. Now, you say it is useful. Therefore you don’t want to remove it. Catch-22!

Please sort out your specification and get back with something unambiguous and straight.

1 Like

This works perfectly. Everyday lakhs of people from Court of the State of Maharashtra in India uses this macro.

I said dashed lines are useful between the tables not at the top of page.

Yes. But we’re talking only (?) of the dashed line occurring at the very top of the page.


PS: avoid single-line posts which stretch a lot the question, resulting in the need for scrolling and some limitation by the site engine requiring to click potentially several times to get to the last posts.

Previous macro deleted the all 1st lines from 2nd page without any control whether the 1st line is only dashed line or not. And because it deletes whole line including the Enter at the end of line, it causes the shifting up of all text after deleted line. So it seems sometimes the dashed line from next page is shifted to the end of previous page (that was deleted 1st line). I see only one possibility
let the empty space instead of dashed line
Macro with easy control the 1st line is only dashed line; delete last page if empty; and execute the deleting lines whether the visible cursor is in bad position (in table or isn’t “focused” in document):

Sub empty1line 'empty all 1st lines from 2nd page to last page
	on local error goto final
	dim oDoc as object, oVCur as object, iPage&, i&, s$, undoMgr as object, oPos as object
	const cUndo="delete 1st lines"
	oDoc=ThisComponent
	oVCur=oDoc.CurrentController.ViewCursor 'visible cursor
	oPos=oVCur.start 'remember the position of visible cursor
	iPage=oDoc.CurrentController.PageCount
	if iPage<2 then exit sub 'only one page so exit
	oVCur.jumpToFirstPage()
	oDoc.lockControllers
	undoMgr=oDoc.UndoManager 'undo manager
	undoMgr.enterUndoContext(cUndo) 'only one step in Undo
	for i=2 to iPage
		with oVCur
			.jumpToPage(i)
			.jumpToStartOfPage()
			.gotoStartOfLine(false) 'start of 1st line
			.gotoEndOfLine(true) 'select line
			s=.String 'text of selected line
		end with
		rem test for dashed line
		s=replace(s, "-", "") 'remove all "-" from line
		if s="" then oVCur.String="" 'it is clear dashed line so delete it
	next i
	rem remove empty last page
	with oVCur
		.jumpToStartOfPage()
		.gotoStartOfLine(false)
		.goToEnd(true)
		s=.String 'text of last page
	end with
	dim calc as object
	calc=CreateUnoService("com.sun.star.sheet.FunctionAccess")
	s=calc.callFunction("REGEX", array(s, "[^:print:]", "", "g")) 'replace non-print characters
	if s="" then oVCur.String="" 'there isn't printable character so delete line
	undoMgr.leaveUndoContext()
	oVCur.gotoRange(oPos, false) 'cursor to initial position (error at this line if cursor wasn't "focused" in document when macro started)
final:
	if oDoc.hasControllersLocked() then oDoc.unlockControllers
End Sub

Theoretically there is some chance to add Enter at the end of page and then delete whole 1st dashedLine+Enter, but if the page ends with the Table and not text, then it is complicated to add new line under the Table, because the macro works with visible cursor and some big or wild jumping of visible cursor could do unexpected bugs, because the execution of macro code could be faster than moving of cursor. So the solution with empty line instead of dashed line seems better.

1 Like

:hot_face:

before @karolus hammers (rightly) it could be free with python,
I shall remind of ScriptForge.String service (SF_String) - FindRegex :wink:

And wouldn’t a ReplaceDescriptor driven approach more straightforward ?

It can be also a possibility to use ScriptForge:

	rem dim calc as object
	rem calc=CreateUnoService("com.sun.star.sheet.FunctionAccess")
	rem s=calc.callFunction("REGEX", array(s, "[^:print:]", "", "g")) 'replace non-print characters
	'with ScriptForge
	GlobalScope.BasicLibraries.loadLibrary("ScriptForge")
	s=SF_String.ReplaceRegex(s, "[^:print:]", "") 'replace non-print characters

But it can be slower because there must be the initialization of ScriptForge library

GlobalScope.BasicLibraries.loadLibrary("ScriptForge")

For this one replacement of one string it is not important, but Calc REGEX is faster than com.sun.star.util.TextSearch that is used in SF_String.ReplaceRegex.

Thanks a lot. I began with writing a post on whatsapp with find and replace regular expression enable. Thousands of people appreciated that. Then I record a macro. Again judicial officers appreciated that. But I noticed that recording a macro can not give bold effects. So I came to asklibreoffice and someone suggested me Andrew Pitonyak’s book on LibreOffice Macro. Then great persons like @KamilLanda helped me to implement my ideas. We are end users. My IQ is not that much. I am a junior clerk. I am an operator not programmer. Many times I feel that final version is created. But people used to ask for different suggestions. Some wants to remove the court name, advocate name, dashed lines, party names. Some do not want to remove anything. Some wants Exhibit bold some do not want. I have to keep in mind all the suggestions and provide facility for all.

Presently I feel that everything is perfect. But after sometimes some other ideas will come to my mind that may help thousands of people and I will ask the doubt on asklibreoffice. The main aim of the macro was to save time and paper. One minute everyday of thousands of people means a lot. I hope you will continue to help me like this. Thanks a lot.