Calcでボタンで引数を渡したい

たとえば次のようなマクロがあるときに、

Sub showMsg(s)
	Msgbox s
End Sub

ボタンAを押したら、「ボタンA」を引数で渡して、
ボタンBを押したら、「ボタンB」を引数で渡す。

ということがやりたいのです。この引数を設定する方法を教えて下さい。

Excelだと、ボタンにマクロを登録するときに引数込みで書けばいけますが、
Calcの場合、ボタンにマクロを登録するときに、引数が入力できません。(コントロールのプロパティのイベントのところで、カーソルは入るけれど、入力は受け付けない。)

こちらの環境は、macOS Catalina 10.15.4
LibreOffice バージョン: 6.4.3.2
です。

よろしくお願いします。

うーん、一応できる事はできる。「実行時」に実行されるのは単なるActionListenerのメソッドだし。以下のメソッドを両方のボタンの「実行時」に設定したりすれば。

Private Sub Buttons_actionPerformed(rEvent As com.sun.star.awt.ActionEvent)
    Msgbox(Event.Source.Model.Name)
End Sub

なるほど、こうするとボタンの名前が渡るわけですね。ということは逆に言うと、渡したい引数を名前に仕込んででおけば、何でもできますね。この発想は、全くなかったです。目からうろこがフィーバー状態です。本当にありがとうございます。

関数名は本当にやろうとしていたことの名残。
なお、この手順の場合、コントロールのプロパティのイベントタブには多分登場しない。
厳密には結構面倒くさい仕組みなんだよね、あれ

Option Explicit
Public Sub Main()
    Dim formModel As Object
    Dim buttonModel As Object
    Dim buttoncontrol As Object
    formModel = ThisComponent.DrawPage.Forms.getByIndex(0)
    REM 名前は変更しています。
    buttonModel = formModel.getByName("PushButton1")
    buttoncontrol = ThisComponent.getCurrentController().getControl(buttonModel)
    buttoncontrol.addActionListener(CreateUnoListener("Buttons_","com.sun.star.awt.XActionListener"))
    REM 名前は変更しています。
    REM 変数は使いまわしました。
    buttonModel = formModel.getByName("PushButton2")
    buttoncontrol = ThisComponent.getCurrentController().getControl(y)
    buttoncontrol.addActionListener(CreateUnoListener("Buttons_","com.sun.star.awt.XActionListener"))
End Sub
Private Sub Buttons_actionPerformed(rEvent As com.sun.star.awt.ActionEvent)
    Msgbox(rEvent.Source.Model.Name)
End Sub

formModel等の型名を調べるのが面倒だったので断念。(っていうかこれWriterでしか動作してなかった。これからCalcについて調べます。

→調べました。

ThisComponent.DrawPage => ThisComponent.getSheets().getByIndex(0).DrawPageで行けそうです。

また、getControl(y)はgetControl(buttonModel)の間違いです。実験時に使っていた変数が残ってました。

それから、このコードでリスナを追加した場合、削除しないとファイルを閉じる時にエラーが出るようなのでremoveActionListenerするため、Global変数に保存しておくほうがいいようです。createUnoListenerをニ回も実行する必要はありませんでしたね。

REM  *****  BASIC  *****
Option Explicit

Global actionListener As Object

Public Sub Main()
    REM (略)
    actionListener = CreateUnoListener("Buttons_","com.sun.star.awt.XActionListener")
    buttoncontrol.addActionListener(actionListener)
    REM (略)
End Sub

Public Sub EndExperiment()
    REM (略)
    buttoncontrol.removeActionListener(actionListener)
    REM (略)
End Sub

GlobalとPublicの違いについては再度勉強してきます。

https://opengrok.libreoffice.org/xref/core/basic/source/comp/dim.cxx?r=8b0a6949#211

https://opengrok.libreoffice.org/xref/core/basic/source/comp/dim.cxx?r=8b0a6949#220

なるほど。>GlobalとPublicの違い

ダイアログのボタンではなく、シートに配置するプッシュ・ボタンのことであれば、
他にハイパーリンクのURLパラメータに引数文字列を追記する方法も有ります

マクロURLの後ろに &a=1 のように引数を追記すると、実行時にマクロ側の引数は URLの全文字列を受け取るので、引数部分を分離して利用します


UIからシートに配置するボタンにハイパーリンクを設定する方法で私が知っているのは3つ

  1. ボタン・コントロールでは、ハイパーリンクの設定が見当たりませんが、右クリックメニューの コントロールのプロパティ全般タブアクション「ドキュメントまたはHTMLを開く」にすると直下のURL項が入力可能になり、そこに記入します

  2. ハイパーリンク [ Ctrl + k ] で出てくるダイアログの URL に記入し 詳細設定フォーム「ボタン」に設定して OK すると、選択中のセルにプッシュ・ボタンが作られます

  3. ボタンを選択して [2.] の操作をする


ハイパーリンク関数 からも同様の方法で引数を渡すことができます
関数の引数は文字列なので、実行する関数名、引数を自在に変更することが容易です


Ask_52616_ボタン引数.ods (12.0 KB)


参考

[Solved] Calc basic macro to add a button to a cell (Dec 26, 2011)

Calc - Macro to change date and list order ('17年10月)

[Calc] How to start a macro with user-specified parameters? ('18 年 4月)

参考2

マクロでセルのURL文字列のハイパーリンク・ボタンを作る
Producing a hyperlink button in Calc ('21 年 7月)

1 Like

ドキュメントに埋め込まれたマクロを macro:// 形式で呼び出す方法は無いと思っていましたが、認識不足でした。ヘルプの記述が間違っていたようで気づくことが出来ませんでした。

Starting LibreOffice Software With Parameters
https://help.libreoffice.org/latest/ja/text/shared/guide/start_parameters.html

誤:macro:///[Library.Module.MacroName](こればアプリ側のBasicマクロを呼び出す)

正:macro://./[Library.Module.MacroName](ドキュメントに埋め込まれたマクロを呼び出す)
or
macro://[ファイル名]/[Library.Module.MacroName](既にファイルが開かれている時はこれでも可)

この記述方法はハイパーリンク(関数)でも同じ記述で動きます。

従って、ドキュメントのマクロも普通の記述で引数を渡すことが出来ます。

例)

macro://./Standard.Sample.getBtnUrl_3("abcd")

Ask_52616_ボタン引数_改1.ods (12.7 KB)


関連記事

https://bugs.documentfoundation.org/show_bug.cgi?id=150251

https://bugs.documentfoundation.org/show_bug.cgi?id=104441#c4 (2017-01-27)

2 Likes

nobuさんの Ask_52616_ボタン引数_改1.odsを手元で試しましたが、「追加 macro:// による呼び出し」では「権利がないのでオブジェクトにアクセスできません」というエラーになりました。
マクロのセキュリティは「中」です。何か環境の問題なのでしょうか?

Version: 7.4.0.2 / LibreOffice Community
Build ID: 40(Build:2)
CPU threads: 8; OS: Linux 5.18; UI render: default; VCL: gtk3
Locale: ja-JP (ja_JP.UTF-8); UI: ja-JP
Debian package version: 1:7.4.0~rc2-3
Calc: threaded
1 Like

自分の環境でドキュメントを全く関係ないフォルダにコピーして起動すると、同じようなエラーを再現できました。
おそらく、起動時にセキュリティでマクロを有効にしても、
「セキュリティ」の「信頼されたソース」、「信頼されたファイル位置」 を設定して、ドキュメント・ファイルはその中に無ければエラーになるようです。

https://help.libreoffice.org/7.2/ja/text/shared/optionen/macrosecurity_ts.html

バグでしょうか?
仕様だとすると、macro://./ 形式はたまたまハイパーリンクでも動くけど、本来はコマンドラインで使うものなのかもしれません。

2 Likes

ありがとうございます。たしかに、「信頼されたファイル位置」 にファイルのパスを設定すれば動作しました。