Ask Your Question

Macro for keeping paragraphs together

asked 2018-02-19 14:34:54 +0100

Rouletabille gravatar image

updated 2018-02-21 08:26:14 +0100

I used to use a macro from myself in MSOffice to easily keep paragraphs together. The macro was

Sub Paralie()

Dim p As Paragraph, bAlready As Boolean

bAlready = True
For Each p In Selection.Paragraphs
    If Not p.KeepTogether Then
        bAlready = False
        Exit For
    End If

If bAlready Then
    'ParaLignesSolidaires 0
    'ParaSolidaires 0
    For Each p In Selection.Paragraphs
        p.KeepWithNext = False
        p.KeepTogether = False
    'ParaLignesSolidaires 1
    'ParaSolidaires 1
    For Each p In Selection.Paragraphs
        p.KeepWithNext = True
        p.KeepTogether = True
End If

End Sub

I searched for the same in Libre Office and did not find.

The idea is to link the macro to a keyboard shortcut to easily switch a pack of paragraphs from being kept together or not. I do this very often to get a nice page formatting. E.g.

Title level1
some text
Title level2

It is frustrating to get the "Title level2" at the top of a page. Making the "some text" linked allows to avoid that.

edit retag flag offensive close merge delete


Should I reformulate as a question + a response?

Rouletabille gravatar imageRouletabille ( 2018-02-19 15:38:30 +0100 )edit

Wouldn't it be simpler to use specific paragraph styles with Keep with next paragraph attribute set or unset? For instance, Heading x styles have this attribute set for this purpose. Your post seems to hint that you use only direct formatting instead of smartly "styling" your document".

When composing a document, you should think in terms of semantic flow of topics and arguments, not in terms of pages and let LO slice text into chunks called pages (that's LO's job, not yours).

ajlittoz gravatar imageajlittoz ( 2018-02-19 15:57:47 +0100 )edit

"Should I reformulate as a question + a response?" That is not necessary, but i would recommend to make the macro for LibreOffice Basic as an Answer, and then accept your own answer, by clicking on the round checkmark icon on the left.

librebel gravatar imagelibrebel ( 2018-02-19 16:47:41 +0100 )edit

ajlittoz is spot on, your macro is not needed hen you use styling in the correct way. Page brake and left/right page start of paragraphs is something the layout program should do. Therefore you'll find this option in all professional lay-out programs and text editors. MS Word has the same options as LO and many others.

Henk C. Meerhof gravatar imageHenk C. Meerhof ( 2018-02-19 22:28:08 +0100 )edit

@ajlittoz: I use styles for about 30 years. My need is for specific cases as in my example. Or for bullet lists that I want to keep together. Using another style in each case would mean nearly double the number of styles. More, I wanted to publish a sample of this kind of macro. I found very few samples when I started to write this first macro.

Rouletabille gravatar imageRouletabille ( 2018-02-20 19:58:03 +0100 )edit

Then if it is for specific list case, insert your (short?) list inside a frame with an adequate anchor. Text flow property is thus clearly notified to Writer. "Keep with next §" should not be used to create huge unsplitable blocks. And there are circumstances when "Keep with next" doesn't prevent block from being split.

ajlittoz gravatar imageajlittoz ( 2018-02-21 08:04:42 +0100 )edit

1 Answer

Sort by » oldest newest most voted

answered 2018-02-20 19:51:10 +0100

Rouletabille gravatar image

updated 2018-02-21 10:41:39 +0100

So, here is my version for anybody needing it

Sub LinkedPara
    dim oDoc as object
    dim oSelections as object
    dim oSel as object
    dim oPE as object
    dim oPar as object
    dim bAlready as boolean

    ' for reference'
    ' MsgBox  vObj.dbg_methods              'Methods for this object.
    ' MsgBox  vObj.dbg_supportedInterfaces  'Interfaces for by this object.
    ' MsgBox  vObj.dbg_properties           'Properties for this object.

    oDoc = ThisComponent
    oSelections = oDoc.getCurrentSelection() 
    oSel = oSelections.getByIndex(0)    

    oPE = oSel.createEnumeration()
    bAlready = True
    Do While oPE.hasMoreElements()
        oPar = oPE.nextElement()
        if not oPar.ParaKeepTogether then
            bAlready = False
            Exit do
        end if
    'MsgBox "bAlready=" & bAlready, 64'

    oPE = oSel.createEnumeration()
    Do While oPE.hasMoreElements()
        oPar = oPE.nextElement()
        oPar.ParaKeepTogether = not bAlready
        oPar.ParaSplit = bAlready

End Sub

Feel free to correct me or enhance as this is my first macro for Libre Office.

edit flag offensive delete link more


Thanks for sharing this macro @Rouletabille.

Just a few things i noticed:

Two times setting ParaKeepTogether is not necessary.

Where you had p.KeepWithNext=TRUE in VBA, you might instead try oPar.ParaSplit=FALSE here ( Note the inverted semantics ).

the line dim oCursor as object is not necessary.

librebel gravatar imagelibrebel ( 2018-02-20 23:18:49 +0100 )edit

Thank you @librebel for pointing my errors. I fixed the macro (and removed some debugging msgbox)

Rouletabille gravatar imageRouletabille ( 2018-02-21 07:46:30 +0100 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2018-02-19 14:34:54 +0100

Seen: 250 times

Last updated: Feb 21 '18