Macros

Introduction

Here you will find a few bits of code that I have found useful. Perhaps you may do too. I know nothing about programming macros in Open Office.

 It is easy to record macros and then assign them to keyboard shortcuts, menus, or toolbar buttons.

  1. Typing Special Characters
  2. Assigning Shortcuts
  3. Assigning Em-dash to a Shortcut
  4. Search and Replace
  5. Add and Remove Ligatures
  6. Launching External Programs
  7. Assigning a Macro to a Button
  8. Assigning a Macro to a Menu
  9. Paste Unformatted Text
  10. Set and Find Quickmark
  11. Go to Page Number

Disclaimer

Always keep backups of files, and test macros thoroughly before relying on them. You use the code snippets on this page entirely at your own risk, and you must take full responsibility for ensuring that they work as you would wish.

Typing Special Characters

If you need to work with foreign languages or symbols, you may find inserting special characters via the Special Character palette too slow for frequent use. The best way is to record macros and assign them to shortcut keys.

Shortcuts

First, record a macro to insert each special character that you need to use frequently. Tools, Macro, Record, Insert, Special Character, then select the character you need, and end recording to save the macro.

The macro will include two lines of code to record the font name in effect when the macro was recorded. The font size is not recorded. This is the code recorded to insert a single estimated symbol.

    sub Estimated
    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 args1(1) as new com.sun.star.beans.PropertyValue
    args1(0).Name = "Symbols"
    args1(0).Value = "℮"
    args1(1).Name = "FontName"
    args1(1).Value = "Guru"

    dispatcher.executeDispatch(document, ".uno:InsertSymbol", "", 0, args1())

    end sub

Unless we always wish to use the “Guru” font when inserting the “Estimated” symbol, we can delete the two lines that I have highlighted in bold.

From the Tools menu, select Macros, Organise, OpenOffice.org Basic. Select the macro you wish to edit from the list and click on edit. Scroll down and delete the two rows defining the font name. You can search within the macro editor for similar lines that you wish to delete. When done, just close the macro editor and your changes will be saved automatically.

Assigning Shortcuts

Next we must assign the macros to suitable shortcut keys.

Tools, Customise, Keyboard, and scroll down in the “Category” field to your OpenOffice.org Basic macros and select one that you wish to use. Click in the “Shortcuts” field and press the shortcut that you wish to assign. Click on “Modify” to assign your macro to the selected shortcut key. Repeat for all other macros.

For fast typing it is very helpful to plan your keyboard assignments carefully so that they are both easy to memorise and easy to type.

For those that are used less frequently, just use the shortcut Control + Shift +S to open the Insert Character palette.

Open Office badly needs more options for assigning shortcuts using the Alter key and Control + Alter combinations with shift.

Vote for Issue 4579 to get it fixed.

Assigning Em-dash to a Shortcut

First, I recorded a short macro to insert an em-dash. Then I edited the macro to remove an reference to the typeface so that it will not change the typeface when used to insert an em-dash.

    sub mdash
    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 args1(1) as new com.sun.star.beans.PropertyValue
    args1(0).Name =
    "Symbols"
    args1(0).Value = "—"

    dispatcher.executeDispatch(document, ".uno:InsertSymbol", "", 0, args1())

    end sub

To assign the macro to a keyboard shortcut:

From the Tools menu, select Customise, Keyboard, Functions, Category, OpenOffice.org Macros, and select your recently recorded macro. Click once inside the Shortcut keys field, press the shortcut you wish to use, then click on modify to assign the selected macro to that shortcut key.

Search and Replace

I often need to update old documents to use Unicode fonts. In the old days, we invented our own encodings to make Pāli fonts using the limited characters available in the ANSI character set. This macro provided by JohnV on the Open Office Forum is very easy to modify to suit your own needs. It uses two arrays: one to hold the characters (or text strings) to find, and another to hold the characters (or text strings) to replace them with. You can add more, but I expect that there is a limit on how many you can add, and how long the strings can be. You can rename the subroutine as you like.

    Sub SktToUnicode
    oDoc = thisComponent
    aFind = Array(
    "  ", "Æ","æ" ,"Ø", "ø" ,"Þ" ,"þ", "Ð", "ð", "Ḥ", "ḥ", "¡", "¹", "º", "µ", "¤", "¼", "£", "³", "®", "¶", "¾", "½", "±", "ª", "©", "¢", "¿", "¥")
    aReplace = Array(
    " ", "Ā", "ā", "Ī", "ī", "Ū", "ū", "Ḍ", "ḍ", "²", "¬", "Ḷ", "ḷ", "Ṃ", "ṃ", "Ṇ", "ṇ", "Ṅ", "ṅ", "Ṛ", "ṛ", "Ṝ", "ṝ", "Ṣ", "ṣ", "Ś", "ś", "Ṭ", "ṭ")
    aRayCount = 0
    FandR = oDoc.createReplaceDescriptor
    FandR.SearchCaseSensitive = true
    FandR.SearchRegularExpression = true
    While aRayCount <= uBound(aFind)
     FandR.setSearchString(aFind(aRayCount))
     FandR.setReplaceString(aReplace(aRayCount))
     aRayCount = aRayCount + 1
     oDoc.ReplaceAll(FandR)
    Wend
    End Sub

Updated to include support for regular expressions (30/11/2005)

The above array values will replace all line-breaks with a space.

The following is an example of the modified code to replace CSX Encoded Pali fonts with Unicode.

    Sub CSXtoUnicode
    oDoc = thisComponent
    aFind = Array(
    "  ", "ò", "ñ", "§", "â","à" ,"ä", "ã" ,"æ","å", "ô", "ó", "ÿ", "þ", "ì", "ë","î", "í", "ý", "ü", "ö", "õ", "¥", "¤", "ð", "ï", "è", "ç", "ê", "é", "ú", "ù", "ø", "÷")
    aReplace = Array(
    " ", "Ṭ", "ṭ", "ṁ", "Ā", "ā", "Ī", "ī", "Ū", "ū", "Ḍ", "ḍ", "Ḥ", "ḥ", "Ḷ", "ḷ","Ḹ", "ḹ", "Ṃ", "ṃ", "Ṇ", "ṇ", "Ñ", "ñ", "Ṅ", "ṅ", "Ṛ", "ṛ", "Ṝ", "ṝ", "Ṣ", "ṣ", "Ś", "ś")
    aRayCount = 0
    FandR = oDoc.createReplaceDescriptor
    FandR.SearchCaseSensitive = true
    FandR.SearchRegularExpression = true
    While aRayCount <= uBound(aFind)
     FandR.setSearchString(aFind(aRayCount))
     FandR.setReplaceString(aReplace(aRayCount))
     aRayCount = aRayCount + 1
     oDoc.ReplaceAll(FandR)
    Wend
    End Sub

Add Ligatures

This version of the search and replace macro will search a document for common ligature groups and replace them with ligatures. Be aware that this will cause problems with spell-checking as words like “effect” or “difficult” will not be recognised when they contain ligatures. As you can probably see below, some fonts like Verdana do not support ligatures, so what you will get is the square box, the notdef character.

    fi ligautreSub AddLigatures
    oDoc = thisComponent
    aFind = Array("ck", "ct", "fj", "fr", "fft", "ffy", "fty", "ft", "fy", "sp", "tr", "tt", "ty", "tz", "Qu", "Th", "ffi", "ffl", "fi", "fl", "ff", "ſt", "st")
    aReplace = Array("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "ffi", "ffl", "fi", "fl", "ff", "ſt", "st")
    aRayCount = 0
    FandR = oDoc.createReplaceDescriptor
    FandR.SearchCaseSensitive = true
    While aRayCount <= uBound(aFind)
     FandR.setSearchString(aFind(aRayCount))
     FandR.setReplaceString(aReplace(aRayCount))
     aRayCount = aRayCount + 1
     oDoc.ReplaceAll(FandR)
    Wend
    End Sub

Remove Ligatures

If you change your mind, or change the font, and wish to revert to regular text, this version of the macro will undo the effects of the previous macro, replacing ligatures with plain text.

    fi ligautreSub RemoveLigatures
    oDoc = thisComponent
    aFind = Array("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "ffi", "ffl", "fi", "fl", "ff", "ſt", "st")
    aReplace = Array("ck", "ct", "fj", "fr", "fft", "ffy", "fty", "ft", "fy", "sp", "tr", "tt", "ty", "tz", "Qu", "Th", "ffi", "ffl", "fi", "fl", "ff", "ſt", "st")
    aRayCount = 0
    FandR = oDoc.createReplaceDescriptor
    FandR.SearchCaseSensitive = true
    FandR.SearchRegularExpression = true
    While aRayCount <= uBound(aFind)
     FandR.setSearchString(aFind(aRayCount))
     FandR.setReplaceString(aReplace(aRayCount))
     aRayCount = aRayCount + 1
     oDoc.ReplaceAll(FandR)
    Wend
    End Sub

Launching External Programs

There are a couple of programs I like to have easily available from the Open Office interface. Windows calculator, Babel Map, and Irfan View are the most useful. This macro will launch Irfan View. Just change the path and the subroutine name if you need to launch another program.

    sub IrfanView
    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 ----------------------------------------------------------------------
    Shell(
    "C:\Program Files\IrfanView\i_view32.exe",1)

    end sub

Assigning a Macro to a Button

This is very similar to assigning a macro to a keyboard shortcut, but with one extra stage, you need to select or import a suitable icon. Irfan View can be used to create a suitable icon. Open the application file in Irfan View. It will usually contain a 32 pixel icon. Resize this to 16 pixels and save it as a PNG image with a transparent background.

 See Customising Toolbars for more details.

Assigning a Macro to a Menu

From the Tools menu, select Customize, Menus. Select the menu to customize, and click the Add. button. In the Add Commands dialogue, Category field, scroll down to OpenOffice.org Macros, and select the macro to add. Close that dialogue, and rename the menu using a ~ tilde sign before the letter you wish to use on the menu for a shortcut. Use the up and down Arrows on the Customize dialogue box to move the new menu item to where you want it.

Customise Menu Dialogue
By default, macro items have no icons. If you want one, add a macro to a toolbar first, and select an icon for it. Then the same icon will be used in the menu.

Paste Unformatted Text

By default, Control V will paste formatted text. If you prefer to paste unformatted plain text you can use the Paste Special submenu on the Edit menu, but it requires extra clicks or keystrokes. Assign this macro to Control V or Control Shift V to speed things up.

    sub PasteText
    dim document as object
    dim dispatcher as object
    document = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
    dim args1(0) as new com.sun.star.beans.PropertyValue
    args1(0).Name =
    "SelectedFormat"
    args1(0).Value =
    1
    dispatcher.executeDispatch(document, ".uno:ClipboardFormatItems", "", 0, args1())
    end sub

Set and Find Quickmark

These two macros are designed to work as a team. The following macro will find the Quickmark if it has already been set in the current session; if not, it will set the Quickmark at the current cursor position. The Quickmark is not saved in the document. You can return to your current working position on reopening documents by checking the setting in Options, Load/Save, General, Load User-specific settings with the document.

    Sub Quickmarkfind
       dim oViewCursor as Object  
       oViewCursor = ThisComponent.currentController.viewcursor   
         On Error Goto ErrorHandler
       oViewCursor.gotoRange(oTextCursor,false)   
     
    Exit Sub
         ErrorHandler:
         Call Quickmarkset
    End Sub

The following macro will set the Quickmark at the current cursor position if it has not yet been set in the current session, or move it to the current position if it has. A Quickmark cannot be set if the cursor is inside a Table or Frame.

    Sub Quickmarkset
       Dim oViewCursor As Object
       oViewCursor = ThisComponent.currentcontroller.viewcursor
         On Error Goto ErrorHandler
       oTextCursor = ThisComponent.Text.createTextCursorByRange(oViewCursor)
       Exit Sub
         ErrorHandler:
         Print (
    "The cursor may be in a table or frame")
    End Sub

Go To Page Number

If your document has front matter, the page number in the Navigator will be out of synch. The command “Go To Page” (Control Shift F5) just gives focus to the Navigator. This macro can be assigned to a shortcut key and will open a dialogue box, where you can enter the offset (for front matter) and the page number. The Prior page shows the page from which you jumped to the current page when you last used the macro.

Go To Page Number Dialogue

    Sub GoToPage
    Def = PriorPjcv
    Def = Lcase(Def)
    oVC = thisComponent.CurrentController.getViewCursor
    CurrentP = oVC.getPage
    If Not ShowDef then Def = ""
    Info =
    "Current Page = " & CurrentP
    If PriorPjcv <> "" then Info = Info & "  Prior Page = " & PriorPjcv
    a$ =
    "Enter Page Number Below. "
    a$ = a$ &
    "However, if Front Matter exists, add a space and an offset. "
    a$ = a$ & "For example, 7 14 will go to Page 7 after Roman Page XIV. "
    a$ = a$ & "To jump by n pages enter +n or -n where n is any number."
    sAns = InputBox(a$,
    "GO TO PAGE " & Info,Def)
    If sAns = "" then End
    b = split(sAns) : c = b(0) : d = 0
    I = Instr("+-",Left(c,1))
    If I > 0 then
     PlusMinus = true
     
    If I = 1 then c = Mid(c,2) 'Another + sign we need to get rid of.
    EndIf
    If ubound(b) > 0 then d = b(1)
    If Not isNumeric(c) Or Not isNumeric(d) then GoToPage() 
    c = Cint(c) : d = Cint(d)
    If PlusMinus then
      p = CurrentP + c + d
     
    Else p = c + d
    EndIf
    If p < 1 then
     MsgBox(
    "There is no page less than 1.",,"Entry Result =  " & p)
     GoToPage()
    EndIf
    oVC.jumpToPage(p) 'If beyond end, you get the last page.
    PriorPjcv = CurrentP
    End Sub