前の関連記事:LibreOffice(40)埋め込みマクロ2:値の引渡しと受け取り
ドキュメントに埋め込んだマクロを外部から呼び出して呼び出し側のドキュメントに作用させる方法を考えます。
XSCRIPTCONTEXTを渡してもうまくいかず
Py-macroEmbedded.odsに埋め込んだEmbedded.py。
#Embedded.py
def calc_embedded(*args):
xscriptctx = args[0] #XSCRIPTCONTEXTを受け取る。
doc = xscriptctx.getDocument() #受け取ったXSCRIPTCONTEXTからドキュメントオブジェクトを得る。
doc.getSheets().getCellByPosition(0, 0, 0).setString(args[1]) #セルA1に入力する。
return "呼び出し側に戻す値",
XSCRIPTCONTEXTがないのでこれだけでは実行できません。argsの0番目の要素でXSCRIPTCONTEXTを受け取ることを想定しています。
呼び出す側のドキュメントのマクロ。
#file_open.py
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():
doc = XSCRIPTCONTEXT.getDocument()
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))
script_uri = "vnd.sun.star.script:Embedded.py$calc_embedded?language=Python&location=document"
s = doc1.getScriptProvider().getScript(script_uri)
xscritpctx = XSCRIPTCONTEXT #このドキュメントのXSCRIPTCONTEXTを取得。
r = s.invoke((xscritpctx, "呼び出し元の値"), (), ())[0] #このドキュメントのXSCRIPTCONTEXTを引数で渡す。
doc.getSheets().getCellByPosition(0, 1, 0).setString(r[0]) "セルA2に受け取った値を入力する。
このfile_openをPy-macroEmbedded.ods以外のCalcのドキュメントから実行すると、そのドキュメントのXSCRIPTCONTEXTがPy-macroEmbedded.odsに埋め込まれたマクロに渡されてfile_openを実行したドキュメントのセルA1に"呼び出し元の値"が入力される、と思ったのですがそうはいきませんでした。"呼び出し元の値"はPy-macroEmbedded.odsのセルA1に入力されてしまいます。
XSCRIPTCONTEXTはドキュメント固有の情報を引き渡すことはできないようです。
XSCRIPTCONTEXT.getDocument()を引き渡すとうまくいく
XSCRIPTCONTEXTを渡しても呼び出し元のものとは解釈されないのでXSCRIPTCONTEXT.getDocument()で得たドキュメントオブジェクトを渡します。
Py-macroEmbedded.odsに埋め込んだEmbedded.py。
#Embedded.py
def calc_embedded(*args):
doc = args[0]
doc.getSheets().getCellByPosition(0, 0, 0).setString(args[1])
return "呼び出し側に戻す値",
呼び出す側のドキュメントのマクロ。#file_open.py #pyファイル名
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():
doc = XSCRIPTCONTEXT.getDocument()
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))
script_uri = "vnd.sun.star.script:Embedded.py$calc_embedded?language=Python&location=document"
s = doc1.getScriptProvider().getScript(script_uri)
r = s.invoke((doc, "呼び出し元の値"), (), ())[0] #6行目で得たこのドキュメント自身を引数を渡す。
doc.getSheets().getCellByPosition(0, 1, 0).setString(r[0])
これは狙ったとおりになりました。Py-macroEmbedded.odsのマクロを使ってPy-macroEmbedded.ods以外のドキュメントのセルA1に値を入力することができました。
Py-macroEmbedded.odsに埋め込んだEmbedded.pyだけでも実行できるように引数を受け取らないときは自身のXSCRIPTCONTEXT.getDocument()を得るようにします。
#Embedded.py
def calc_embedded(*args):
if not args:
args = list()
args.append(XSCRIPTCONTEXT.getDocument())
args.append("Embedded.pyの値")
doc = args[0]
doc.getSheets().getCellByPosition(0, 0, 0).setString(args[1])
return "呼び出し側に戻す値",
これでPy-macroEmbedded.odsで呼び出しても実行できるようになりました。条件演算 (Conditional Expressions)を使うともう少しスマートになりますね。
#Embedded.py
def calc_embedded(*args):
doc = args[0] if args else XSCRIPTCONTEXT.getDocument()
args1 = args[1] if args else "Embedded.pyの値"
doc.getSheets().getCellByPosition(0, 0, 0).setString(args1)
return "呼び出し側に戻す値",
argsの要素数が多いのなら条件式の評価は1回で済ませたほうがよいでしょうね。#Embedded.py
def calc_embedded(*args):
if args: #引数があるとき
doc = args[0]
args1 = args[1]
else: #引数がないとき
doc = XSCRIPTCONTEXT.getDocument()
args1 = "Embedded.pyの値"
doc.getSheets().getCellByPosition(0, 0, 0).setString(args1)
return "呼び出し側に戻す値",
参考にしたサイト
6.11. 条件演算 (Conditional Expressions)
x if C else y という式はC が true の場合 x が返されます。


0 件のコメント:
コメントを投稿