前の関連記事:Calc(62)選択したセルの上下左右に枠線を引くマクロ
XViewSplitableインターフェイスはDeprecatedになっている
コントローラがサポートしているXViewSplitableインターフェイスのgetSplitRow()メソッドでは左上の枠に表示されている最下行の次の行インデックス、getSplitColumn()メソッドでは左上の枠に表示されている右端列の右の列インデックスが取得できます。
ウィンドウの分割のこの状態ではgetSplitRow()で23、getSplitColumn()で3が返ってきます。
これらの戻り値は左上の枠の最下行と右端列のインデックスのみ依存して、他の枠の状態には依存しません。
ウィンドウの分割のときはXViewSplitableインターフェイスでは左上の枠以外のインデックスを取得することはできません。
セルの固定の時はgetSplitRow()が左下と右下のの枠の最初の行インデックス、getSplitColumn()が右上と右下の最初の列インデックスに該当します。
APIリファレンスではXViewSplitableインターフェイスはDeprecatedと書いてあるのですが、代替手段は書いてありませんでした。
Spreadsheet Document Controller - Apache OpenOffice Wiki
デベロッパーガイドにも代替手段は書いてありませんでしたが、ビューが分割か固定されているときはXIndexAccessインターフェイスで最大4つまでの枠にアクセスできると書いてあり、コントローラにインデックスアクセスがあることがわかりました。
コントローラのインデックス0のサービスとインターフェイス一覧
コントローラのインデックス0の枠は常に存在するはずなのでそのサービスとインターフェイス一覧を調べました。
def macro(): ctx = XSCRIPTCONTEXT.getComponentContext() # コンポーネントコンテクストの取得。 smgr = ctx.getServiceManager() # サービスマネージャーの取得。 tcu = smgr.createInstanceWithContext("pq.Tcu", ctx) # サービス名か実装名でインスタンス化。 doc = XSCRIPTCONTEXT.getDocument() controller = doc.getCurrentController() # コントローラの取得。 tcu.wtree(controller[0])
object
├─.sheet.SpreadsheetViewPane
│ ├─.sheet.XCellRangeReferrer
│ │ .table.XCellRange getReferredCells()
│ ├─.sheet.XViewPane
│ │ long getFirstVisibleColumn()
│ │ long getFirstVisibleRow()
│ │ .table.CellRangeAddress getVisibleRange()
│ │ void setFirstVisibleColumn( [in] long nFirstVisibleColumn)
│ │ void setFirstVisibleRow( [in] long nFirstVisibleRow)
│ └─.view.XControlAccess
│ .awt.XControl getControl( [in] .awt.XControlModel xModel
│ ) raises ( .container.NoSuchElementException)
└─.view.XFormLayerAccess
.form.runtime.XFormController getFormController( [in] .form.XForm Form)
boolean isFormDesignMode()
void setFormDesignMode( [in] boolean DesignMode
├─.sheet.SpreadsheetViewPane
│ ├─.sheet.XCellRangeReferrer
│ │ .table.XCellRange getReferredCells()
│ ├─.sheet.XViewPane
│ │ long getFirstVisibleColumn()
│ │ long getFirstVisibleRow()
│ │ .table.CellRangeAddress getVisibleRange()
│ │ void setFirstVisibleColumn( [in] long nFirstVisibleColumn)
│ │ void setFirstVisibleRow( [in] long nFirstVisibleRow)
│ └─.view.XControlAccess
│ .awt.XControl getControl( [in] .awt.XControlModel xModel
│ ) raises ( .container.NoSuchElementException)
└─.view.XFormLayerAccess
.form.runtime.XFormController getFormController( [in] .form.XForm Form)
boolean isFormDesignMode()
void setFormDesignMode( [in] boolean DesignMode
Calc(19)Calcコントローラのサービスとインターフェイス一覧と比べるとサポートしているサービスとインターフェイスはかなり少ないです。
分割した各枠のセル範囲を取得するマクロ
def macro(documentevent=None): # 引数は文書のイベント駆動用。 doc = XSCRIPTCONTEXT.getDocument() # 現在開いているドキュメントを取得。 controller = doc.getCurrentController() # コントローラの取得。 for i, subcontroller in enumerate(controller): # インデックスも取得する。 cellrangeaddress = subcontroller.getVisibleRange() # 見えているセル範囲のアドレスを取得。 cellrange = subcontroller.getReferredCells() # 見えているセル範囲を取得。 cellrange[0, 0].setString("Index: {}\nStartRow: {}, EndRow: {}\nStartColumn: {}, EndColumn: {}"\ .format(i, cellrangeaddress.StartRow, cellrangeaddress.EndRow, cellrangeaddress.StartColumn, cellrangeaddress.EndColumn)) # 各コントローラーのセル範囲の左上端セルにセル範囲アドレスを代入する。 cellrange[0, 0].getRows()[0].setPropertyValue("OptimalHeight", True) g_exportedScripts = macro, #マクロセレクターに限定表示させる関数をタプルで指定。getReferredCells()で枠内の表示されているセル範囲が返ってくるのでそこからセル範囲アドレスも取得できるのですが、このマクロではgetVisibleRange()でセル範囲アドレスを取得しています。
D10セルを選択して表示→ウィンドウの分割、としたあとに左下の枠の開始列をBに開始行を16に変更し、上記のマクロを実行した結果です。
各枠の左上端のセルにその枠のインデックスとセル範囲アドレスのアトリビュートを表示し、その行の高さを最適化しています。
枠のインデックスは左上の0から始まり左下の枠が1、右上が2、右下が3になっていました。
各枠のセル範囲アドレスはそれぞれの枠内で画面に表示されているセル範囲に一致するのですが、左下の枠のアドレスを取得した後に行の高さを最適化しているので、右下の枠のEndRowよりずれています。
D10セルを選択して表示→セルの固定→行と列の固定、としたシートでこのマクロを実行した結果です。
セルの固定をしたときはスクロールできるのは右下の枠だけなので、インデックス0の枠のEndRow+1とEndColumn+1がセルの固定をしたときの行と列とわかります。
ウィンドウの分割のときは左上の枠の行数と列数から分割をしたときの選択セルを取得できます。
セルの固定はXViewFreezableインターフェイスのfreezeAtPosition()メソッドでできますが、ウィンドウの分割はDeprecatedになっているXViewSplitableインターフェイスのsplitAtPosition()メソッドに代わる方法はディスパッチコマンドを使う方法以外は思いつきませんでした。
セルの固定をすると左上の枠はスクロールできないのでその枠より上の行と左の列のセルは表示できなくなります。
(2018.5.26追記。 この方法は必ずしもうまくいかないようで、LibreOffice5.4ではマクロでシートを切り替えた時に切り替えた先のシートではうまく境界の列インデックスが取得できませんでした。)
0 件のコメント:
コメントを投稿