銀月の符号

Python 使い見習いの日記・雑記

Python-Uno 2時間目

OpenOffice calcをpythonで動かしたいけど — lights on zope への挑戦開始。ちょっと興味わいてきた。

まだよくわかってないけれど、なんとかセルの値を読むところまでできた。この内容の py ファイル(UTF-8, 改行文字LF)を C:\Documents and Settings\ユーザー名\Application Data\OpenOffice.org2\user\Scripts\pythonWindows の場合。python ディレクトリはなければ作る。)におくと Python マクロ ダイアログに「message_box」と「print_sheet1_A2」が現れる。

「message_box」は "message" というメッセージボックスを表示するもの。まずここで30分引っかかった。なんてこったい。
「print_sheet1_A2」は現在開いている Calc ファイルの「表1」シートの「A2」に入っている値をメッセージボックスに表示。

# -*- coding: utf-8 -*-
u"""
OpenOffice calc を動かすぜ!?
2 時間目。
"""
import uno
import unohelper

# XSCRIPTCONTEXT フレームワークスクリプトで利用される変数。
#                Python と OOo とのやり取りをするのに。
#                import 不要。

ctx = XSCRIPTCONTEXT.getComponentContext() # コンポーネントコンテキスト
smgr = ctx.ServiceManager # サービスマネージャ。
                          # サービスをインスタンス化するために使う。
                          # com.sun.star.lang.XMultiComponentFactory インターフェース
desktop = XSCRIPTCONTEXT.getDesktop() # デスクトップ。
                                      # com.sun.star.frame.Desktop サービス

def message_box(message="massage", title=""):
    u"""
    メッセージボックスの表示
    http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOoPython%2FOverView#w59468b2 の最下、
    「メッセージボックス」より。
    """
    _message_box(XSCRIPTCONTEXT.getDesktop(), message, title) 


def _message_box(desktop, msg, title):
    frame = desktop.getCurrentFrame()
    win = frame.getContainerWindow()
    toolkit = win.getToolkit()
    rect = uno.createUnoStruct("com.sun.star.awt.Rectangle")
    msgbox = toolkit.createMessageBox( 
        win,
        rect,
        "messbox",
        1,
        title,
        msg,
        )
    msgbox.execute()


def print_sheet1_A2(sheet_name=u"表1"):
    u"""
    シート 表1 のセル A2 を取得
    http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOoBasic%2FCalc
    の「ドキュメント」、「シート」、「セル」、「セルの値」より
    """
    doc = XSCRIPTCONTEXT.getDocument() # 現在のドキュメント
    sheets = doc.getSheets() # シートコンテナ
    if sheets.hasByName(sheet_name):
        sheet = sheets.getByName(sheet_name) # 名前でシートにアクセス
        cell = sheet.getCellByPosition(0, 1) # セル A2 取得
        #cell = sheet.getCellRangeByName("A2") # セル A2 取得 その2
        message_box(cell.String, u"文字列") # セルの文字列を表示
        message_box(cell.Formula, u"数式") # セルの数式を表示
        message_box(cell.Value, u"値") # セルの数値を表示
    else:
        message_box(u"シートが見つかりません")


# グローバル変数 g_exportedScripts に登録した関数のみ
# マクロとして使用可能。
# この変数が未定義だとすべての関数が使用可能。
g_exportedScripts = (
        message_box,
        print_sheet1_A2,
        )

外部の Python スクリプトから呼ぶには http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOoPython%2FAutomation 参照。しかし Python 2.5 から uno モジュールをインポートすると pyuno モジュールの拡張子が dll ゆえに引っかかる。 pyd になっていない。 どうやら Python 2.3.4 時代の産物のようなんだよなぁ。内蔵している Python のバージョンが 2.3.4 。
外部操作は… Excel を COM 経由で操るよりも問題が多そうだ?