LibreOffice Calcでアプリケーション 基礎編

プログラミング

概要

LibreOfficeを使って、アプリケーションを作成するための基礎編です。
ちょっとしたツールを作りたいときに、便利なスキルです。
GUIツールを作りたいけど、プログラミングが苦手な人にもおすすめです。
LibreOfficeのコントロール(部品)を使ってGUIを作ります。
基本的なコントロールは、あるのでまぁまぁ簡単なことはできるかなと思います。
そもそもDatabaseアプリのBaseのフォーム画面は、Writerを使って作られています。
ただ、試してみて便利かもと思ったのは、CalcをGUIに使うと表も使えるので、
データの表示や計算もできるという事を考えると非常に便利ではないでしょうか?
BasicでもPythonでも基本的に同じなのでお好きなほうをお使いください。

※この文章を最後まで書いた後気が付いたのですがこの記事には問題ありです。
ツールバーが消えません。一旦は、マクロで消せるのですがCalcであれば別の画面のCalcで
コントロールを有効にするとその瞬間別の画面でも有効になります。
どうやらドキュメントごとに設定は保存されるようですがツールバーは、アプリケーションごとに共通の様です。
回避できる方法がありましたら、改めて解説します。

アプリケーション用のプロファイルを別に用意する方法でツールバーが消えない問題は、回避できました。
すべての設定が別の環境になるのでアプリケーションを使うとき専用の設定が用意できます。

基本的な考え方

CalcをGUIとして使うときの基本的な考え方です。
Pythonをつかって説明します。
GUIとして使うときコントロールは、使えるものが最低限はあります。
あっても問題は、無いですがツールバーやCalc用のコントロールや罫線など必要のないものは、非表示にして起きます。
セルは、必要な部分だけ使えるように設定して他は書き込み禁止にします。

メニューを使う場合は、必要のないメニューを非表示にしてアプリケーションとして使えるメニューを
追加するなどして使うと良いと思いますが検証していませんので、ご自身で試してみてください。
自分でダイアログボックスや別のシートを使うなどしてメニューを作ることもできるはずですが
今回は、基本的な部分だけを説明します。

メニューなどを隠してしまうと修正しようとしてもマクロ編集の画面すら開けなくなるので
他の画面から開くようにしておく方法も後ほど説明します。

アプリ用のプロファイルを用意する

起動時に専用のプロファイルを指定することで専用のプロファイルが使えます。

run_testcalc01.bat


@ecoh off
start "" "C:\Program Files\LibreOffice\program\soffice.exe" "c:\Users\[USER_NAME]\Desktop\TestCalc01.ods" -env:UserInstallation="file:///C:/Users/[USER_NAME]/AppData/Roaming/LibreOffice/4/my_app"

このようなスクリプトを作ると初回だけ新たなプロファイルを作ってTestCalc01.odsを起動します。
[USE_NAME]とファイル名は、環境に合わせて変更してください。
改めてAPSOをインストールし、Pythonスクリプトは必要でしたらフォルダごと新しいプロファイルにコピーすれば使えます。
あと、プロファイルのフォルダ指定が通常の”\”を使った指定ではなく”/”なので注意してください。
ただし、この方法だと一瞬ターミナルの窓がちらつきます。

他の方法としては、
run_testcalc01.py


# -*- encoding:utf-8 -*-
import subprocess

command = r'C:\Program Files\LibreOffice\program\soffice.exe'
arg1 = r'c:\Users\[USER_NAME]\Desktop\TestCalc01.ods'
arg2 = r'-env:UserInstallation=file:///C:/Users/[USER_NAME]/AppData/Roaming/LibreOffice/4/my_app'
subprocess.run([command, arg1, arg2])

このような内容のPythonスクリプトを作って、
スクリプトを右クリックして
“プログラムから開く”->”別のプログラムを選択”
で開いたダイアログから
“その他のアプリ”->”このPCで別のアプリを選択”
でファイルを選びます。
特にpyenvなどを使っていなければデフォルトのPythonフォルダから”pythonw.exe”を選んでください。
pyenv-winかんきょうであれば、例えばgrobalで3.12.5を使っているならば、
C:\Users\\.pyenv\pyenv-win\versions\3.12.5\pythonw.exeを選択してください。
これでターミナルは、表示されなくなりました。
pythonw.exeの”w”のついたものはターミナルを表示させないためのものです。

あとは、ショートカットなりを作ってアイコンなんかも変えておけば良いのでは。
アイコンはショートカットを右クリックで
“ショートカッt”タブ->”アイコンの変更”
から選択して変更できます。

ここにプロファイルに関連して少し解説してあります。
“LibreOfficeのアプリ使用中はサーバーモードが使えないを解消”

ツールバーなどの隠し方

メニューとツールバーは、マクロから非表示にすることができます。
“行列見出し”や”サイドバー”などは、”表示”メニューから非表示にできます。
Calcの”罫線”やする”ロールバー”、”シートのタブ”などは
“オプション”で”LibreOffice Calc”の”表示”から非表示にします。
マクロから非表示にする方法は、探していないので説明できませんがマクロからも
非表示にすることができるとは思います。

以下のコードでメニューとツールバーを非表示にします。

    # coding: utf-8
    from __future__ import unicode_literals
    from scriptforge import CreateScriptService
    
    def hide_controls(*args):
        ui = CreateScriptService("UI")
        bas = CreateScriptService("Basic")
        
        doc = CreateScriptService("Document", bas.ThisComponent)
        
        # 現在のコントローラーを取得
        oCurrentController = bas.ThisComponent.getCurrentController()
        
        # レイアウトマネージャーを取得
        oLayoutManager = oCurrentController.getFrame().LayoutManager
    
        # メニューを再表示に設定
        oLayoutManager.hideElement("private:resource/menubar/menubar")
        #oLayoutManager.showElement("private:resource/menubar/menubar")
        
        toolbars = doc.Toolbars()
        for toolbar in toolbars:
            #toolbarは文字列なので、オブジェクトとして取得しなおす
            obj_toolbar = doc.Toolbars(toolbar)
            obj_toolbar.Visible = False
            
        ui.Dispose()
        bas.Dispose()
        doc.Dispose()

 

oLayoutManager.hideElement(“private:resource/menubar/menubar”)
でメニューを非表示にします。

ツールバーは、doc.Toolbars()ですべてのツールバーを取得して、ひとつづつ VisibleをFalse にします。

このコードは、
”ツール”->”カスタマイズ”
で ”イベント”タブの”文章を開いたとき”に設定します。
手動で非表示するものは、以下のものです。

表示メニューから非常時にするもの

“表示”メニューから変更できるものです。
数式バー
ステータスバー
行列見出し
サイドバー

オプションから非表示にするもの

“ツール”->”オプション”にある”LibreOffice Calc”の”表示”から変更できるものです。
罫線
シートのタブ
改ページ
水平スクロールバー
垂直スクロールバー

当初、設定から変更するとほかのドキュメントにも影響があるかと思いましたが、
文章ごとに設定されるようです。

セルの設定

セルの設定は、セルの書式設定を変更することで設定します。
こちらで、後からつかうせるについては”セルの保護”のチェックを外しておきます。
“ツール”->”シートの保護”
を有効にすると、セルが保護されて先ほどチェックを外したセル以外は編集できなくなります。
ここまで作業するとこのような画面を作れます。
テスト画面なのでアプリっぽくないですが左列がコントロールでその右列に取得した値を表示しています。

メニューの再表示

特に、何も対処をしないとメニューを非表示にすると戻すことができなくなります
ショートカットなどにメニューを表示するコードを登録する方法もあるかと思います。
アプリケーションを修正したい場合に困るのでメニューをほかの画面から再表示する方法を説明します。

以下のコードでメニューを再表示にします。

    # coding: utf-8
    from __future__ import unicode_literals
    import re
    import uno
    from scriptforge import CreateScriptService
    
    def disp_menubar_by_title(*args):
        # LibreOfficeのデスクトップを取得
        desktop = XSCRIPTCONTEXT.getDesktop()
        
        # 開かれているすべてのドキュメントを取得
        components = desktop.getComponents()
        component_enum = components.createEnumeration()
        
        while component_enum.hasMoreElements():
            doc = component_enum.nextElement()
            
            # ドキュメントのタイトルで対象を判別(例: タイトルで特定)
            if re.match("^TestCalc01", doc.Title):
                # ドキュメントのコントローラーからフレームを取得
                frame = doc.getCurrentController().getFrame()
                
                # LayoutManagerを取得
                layout_manager = frame.LayoutManager
                layout_manager.showElement("private:resource/menubar/menubar")
                #layout_manager.hideElement("private:resource/menubar/menubar")
                

 

このコードは、開いているファイルの中からタイトルを指定してメニューを再表示します。
今回は”TestCalc01.ods”を開いている仮定してします。
閉じているときは、このコードは何もしません。

コントロールを使用する

コントロールを使用するときは、コントロールの名前を指定して取得します。
コントロールを選択した状態で右クリックメニューから”コントロールのプロパティ”を選択すると名前がわかります。
“シートの保護”を有効にしているとコントロールを選択できないので注意してください。
“フォームのプロパティ”と言う項目もあるのですが、これはフォーム全体のプロパティです(今回は、無関係です)。
以下は、コントロールから値を取得したり、設定するコードの例です。


        # coding: utf-8
        from __future__ import unicode_literals
        from scriptforge import CreateScriptService
        
        def Test_Script():
            doc = CreateScriptService("Document")
            form = doc.Forms('Sheet1', 'フォーム')
            
            controls = form.Controls()
            
            label1 = form.Controls('ラベルフィールド 1')
            doc.setValue('~.E5', label1.Caption)
            
            text_box1 = form.Controls('テキストボックス 1')
            doc.setValue('~.E10', text_box1.Value)
            text_box1.Value = "Hello, World!"
            
            check_box1 = form.Controls('チェックボックス 1')
            doc.setValue('~.E14', check_box1.Value)
            
            radio_button1 = form.Controls('ラジオボタン 1')
            doc.setValue('~.E18', radio_button1.Value)
            radio_button2 = form.Controls('ラジオボタン 2')
            doc.setValue('~.E20', radio_button2.Value)
            
            list_box1 = form.Controls('リストボックス 1')
            doc.setValue('~.E25', list_box1.Value)
            
            combo_box1 = form.Controls('コンボボックス 1')
            doc.setValue('~.E32', combo_box1.Value)
            
            doc.Dispose()
        

 

Formからコントロールをすべて取得して、コントロールを名前で指定して取得します。
あとは、それぞれのコントロールに対して値を取得したり、設定したりします。
“~.E18″等の”~”は、現在のシートを指定しています。
“Sheet1.E18″と同じ意味です。

まとめ

CalcをGUIとして使うときの基本的な考え方とコードの例を説明しました。
他にも、いろいろなことができると思いますが、基本的な部分だけを説明しました。
アプリケーションのGUIとしてそれらしく見えるよう必要のないものを非表示にする方法を説明しました。
メニューが非表示になるともとに戻すことができなくなるので、再表示する方法も説明しました。
コントロールを使うときの基本的なコードの例を説明しました。

以上、後はボタンを作ってそれにマクロを登録すれば思ったものがつくれると思います。

Commnts