試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

OpenOffice.orgのマクロをPythonで記述して動かす(概要,ファイル配置,ダイアログの表示)

OpenOffice.orgには専用の「OpenOffice.org Basic」という言語があり、マクロを記録したときにはこの言語で書き出されるのだが、マクロはPythonで記述することもできる。
ここでは、必要なパッケージ,スクリプトの配置,簡単なダイアログの表示までを扱う。

必要なパッケージ

ここではディストリがパッケージとして用意するOpenOffice.orgについてを扱う。本家(www.openoffice.org)版ではなくGo-oo(go-oo.org)版が用いられているディストリも多い。
PythonのマクロをOpenOffice.orgで用いるにはその仲立ち*1をするソフトウェア(ブリッジ)のパッケージ(Python-UNO*2もしくはPy-UNOと呼ばれる)を別にインストールする必要がある。パッケージ名はディストリによって異なるが、「python(py)」「uno」「openoffice.org(ooo)」といった単語が関係している。

本家版のパッケージでは幾つかパッケージが分かれている中の1つとしてPython-UNOのパッケージがあり、Python本体もこれに同梱される形となっている(システムのPythonは用いられない)。Windows版でもPythonは同じようにして付属するようだ(未確認)。OpenOffice.orgのバージョン3.2系の時点では付属するPythonのバージョンは2.6系となっている。

スクリプトの配置

${HOME}/[OOoのユーザディレクトリ]/user/Scripts/ディレクトリの中にpythonというディレクトリを作成し、その中にスクリプトを配置する。実行属性は不要。
ユーザディレクトリの名前は使用しているOpenOffice.orgによって異なる場合があり、Mandriva Linux 2010.0のGo-oo版の場合、スクリプトの配置場所は${HOME}/.ooo3/user/Scripts/python/[スクリプト].pyのようになっている。ユーザディレクトリは自動的に作成されるので、隠しファイル/ディレクトリを表示するようにして自分のホームディレクトリを見ればどこに入れればよいかが分かる。

簡単な例

まずは下の内容のスクリプトを上のディレクトリに配置する。
[任意]ファイル名: [OOoユーザディレクトリ]/user/Scripts/python/hello.py

# -*- mode: python; coding: utf-8 -*-

import uno
#import unohelper  # このコードでは未使用

class Bridge(object):
  """
  PythonとOOoの仲立ちをする各種オブジェクトと
  それを用いた幾つかの操作を提供
  """
  def __init__(self):
    """
    各種オブジェクトの取得
    """
    # http://api.openoffice.org/docs/common/ref/com/sun/star/script/provider/XScriptContext.html
    # http://api.openoffice.org/docs/common/ref/com/sun/star/uno/XComponentContext.html
    self._context = XSCRIPTCONTEXT.getComponentContext()
#    self._manager = self._context.ServiceManager  # このコードでは未使用
    self._desktop = XSCRIPTCONTEXT.getDesktop()
#    self._document = XSCRIPTCONTEXT.getDocument()  # このコードでは未使用
    # http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XDesktop.html
    self._frame = self._desktop.CurrentFrame
    # http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XFrame.html
    self._window = self._frame.ContainerWindow
    self._toolkit = self._window.Toolkit
  def run_infodialog(self, title='', message=''):
    """
    情報ダイアログを表示する
    http://api.openoffice.org/docs/common/ref/com/sun/star/awt/XMessageBoxFactory.html
    http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOoPython%2FOverView
    """
    msgbox = self._toolkit.createMessageBox(self._window,
                                            uno.createUnoStruct('com.sun.star.awt.Rectangle'),
                                            # ダイアログの種類を指定する文字列
                                            # infobox,warningbox,errorbox,
                                            # querybox,messboxのいずれか
                                            'infobox',
                                            1,
                                            title,
                                            message)
    msgbox.execute()
    msgbox.dispose()


def hello():
  """
  ここに記述した文字列がマクロ選択ダイアログから説明として表示される
  """
  # マクロとしての処理は関数の先頭から始まる
  pyuno = Bridge()
  pyuno.run_infodialog(title='Test テスト', message='Python UNO Test\nパイソン ユーノウ テスト')


# このタプルに名前を書いた関数のみマクロ選択ダイアログから実行できる
# g_exportedScriptsを記述しない場合は全て実行可
g_exportedScripts = (hello,)

その後メニュー「ツール - マクロ - マクロを実行」で「ライブラリ - マイマクロ - [ファイル名]」を選択すると右に「hello」が出るのでこれを選択し、「実行」を押す。

すると

このようなダイアログが出る。アイコンはアイコンテーマの設定によって異なる。
(2010/3/15)一部メンバ関数をプロパティに置き換え

メモ

処理の開始

マクロの処理はスクリプト中のいずれかの関数(クラスのメンバ関数ではない)から始まる。
既定ではスクリプト中に記述した全ての関数が選択可となるが、g_exportedScriptsというタプルに関数名を記述すると、それ以外の関数名をマクロの一覧に表示させない(開始位置として指定できない)ようにできる。

Python-UNOの各種オブジェクト

マクロとして実行したときにXSCRIPTCONTEXTというオブジェクトが利用可能となり、ここから取得できる幾つかのオブジェクトから更に別のオブジェクトを得るという形でOpenOffice.org側とのやりとりをするための色々なオブジェクトを得るという流れがある。これはPython-UNOを用いたスクリプトでは決まった流れの1つで、上の例ではこういったオブジェクトはクラス(「Bridge」とした)のメンバとしてまとめてしまい、これらを用いる処理はそのクラスのメンバ関数にした。
XSCRIPTCONTEXTなどの各種オブジェクトの詳しい部分は把握できていない。

メッセージダイアログの表示

メッセージダイアログを表示するには決まった流れがあり
http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOoPython%2FOverView
を参考にした。この流れの中ではXSCRIPTCONTEXTから取得した幾つかのオブジェクトを用いており、上の例ではBridgeクラスのメンバ関数にした。

マクロの説明文字列

関数のドキュメンテーション文字列がマクロ一覧のダイアログの中で説明として表示される。関数名(マクロ名となる)に日本語は使えないがこの説明には日本語が記述できる。
(2010/3/12)ドキュメンテーション文字列の最初に改行があると表示も改行され、行の先頭にスペースがあるとそれも反映される。表示を最もコンパクトにするには

def hello():
  "ここに記述した文字列がマクロ選択ダイアログから説明として表示される"

のようにするのが良い(複数行の場合は改行に注意)が、改行をエスケープして

def hello():
  """\
  ここに記述した文字列がマクロ選択ダイアログから説明として表示される
  """

のようにしたり、色々な書き方はできる。ただ、上の例では行頭のスペース(に加え、実際は見えないが最後の改行も)は説明の中に入ってしまう。
しかし、それほど説明が長くならなければ、あまり気にする必要はないかもしれない。

参考にしたURLなどについて

など。
実行するメンバ関数の名前が分かっていてその詳細が調べたいというときには関数名*3検索エンジンで調べるか
http://api.openoffice.org/
の検索ボックスに関数名を入力し、結果の「HTML コンテンツ」からその説明になっているページを探して開く。
どのようなことができるかは色々なサンプルを参考にするのが良さそうで、Basicを用いたものに関するページでも、場合によっては考え方や処理の流れについての記述があったりして参考になることがある。Basicのコードについても部分的に参考にできる部分がある場合が多い。

関連記事:

使用したバージョン(いずれもMandriva Linux 2010.0のパッケージ):

*1:OpenOffice.org APIを扱うためのものであり、OpenOffice.orgが持つ機能の大部分が扱える仕組みになっている

*2:「UNO」の読み方は「ユーノウ」であり「ウノ」「ウーノ」「ウノウ」「ユーノ」などは間違い・UNOはOpenOffice.orgの機能を用いるための仕組み

*3:キーワード「api」などと組み合わせてもよい