LibreOffice(5)PythonでLibreOfficeが動く仕組み:UNO

ラベル: ,

前の関連記事:LibreOffice(4)PyCharmからLibreOfficeを動かす(オートメーション)


基礎の仕組みがわからないとマクロを書こうにも解説ページの読解もままなりません。自分なりに理解したことをまとめます。私は全くの独学なので不正確な箇所が多々あるかもしれません。

LibreOfficeはOpenOffice.org APIを操作して動かす


H26.1.9追記。正確にはOpenOffice.org APIではなくLibreOffice 4.2 SDK API Referenceです。)

APIとはApplication Programming Interface(アプリケーション プログラミング インタフェース)の略です。

インターフェースとはざっくりいえば"操作盤"のことです。

LibreOfficeの"操作盤"をOpenOffice.org APIといい、これを操作することによりLibreOfficeが動きます。

LibreOfficeはOpenOffice.orgから派生しているのでOpenOffice.org APIという名前がそのまま使われています。
(ちゃんとLibreOffice 4.2 SDK API Referenceがありました。仕組みはOpenOffice.orgと同じなので以下の説明ではOpenOffice.org APIという名前をそのまま使っています。)

OpenOffice.org APIは、自動車で例えればハンドルやアクセル、ブレーキ、シフトレバーに相当しこれらを操作すればタイヤやエンジンが動くのと同じです。

人間と自動車のようにヒト対機械の間にあるのはユーザーインターフェース、パソコンとプリンタを繋ぐUSBコードのように機械対機械の間にあるのはハードフェアインターフェースといいます。

これと同様にプログラム対プログラムの間にあるAPIなどはソフトウェアインターフェースといいます。

現代の自動車の洗練された操作方法と違ってLibreOfficeの操作は多岐にわたり、基礎知識がないといったいどこを操作すればLibreOfficeを思うとおりに動かせるのかがわかりません。

そのためにはLibreOfficeで導入されている仕組みについての基礎知識を学習します。

OpenOffice.org APIを操作する言語が複数あるのはUNOのおかげ


LibreOffice BasicやPythonのコマンドでOpenOffice.org APIを操作すればLibreOfficeを動かすことができます。

このようにLibreOffice BasicやPythonなど違う言語で書かれたプログラムをLibreOfficeが解釈できるのはその仲立ちの仕事をする仕組みがあるからです。

LibreOfficeではこの仕組みをUniversal Network Objects (UNO)を使って実現しています。

UNOは言語の違いを吸収するだけではなくLibreOfficeという枠さえ乗り越えてプログラムの部品をやりとりできる基盤を構築する壮大な仕組みです。


この仕組みが広がればUNOを組み合わせるだけで自分の思うとおりの働きをするソフトウェアを作ることができるようになるかもしれません。

UNOの部品同士のやり取り、つまりAPIはUNO IDL (UNO Interface Definition Language)で定義されます。

UNOの実際の動作自体はいずれかのプログラミング言語で書かないといけません。

各言語間のデータタイプの違いはUNOのデータタイプに変換して提供します。

各言語を解釈する働きをする部分をUNO Language Bindingsといいます。

UNO Language BindingsはUNO Runtime Environment (URE)ともいい各言語のプログラムはそのなかで動きます。

LibreOffice(4)PyCharmからLibreOfficeを動かすではPythonのUNO Language BindingsであるPy-UNOを使いました。

次にこのPyUNOの働き方をみてみましょう。

PyUNOの3つのモード


PyUNOの働き方には3つのモードがあります。

1つ目はLibreOfficeの中のScripting Frameworkで動くモードです。(=マクロ)


これはLibreOfficeのメニューからツール→マクロ→マクロの管理→Python、からマクロを呼び出したときが該当します。

まさにマクロとしてPythonスクリプトを使います。

2014.3.23追記。sys.executableで確認すると使用されているインタプリタはC:\Program Files (x86)\LibreOffice 4\program\soffice.binでした。)

2つ目はPythonプロセスの中で動くモードです。(=オートメーション)

LibreOffice(4)PyCharmからLibreOfficeを動かすで使ったソケット接続やパイプ接続がこのモードです。

Python-UNO bridgeより改変。

これはLibreOfficeプロセスとPythonプロセスとの間の通信が障壁になって次の3つ目のモードに比べて速度が劣ります。

このようにLibreOfficeの外から起動したスクリプトでLibreOfficeを操作することをオートメーションといいます。

2014.3.23追記。LibreOffice付属のC:\Program Files (x86)\LibreOffice 4\program\python.exeを使うのが無難です。どうしてもバージョンが違うReleases | Python.orgを使いたければそのバージョンでPyUNOをコンパイルしないといけないようです。詳しくはLibreOffice(29)Pythonインタプリタの置き換えは断念へ。)

3つ目はLibreOfficeプロセスの中で動くモードです。(=UNOコンポーネント)

Python-UNO bridgeより改変。

これはアドオンを作る場合に利用されるモードです。

この場合PythonコードはPyUNOに解釈された後は他のUNOと直接やりとりをしないといけませんのでUNO IDLを備えていないといけません。

このようにUNO IDLを備えたものをUNOコンポーネントといいます。

このモードはUNOとして働くので、UNOパッケージとして簡単に配布できます。

LibreOfficeのメニューやツールバーから起動できます。

上記のモードのなかで最高の性能を発揮できます。

利用するにはインストールなどが必要です。

OOoSDK/java/Tutorial - ...?にJavaのUNOコンポーネントの作り方のチュートリアルがあります。

いいこと尽くしですが、UNOIDLの実装を習得しないといけないので自分で作るのはちょっと大変そうです。

(2015.12.13追記。既存のインターフェイスを継承すると意外と簡単にPython UNOコンポーネントが作れました。LibreOffice5(6)既存インターフェイスを継承してPythonスクリプトをUNOコンポーネント化する例:その1参照。さらにCalcの関数の追加にはインターフェイスのIDLの作成が必須です。LibreOffice5(10)Calcに関数を追加するPython拡張機能の例その1参照。)

参考にしたサイト


OpenOffice.org API について - Apache OpenOffice Wiki
OpenOffice.org Basicのプログラミングガイドの中の説明。。

LibreOffice 4.2 SDK API Reference
OpenOffice.org APIはLibreOfficeではLibreOffice 4.2 SDK APIに引き継がれてるようです。

Introduction - Apache OpenOffice Wiki
ここを読めばUNOとは何なのかがわかります。

UNO - N->N->N
N->N->NブログのUNOの解説。このブログを読んで理解できました。

はじめに - N->N->N
上記のブログの最初の記事です。素人向けにとてもわかりやすく解説されています。

Uno Development Kit Project
UNOをLibreOffice以外でも使えることを目指すプロジェクトです。

A. Python-UNO - N->N->N
Python-UNOについて詳しく解説されています

Python-UNO bridge
本家のPyUNOの解説。図を引用させていただきました。

Writing UNO Components - Apache OpenOffice Wiki
UNOコンポーネントの書き方。

4 UNO コンポーネントを書く
古いバージョンですが上記の日本語版。

OOoSDK/java/Tutorial - ...?
JavaでのUNOコンポーネントの書き方のチュートリアル。

次の関連記事:LibreOffice(6)IDLリファレンスでOpenOffice.org APIを知る

PR

1 件のコメント:

  1. Excel VBAのbit操作機能が貧弱で、10進数に戻ってからの演算となります。コードのメンテを考えると、Pythonを検討中で、助かります。

    返信削除