LibreOffice5(89)マクロをオートメーションで実行するためのコード

公開日: 2017年10月27日 更新日: 2019年05月11日

旧ブログ

t f B! P L
LibreOffice5(59)モードレスダイアログの例をPythonに翻訳する:その5の「マクロをオートメーションで実行するためのコード」はグローバル変数が多いので、それを減らしたものに変更します。

前の関連記事:LibreOffice5(88)Writerドキュメントのサービスとインターフェイス一覧


マクロをオートメーションで実行するためのコード


このコードはマクロをオートメーションで動作確認するだけためのものなので、副作用はなるべく少なくしたいものです。

グローバル変数が多くするとマクロ内の同名の変数に対して、PyDevでUndefined variableを指摘されなくなってしまいます。

なので、なるべく関数内のスコープで処理するようにして、グローバル変数を少なくします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
if __name__ == "__main__"# オートメーションで実行するとき
    def automation():  # オートメーションのためにglobalに出すのはこの関数のみにする。
        import officehelper
        from functools import wraps
        import sys
        from com.sun.star.beans import PropertyValue
        from com.sun.star.script.provider import XScriptContext 
        def connectOffice(func):  # funcの前後でOffice接続の処理
            @wraps(func)
            def wrapper():  # LibreOfficeをバックグラウンドで起動してコンポーネントテクストとサービスマネジャーを取得する。
                try:
                    ctx = officehelper.bootstrap()  # コンポーネントコンテクストの取得。
                except:
                    print("Could not establish a connection with a running office.", file=sys.stderr)
                    sys.exit()
                print("Connected to a running office ...")
                smgr = ctx.getServiceManager()  # サービスマネジャーの取得。
                print("Using {} {}".format(*_getLOVersion(ctx, smgr)))  # LibreOfficeのバージョンを出力。
                return func(ctx, smgr)  # 引数の関数の実行。
            def _getLOVersion(ctx, smgr):  # LibreOfficeの名前とバージョンを返す。
                cp = smgr.createInstanceWithContext('com.sun.star.configuration.ConfigurationProvider', ctx)
                node = PropertyValue(Name = 'nodepath', Value = 'org.openoffice.Setup/Product' # share/registry/main.xcd内のノードパス。
                ca = cp.createInstanceWithArguments('com.sun.star.configuration.ConfigurationAccess', (node,))
                return ca.getPropertyValues(('ooName', 'ooSetupVersion'))  # LibreOfficeの名前とバージョンをタプルで返す。
            return wrapper
        @connectOffice  # createXSCRIPTCONTEXTの引数にctxとsmgrを渡すデコレータ。
        def createXSCRIPTCONTEXT(ctx, smgr):  # XSCRIPTCONTEXTを生成。
            class ScriptContext(unohelper.Base, XScriptContext):
                def __init__(self, ctx):
                    self.ctx = ctx
                def getComponentContext(self):
                    return self.ctx
                def getDesktop(self):
                    return ctx.getByName('/singletons/com.sun.star.frame.theDesktop'# com.sun.star.frame.Desktopはdeprecatedになっている。
                def getDocument(self):
                    return self.getDesktop().getCurrentComponent()
            return ScriptContext(ctx) 
        XSCRIPTCONTEXT = createXSCRIPTCONTEXT()  # XSCRIPTCONTEXTの取得。
        doc = XSCRIPTCONTEXT.getDocument()  # 現在開いているドキュメントを取得。
        doctype = "scalc", "com.sun.star.sheet.SpreadsheetDocument"  # Calcドキュメントを開くとき。
    #  doctype = "swriter", "com.sun.star.text.TextDocument"  # Writerドキュメントを開くとき。
        if (doc is None) or (not doc.supportsService(doctype[1])):  # ドキュメントが取得できなかった時またはCalcドキュメントではない時
            XSCRIPTCONTEXT.getDesktop().loadComponentFromURL("private:factory/{}".format(doctype[0]), "_blank", 0, ())  # ドキュメントを開く。ここでdocに代入してもドキュメントが開く前にmacro()が呼ばれてしまう。
        flg = True
        while flg:
            doc = XSCRIPTCONTEXT.getDocument()  # 現在開いているドキュメントを取得。
            if doc is not None:
                flg = (not doc.supportsService(doctype[1]))  # ドキュメントタイプが確認できたらwhileを抜ける。
        return XSCRIPTCONTEXT
    XSCRIPTCONTEXT = automation()  # XSCRIPTCONTEXTを取得。
    macro()  # マクロの実行。
40行目と41行目でオートメーションでロードするとドキュメントをCalcかWriterのものか選択できます。

すでに開いているドキュメントが同じタイプであるときはそれを利用します。

シート内容を削除するマクロを実行するときはそのことに注意しないといけません。

このコードではグローバルに出しているのはXSCRIPTCONTEXTとautomationだけです。

モジュールのインポートも関数内のスコープで行うようにしました。

macro()はマクロとして実行する関数です。

次の関連記事:LibreOffice5(90)ScriptingURLの動的取得

ブログ検索 by Blogger

Translate

«
Oct. 2017
»
Sun
Mon
Tue
Wed
Thu
Fri
Sat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Created by Calendar Gadget

QooQ