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

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

OpenOffice.orgのマクロをPythonで記述して動かす(Calcのアクティブもしくは任意のシートとセルのオブジェクトの取得)

ここではPython-UNOを用いたOpenOffice.org Calcの個別のシートとその中のセルのオブジェクトの取得に関するメモを扱い、実際のセル操作とその例については別記事で扱う。

操作するシートのオブジェクトを得る

マクロからセルの操作を行うためには、操作対象のシートのオブジェクトを事前に取得しておく必要がある。

アクティブシートオブジェクトの取得

アクティブなシートのオブジェクトは(Python-UNOのマクロスクリプトから常にアクセスできる)XSCRIPTCONTEXTオブジェクトのメンバ関数getDocument()で得たドキュメントオブジェクトのメンバCurrentControllerのメンバActiveSheet*1として得られるが、OpenOffice.org Calc上でマクロが実行された場合でないと得られない*2ため、ドキュメントオブジェクトのsupportsService()によるチェックを行うとよい。

class NotOOoCalcException(Exception):
  pass

class Bridge(object):
  def __init__(self):
    self._document = XSCRIPTCONTEXT.getDocument()

class OOoCalc(Bridge):
  def __init__(self):
    Bridge.__init__(self)
    if not self._document.supportsService('com.sun.star.sheet.SpreadsheetDocument'):
      self.run_errordialog(title='エラー', message='このマクロはOpenOffice.org Calcの中で実行してください')
      raise NotOOoCalcException()
    # ここまで処理が正常に進んだらOOo Calcの中であるとみなせる
    # CurrentControllerは「ようこそ」画面でマクロを実行した場合などには取得できないので
    # チェックの後でアクセスするようにする
    self.__current_controller = self._document.CurrentController
  def get_active_sheet(self):
    return self.__current_controller.ActiveSheet
  def set_active_sheet(self, value):
    self.__current_controller.ActiveSheet = value
  active_sheet = property(get_active_sheet, set_active_sheet)

def macroname():
  try:
    calc = OOoCalc()
  except NotOOoCalcException:
    return
  # ここからマクロのメイン処理
  sheet = calc.active_sheet
  cell = sheet.[メンバ関数]()
任意のシートのオブジェクトを取得

OpenOffice.orgのマクロをPythonで記述して動かす(Calc上でマクロが動作しているかのチェックと全シートのオブジェクトの取得に関するメモ)」の要領で全てのシートを含むオブジェクトを取得し、メンバ関数getByIndex()(何番目かを指定)*3getByName()(シート名で指定)を呼ぶことで、戻り値として対象のシートのオブジェクトを得ることができる。

class NotOOoCalcException(Exception):
  pass

class Bridge(object):
  def __init__(self):
    self._document = XSCRIPTCONTEXT.getDocument()

class OOoCalc(Bridge):
  def __init__(self):
    Bridge.__init__(self)
    if not self._document.supportsService('com.sun.star.sheet.SpreadsheetDocument'):
      self.run_errordialog(title='エラー', message='このマクロはOpenOffice.org Calcの中で実行してください')
      raise NotOOoCalcException()
  @property
  def sheets(self): return self._document.Sheets

def macroname():
  try:
    calc = OOoCalc()
  except NotOOoCalcException:
    return
  # ここからマクロのメイン処理
  # 全てのシートのオブジェクト
  sheets = calc.sheets
  # 0番のインデックスを持つシートを取得する例
  # http://api.openoffice.org/docs/common/ref/com/sun/star/container/XIndexAccess.html
  sheet0 = sheets.getByIndex(0)
  # "Sheet2"の名前を持つシートを取得する例
  # http://api.openoffice.org/docs/common/ref/com/sun/star/container/XNameAccess.html
  sheet2 = sheets.getByName('Sheet2')

セルオブジェクトの取得

セルの内容にアクセスするにはセルのオブジェクトを得る必要があり、個別のシートオブジェクトに対して以下のいずれかのメンバ関数を呼び出して戻り値として得る。

  • getCellByPosition(): 引数にはセルのX,Yインデックス(ともに0から・A1なら「0,0」)を指定
  • getCellRangeByName(): 引数には単一のセルの名前を示す文字列(例:A1)を指定*4

(「OpenOffice.orgのマクロをPythonで記述して動かす(Calcのセル内容へのアクセスについてとセル内容の操作に関する例)」に続く)

関連記事:

参考URL:

使用したバージョン:

*1:後述の方法で取得するシートオブジェクトの代入によりアクティブシートの切り替えもできる

*2:「ようこそ」画面などでマクロを動かしたときには途中のCurrentControllerというメンバが見つからずにエラーとなる

*3:0番目からなのに注意

*4:セル範囲を得るためのものだが、単一のセルを得るのにも使える