やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

LibreOffice Calc マクロ情報まとめ(環境構築〜HelloWorld)

 これを見ればPythonマクロ実行までできる。

環境構築

sudo apt -y install libreoffice libreoffice-l10n-ja libreoffice-help-ja

スクリプト配置パス

 パスはバージョンや環境によって変わる。ここに配置するとLibreOfficのメニュー→ツールマクロマクロの実行で選択できるようになる。

Python

/home/pi/.config/libreoffice/4/user/Scripts/python

BASIC

/home/pi/.config/libreoffice/4/user/basic/Standard/Module1.xba

セキュリティ

 マクロを実行できるようセキュリティを下げる。

  1. LibreOffice Calc を起動する
  2. メニュー→ツールオプションをクリックする
  3. ダイアログの左にあるツリーからLibreOfficeセキュリティをクリックする
  4. ダイアログの右にあるマクロセキュリティボタンをクリックする
  5. セキュリティレベルタブ内のラジオボタンをクリックする
  6. OKボタンをクリックする

 これでマクロ実行時、信頼されていないソースからのマクロでも、確認ダイアログが表示される。そのときマクロの有効化ボタンをクリックすればマクロが実行できるようになる。

情報収集

情報源

関数一覧

  1. メニューの挿入関数をクリックする(Ctrl+F2

 または以下参照。

マクロの記録

マクロの記録を有効にする

  1. LibreOffice Calc を起動する
  2. メニューのツールオプションをクリックする
  3. ダイアログ左側にあるツリーからLibreOffice詳細を展開する
  4. ダイアログ右側にあるマクロの記録を有効にするチェックボックスをONにする
  5. OKボタンをクリックする

マクロを記録する

  1. メニューのツールマクロマクロの記録をクリックする

スクリプトの作成から実行まで(BASIC)

mkdir -p ~/.config/libreoffice/4/user/basic/Standard
cp ./Module1.xba ~/.config/libreoffice/4/user/basic/Standard
soffice macro:///Standard.Module1.Main

Module1.xba

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic">Sub Main
    MsgBox(&quot;マクロのテストです。&quot;)
End Sub
</script:module>

スクリプトの作成から実行まで(Python

soffice --calc --norestore "--accept=pipe,name=librepipe;urp;" & {
    # LibreOffice Calc の GUI が起動するまでの時間だけ待機させる必要がある。さもなくば以下エラーになる。
    # __main__.NoConnectException: Connector : couldn't connect to pipe librepipe(10)
    sleep 3
    ./filters.py
    jobs
    kill %%
}
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import uno
import unohelper
from pythonscript import ScriptContext
import os.path
import datetime

def connect_script_context(host='localhost', port='2002', namedpipe=None):
    UNO_RESOLVER = "com.sun.star.bridge.UnoUrlResolver"
    UNO_DESKTOP = "com.sun.star.frame.Desktop"
    localCtx = uno.getComponentContext()
    localSmgr = localCtx.ServiceManager
    resolver = localSmgr.createInstanceWithContext(UNO_RESOLVER, localCtx)
    if namedpipe is None:
        uno_string = 'uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext' % (host, port)
    else:
        uno_string = 'uno:pipe,name=%s;urp;StarOffice.ComponentContext' % namedpipe
    ctx = resolver.resolve(uno_string)
    smgr = ctx.ServiceManager
    XSCRIPTCONTEXT = ScriptContext(ctx,
                                   smgr.createInstanceWithContext(UNO_DESKTOP, ctx),
                                   None)
    return XSCRIPTCONTEXT

XSCRIPTCONTEXT = connect_script_context(namedpipe='librepipe')
desktop = XSCRIPTCONTEXT.getDesktop()
doc = desktop.getCurrentComponent()
sheet = doc.getSheets().getByIndex(0)
sheet.getCellByPosition(0,0).Value = 1234

now = datetime.datetime.now()
timestamp = now.strftime('%Y%m%d%H%M%S')
file = os.path.join(os.path.dirname(os.path.abspath(__file__)), timestamp + '.ods')
url  = unohelper.systemPathToFileUrl(file)
doc.storeToURL(url, ())

対象環境

$ uname -a
Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux