前の関連記事:Calc(87).uno:Copy後の選択状態の解除
マクロを埋め込んだCalcドキュメント
GridControlDialogs.ods
A列やB列の2行目以降をダブルクリックするとその位置にダイアログが出現します。
ダイアログの外をクリックするとダイアログは閉じます。
定型句を保持するダイアログ
1行目にstaticdialog3と書いてある列の2列目以降をダブルクリックすると、クリックした位置に定型句を保持するダイアログが出現します。
各項目をダブルクリックするとセルにその項目が入力されます。
右クリックするとチェックボックス付きのコンテクストメニューが出現します。
「セル入力で閉じる」にチェックをつけておくと、セルに入力後にダイアログが閉じるようになります。
「オプション表示」にチェックをつけると、項目を編集するためのコントロールが出現します。
テキストボックスに文字列を入力して「行挿入」ボタンをクリックすると、テクストボックスの文字列が項目に追加されます。
「上へ」「下へ」ボタンをクリックして項目の位置を移動できます。
「行挿入」ボタン以外はCtrlキーを押しながら選択した複数行にも対応します。
ダイアログの項目やチェックボックスの状態は、configという名前の隠しシートに保存します。
シート→シートの表示、で非表示のシートを表示することができます。
保存したデータを破棄したいときはそれぞれ対応した行を削除するか、configシートを削除します。
configシートへのアクセスにはCalc(82)名前でセルを参照するを使っています。
参照エラーのある名前はドキュメントを開いた時に削除するマクロも埋め込んであります。
入力履歴を保持するダイアログ
1行目にhistorydialog8と書いてある列の2列目以降をダブルクリックすると、クリックした位置に入力履歴を保持するダイアログが出現します。
このダイアログのテキストボックスに文字列を入力して「Enter」ボタンをクリックすると、セルにテキストボックスの文字列を代入するとともに、ダイアログの項目にその文字列をダイアログの項目に追加します。
重複した値は保持しないようにしているので、すでに存在する項目があればそれは削除されます。
項目をダブルクリックしてもセルにその項目を代入します。
テキストボックスには選択した項目の文字列が入ります。
項目を削除したいときは選択した項目を右クリックして出現するコンテクストメニューから行います。
「逐次検索」にチェックをするとテキストボックスに入力した文字列に対して逐次検索します。
テキストボックスに「a」と入力すると「a」から始まる行だけ表示されます。
「abcd」と入力するとさらに絞り込めます。
ただし、1項目のみに絞りこめたときにその行より上の行は削除しません。
この状態で「1234」を選択したときは「1234」だけに絞り込めるはずですが、そうするには「1234」の上の行を削除しないといけないので、表示される行は変化しません。
これは選択行より上の行を削除して1行だけになってしまうと、なぜかグリッドコントロール以外のコントロールが動かなくなるので、やむを得ない対応です。
ダイアログのデータの保存方法は定型句を保持するダイアログと同じです。
定型句を保持するダイアログを生成するモジュール
staticdialog3.py
このモジュールにあるの関数createDialog()で定型句を保持するダイアログを生成します。
createDialog(xscriptcontext, enhancedmouseevent, dialogtitle, defaultrows=None)xscriptcontextはXSCRIPTCONTEXT、 enhancedmouseeventはXEnhancedMouseClickHandlerのメソッドの引数、dialogtitleはダイアログのタイトルにする文字列(ダイアログのデータを保存する名前にも使用)、defaultrowsは初めてダイアログを表示するときに表示する項目のリストです。
defaultrowsはリストでもタプルでも、リストのリスト、タプルのタプルなどに対応します。
ダイアログの大きさを変化させたかったので、LibreOffice5(58)モードレスダイアログの例をPythonに翻訳する:その4の方法のうちTaskCreatorサービスでダイアログを作成しています。
linuxBeanでは問題ないのに、Windows10でだけ、ダイアログウィンドウの位置や大きさをsetPosSize()メソッドで変更する前に、setVisible(True)で表示させておかないと、位置がおかしくなることに気が付くまで苦労しました。
グリッドコントロールの項目の選択に対して発火するリスナーにはXGridSelectionListenerを使うつもりでしたが、これはXEnhancedMouseClickHandlerで代替可能なことがわかったので、XGridSelectionListenerは使っていません。
入力履歴を保持するダイアログを生成するモジュール
historydialog8.py
このモジュールにあるの関数createDialog()で入力履歴を保持するダイアログを生成します。
(2018.8.15追記。グリッドコントロールのデータをグローバル変数DATAROWSに持たして処理していますが、グローバル変数はモジュールを読み込んだ時にしか初期化していないので、同じマクロの中で複数のダイアログを使用するとグリッドコントロールの内容が交差してしまいます。なので、createDialog()の中でもグローバル変数DATAROWSを初期化したほうがよいです。)
引数はstaticdialog3.pyのときと同じです。
グリッドコントロールでは、選択している行を削除するとgetSelectedRows()でインデックスの負数が返ってくるときがありました。
グリッドの行を選択するときに負数のインデックスを渡してしまうと、Calcがクラッシュするので、負数が入っているときは何もしないようにしています。
グリッドコントロールで選択している行よりインデックスが小さい行を削除してしまうと、グリッドコントロール以外のコントロールが操作できなくなりました(LibreOffice5.4)。
行の削除方法や追加方法などいろいろ試してみましたがいい解決法はみつかりませんでした。
GridControlDialogs.odsの埋め込みマクロの仕組み
p--q/GridControlformyRs2
このリポジトリはCalc(47)埋め込みマクロのためのPyDevプロジェクトを元にしていますので、toolsフォルダ内のツールでodsファイル内のモジュールを読み書きできます。
埋め込みマクロはLibreOffice5(120)ドキュメントに埋め込んだモジュールをインポートするの方法を使って複数の埋め込みモジュールをロードしています。
└── python ├── embeddedmacro.py └── pythonpath ├── indoc │ ├── __init__.py │ ├── commons.py │ ├── dialogs.py │ ├── documentevent.py │ ├── historydialog8.py │ ├── listeners.py │ └── staticdialog3.py └── tdocimport.py埋め込みマクロフォルダ内の構造はこのようになっています。
tdocimport.pyでモジュールをロードするには__init__.pyは省略できません。
embeddedmacro.pyとtdocimport.py、listeners.pyはモジュールをロードするためのものです。
ドキュメントを開くとまずembeddedmacro.pyを起動するように、ツール→カスタマイズ、イベントで、「文書を開いた時」にこのマクロを登録してあります。
tdocimport.pyがpythonpathフォルダ以下のすべてのモジュールをロードできるようにします。
listeners.pyにはCalcドキュメントで使う可能性のあるイベントのリスナーをすべて登録してあり、イベントが発生すると、commons.pyの関数getModule()で各モジュールを呼び出しています。
シート名で割り振ることを想定しています。
getModule()で呼び出すモジュールにはリスナーのメソッドと同名の関数をイベントで駆動するコードを書いてあります(dialogs.py)
ドキュメントイベントはシート名に関係ないのでdocumentevent.pyにリスナーのメソッドと同名の関数を書いてあります。
0 件のコメント:
コメントを投稿