Converting MS Word macros to LibreOffice ones?

I’ve been using MS Word 2003 since it came out and I’m ready to switch over to LibreOffice, but I need help when it comes to macros

There are two macros I use in ‘03 that someone was nice enough to make for me years ago on a Word forum because I didn’t (and still don’t) know how to make them myself. The first one makes so you can search a keyword and it’ll send all paragraphs containing those keywords to a new document that opens up. The second macro takes all paragraphs and automatically arranges them from biggest to smallest

They both save me a lot of time and I was hoping LibreOffice could do this sort of thing too, but I read that the coding languages are different. Can anyone help me with this? I would be so grateful

Here are the macros in their ‘03 code

First:

Sub TheNewMagicTimeSaver()
  Dim oDoc As Document
  Dim oRng As Range
  Dim strKeyWord As String
  strKeyWord = InputBox("What are you looking for?")
  If strKeyWord = "" Then GoTo lbl_Exit
  Set oRng = ActiveDocument.Range
  Set oDoc = Documents.Add
  With oRng.Find
    Do While .Execute(FindText:=strKeyWord, MatchCase:=False, MatchWholeWord:=True)
      oDoc.Range.InsertAfter oRng.Paragraphs(1).Range.FormattedText
      oDoc.Range.InsertParagraphAfter
      oRng.Paragraphs(1).Range.Delete
      oRng.Collapse 0
    Loop
  End With
  oDoc.Range.ParagraphFormat.SpaceBefore = 0
  oDoc.Range.ParagraphFormat.SpaceAfter = 0
lbl_Exit:
  Exit Sub
End Sub

Second:

Sub SortParasBySize()
  Dim aRng As Range, aTable As Table, aRow As Row
  ActiveWindow.View = wdNormalView
  With ActiveDocument.Range.Find  'Do Find and Replace for separators
    .ClearFormatting
    .Replacement.ClearFormatting
    .Text = "^p"
    .Replacement.Text = "zx"
    .Forward = True
    .Wrap = wdFindContinue
    .Format = False
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
    .Execute Replace:=wdReplaceAll
    .Text = "zxzx"
    .Replacement.Text = "^p"
    .Execute Replace:=wdReplaceAll
    ActiveDocument.Range.ConvertToTable Separator:=wdSeparateByParagraphs, NumColumns:=1
    .Text = "zx"
    .Replacement.Text = "^p"
    .Execute Replace:=wdReplaceAll
  End With
  Set aTable = ActiveDocument.Tables(1)
  aTable.Columns.Add BeforeColumn:=aTable.Columns(1)
  For Each aRow In aTable.Rows
    aRow.Cells(1).Range.Text = Len(aRow.Cells(2).Range.Text)
  Next aRow
  aTable.Rows.Add BeforeRow:=aTable.Rows(1)
  aTable.SortDescending
  aTable.Columns(1).Delete
  aTable.Columns.Add    'insert empty column to reinstate extra paras between sections
  aTable.Rows(1).Delete
  aTable.ConvertToText Separator:=wdSeparateByParagraphs
End Sub

Yes, you must completely rewrite the MS VBA code based on the LO API and one of the supported programming language of the LibreOffice. The LibreOffice supports more than one programming languages. The most similar to the Basic of the VBA is the StarBasic (or it should be named simple “Basic” - the name “StarBasic” comes from the StarOffice era.)

But, there is an option for more compatibility with the VBA in the StarBasic. Try it: your VBA code maybe can run in LibreOffice by usage of this Option:
https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03103350.html

    →

The o.p. can try the Option VBAsupport - without rewriting the macro. I (we) can not try the code without sample documents.

I’m sure @Lupp can :wink:

1 Like

this can be done with altsearch extension with the \R trick on regular expression Replace All,
e.g.

see embedded help for details on redirection.

the sorting by paragraph-size into new document with python:

from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK  as BREAK

def new_doc(which):
    desktop = XSCRIPTCONTEXT.getDesktop()
    return desktop.loadComponentFromURL(f"private:factory/s{which}",
                                       "_blank",
                                       0,
                                       (),)

def clone_para(cursor, paragraph):
    for portion in paragraph:
        cursor.String = portion.String
        names = [ prop.Name for prop in portion.PropertySetInfo.getProperties() ]
        values = [ portion.getPropertyValue( name ) for name in names]
        for name, value in zip(names, values):
            try:
                setattr(cursor, name, value)
            except:
                pass
        cursor.gotoEnd(False)
        
def main(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    paras = sorted(doc.Text, key=lambda para: len(para.String), reverse=True)
    _new = new_doc('writer')
    _new.lockControllers()
    text = _new.Text
    tc = text.createTextCursor()
    for para in paras:
        clone_para(tc, para)
        text.insertControlCharacter(tc.End, BREAK, False)
    _new.unlockControllers()

Sorry I’m new, are python macros different from regular ones? If so I’m willing to learn, I was just curious if it was possible as regular macros like it works in MS Word like I’m more used to. Thank you for any help

Yes, as you use another programming language, and python brings its own standard library (some items may be missing in LibreOffice).
For example in code above you may notice the advanced possibilities to iterate over data-structures:

for name, value in zip(names, values):
            try:

.
“No” would be also right, as you use the same API. Simple procedures, where you only pass some parameters to an API-call will be quite similiar in any language.

…then you should use the extension apso.oxt from here to manage and organizing your python-scripts.