LibreOffice(38)埋め込みマクロ1:セキュリティレベルを変更して開く

ラベル: ,

前の関連記事:LibreOffice(37)マクロの記録をPythonに翻訳3:クラスを使う


LibreOffice(31)Pythonマクロをドキュメントファイルに埋め込むで埋め込んだマクロを他のドキュメントから実行してみます。

Basicの例はみつけたがPythonの例はみつけられず


faq/5/285 - OpenOffice.org Q&Aを読むとBasicではScriptProviderを使う方法と使わない方法があるようです。

(H26.4.13追記。PythonマクロでもScriptProviderを使わない方法、おそらくディスパッチフレームワークを使う方法、をやってみようとしましたがよくわかりませんでした。Pythonマクロから埋め込まれたBasicマクロの起動もうまくできませんでした。エラーもでてこずどこを直したらよいのかもわからないのでいまのところお手上げです。)

具体的には以下の2つのページがとても参考になります。

マクロを実行するマクロ (トピック) • OpenOffice.org コミュニティーフォーラム

OOoBasic/Generic/execute - ...?

いずれもOpenOffice.org Basic、Excel VBA、VB Scriptでの例がありますがPythonの例は見つけられませんでした。

Pythonマクロ固有の書き方についてはPython-UNO bridgeに資料があります。

マクロを外から実行する方法を考える前に、まずは実行したいマクロを埋め込んだドキュメントを呼び出す方法から考えないといけません。

Pythonマクロからドキュメントを開く方法の資料を集める


OOobbs/104 - ...?にBasicの例があります。

LibreOffice(31)Pythonマクロをドキュメントファイルに埋め込むで作ったPy-macroEmbedded.odsをマクロから開くことにします。

このファイルのフルパスはC:\_LibreOffice_test\Py-macroEmbedded.odsです。

このドキュメントファイルを開くにはloadComponentFromURL()を使います。

APIリファレンスでこの使い方をたどっていきます。

APIリファレンスで検索するとloadComponentFromURL()XComponentLoaderインターフェイスのメソッドであることがわかります。


継承図をみるとDesktopサービスXComponentLoaderインターフェイスを継承していることがわかり、PythonマクロではXSCRIPTCONTEXT.getDesktop()でDesktopサービスが得られます。

ですのでXSCRIPTCONTEXT.getDesktop().loadComponentFromURL()loadComponentFromURL()が呼び出せます。
loadComponentFromURL([in] string                                            URL,
                     [in] string                                            TargetFrameName,
                     [in] long                                              SearchFlags,
                     [in] sequence< com::sun::star::beans::PropertyValue >  Arguments
                    )  
loadComponentFromURL()の引数は4つあります。

URLで開くファイルを指定します。

ターゲットフレームは"_blank"とすると常に新しいフレームが生成されます。

サーチフラグはフレームの探し方の指定でFrameSearchFlag Constantに一覧がありますが、これはあまり気にせず「0」でよいようです。

最後の引数でいろいろオプションを指定します。

LibreOffice(35)マクロの記録をPythonに翻訳1:リストとタプルでみたcom.sun.star.frame.XDispatchHelperexecuteDispatch()のArgumentsと同じ形式です。

com.sun.star.beans.PropertyValueのシーケンス型(UNOのシーケンス型)です。

PropertyValueはNameとValueを属性にもつStructです。

Nameはcom.sun.star.document.MediaDescriptorサービスから指定します。

マクロのセキュリティレベルの指定はcom.sun.star.document.MediaDescriptorサービスのMacroExecutionModeになります。

Valueは定数リストcom::sun::star::document::MacroExecMode Constant Groupから指定せよ、とあります。

OOoBasic/Generic/MediaDescriptor - ...?に日本語の解説があります。

UNOの定数をPythonマクロで使う方法はUNO Type mappingのconstantsに書いてあります。

これでPythonマクロを書く資料が整いました。

マクロのセキュリティレベルを変更してマクロからドキュメントを開く方法


まずは単純にドキュメントファイルを開くマクロ。
def file_open():
    f_url = "file:///C:/_LibreOffice_test/Py-macroEmbedded.ods"
    doc1 = XSCRIPTCONTEXT.getDesktop().loadComponentFromURL(f_url, "_blank", 0, ())
ファイルを開くときのオプションは指定せず空のタプル「()」を指定しています。

unohelper.pyにある関数systemPathToFileUrl()を使えばWindowsのパス表記をそのまま使えます。
import unohelper
def file_open():
    f_url = unohelper.systemPathToFileUrl("C:\_LibreOffice_test\Py-macroEmbedded.ods")
    doc1 = XSCRIPTCONTEXT.getDesktop().loadComponentFromURL(f_url, "_blank", 0, ())
これでPy-macroEmbedded.odsは開くのですがこの開き方ではPy-macroEmbedded.odsからマクロは実行できません。

ArgumentsにMacroExecutionModeを指定して開いたドキュメントでマクロが実行できるようにします。
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.document.MacroExecMode import ALWAYS_EXECUTE_NO_WARN
def file_open():
    f_url = unohelper.systemPathToFileUrl("C:\_LibreOffice_test\Py-macroEmbedded.ods")
    args = [PropertyValue()]
    args[0].Name = "MacroExecutionMode"
    args[0].Value = ALWAYS_EXECUTE_NO_WARN
    doc1 = XSCRIPTCONTEXT.getDesktop().loadComponentFromURL(f_url, "_blank", 0, tuple(args))
これでPythonマクロから開いたPy-macroEmbedded.odsでマクロが実行できるようになりました。

3行目で定数ALWAYS_EXECUTE_NO_WARNをインポートして8行目で使用しています。

開いたドキュメントのマクロを警告なしで実行するモードです。

この書き方ですと定数を変更するときは3行目と8行目の2箇所を書き換えないといけません。
from com.sun.star.document.MacroExecMode import (NEVER_EXECUTE, ALWAYS_EXECUTE, ALWAYS_EXECUTE_NO_WARN)
3行目をこのように書いて複数の定数のインポートもできます。

インポートするときにMacroExecutionModeを変数に代入すると1箇所の記載だけで済みます。
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.document.MacroExecMode import ALWAYS_EXECUTE_NO_WARN as uno_mem
def file_open():
    f_url = unohelper.systemPathToFileUrl("C:\_LibreOffice_test\Py-macroEmbedded.ods")
    args = [PropertyValue()]
    args[0].Name = "MacroExecutionMode"
    args[0].Value = uno_mem
    doc1 = XSCRIPTCONTEXT.getDesktop().loadComponentFromURL(f_url, "_blank", 0, tuple(args))
あるいはuno.getConstantByName()を使う方法もあります。
import uno
import unohelper
from com.sun.star.beans import PropertyValue
def file_open():
    f_url = unohelper.systemPathToFileUrl("C:\_LibreOffice_test\Py-macroEmbedded.ods")
    args = [PropertyValue()]
    args[0].Name = "MacroExecutionMode"
    args[0].Value = uno.getConstantByName( "com.sun.star.document.MacroExecMode.ALWAYS_EXECUTE_NO_WARN" )
    doc1 = XSCRIPTCONTEXT.getDesktop().loadComponentFromURL(f_url, "_blank", 0, tuple(args))
uno.getConstantByName()を使うには1行目のimport unoが必要です。

私の環境ではマクロのセキュリティレベル「中」に設定していますが、ALWAYS_EXECUTE_NO_WARNUSE_CONFIGに変更しても警告は表示されず、開いたドキュメントのマクロは実行できませんでした。

参考にしたサイト


ファイルに埋め込まれたマクロを外部から実行するには?
Basicでの方法が紹介されています。

マクロを実行するマクロ (トピック) • OpenOffice.org コミュニティーフォーラム
OpenOffice.org BasicとExcel VBAの例があります。

OOoBasic/Generic/execute - ...?
ドキュメント内のマクロをVB Scriptから実行する例とセキュリティレベルの設定方法もあります。

OOobbs/104 - ...?
マクロのセキュリティモードを指定してマクロからファイルを開くBasicの例。

Python-UNO bridge
Pythonマクロ固有の書き方についての資料があります。

LibreOffice: Namespace List
LibreOffice 4.2 SDK APIの入り口com.sun.star。

OOoBasic/Generic/MediaDescriptor - ...?
マクロのセキュリティモードを指定するMacroExecutionModeの定数の解説。

次の関連記事:LibreOffice(39)7-ZipのGUIで楽にPythonマクロをドキュメントに埋め込む

PR

0 件のコメント:

コメントを投稿