「Web出版サイト」ベータ公開

Q&A集[?]

当サイトでのご質問の受付は終了しました

すべてのコンテンツを読み込み専用としたため、回答欄からも投稿できません

Apache OpenOffice/LibreOfficeのご質問はそれぞれのフォーラムへご投稿ください

質問コーナー

サイト内検索

分類メニュー

関連サイト


本日:1
昨日:0
総数:2098
現在:7


セルの値が変わった時のイベント

ページOpenOffice.org FAQの登録ページ
投稿者
分類
edit/refer
優先順位
edit/refer
状態
edit/refer
カテゴリー
edit/refer
投稿日2008-07-19 15:47:43 (土)
OSXP
依存するページ
バージョン
edit/refer

メッセージ

回答ページでは行末に「~」を付加する必要はありません

セルの値が変わった時のイベントをキャッチし、
そのセルの位置(行と列)と値を参照した処理がしたいのですが、
そのようなことは可能でしょうか?


ここが参考になります。

Kuma (2008-07-19 16:20:13 (土))

はにゃさんが開設されている下記サイト
http://hermione.s41.xrea.com/pukiwiki/index.php?OOobbs2%2F84
に同じような質問と回答が出ていましたのでごらんください。

上記方法でイベントリスナーを追加した後に、選択されているセルの行と列番号の取得は

Dim oSelection As Object
oSelection=ThisComponent.CurrentController.Selection
i=oSelection.CellAddress.Row '行番号の取得
j=oSelection.CellAddress.Column '列番号の取得

で出来ます。

全体像をもう少しお話くだされば、、、

Tora (2008-07-20 14:37:43 (日))

まず、全体的にどのような分野でどのような作業をなされようとしているのか、できる範囲で構いませんので、お話いただけませんでしょうか。
そして、その作業の中で、セルの値をユーザーが書き換えたときなのか、そのセルの数式などの計算結果が変化したときなのか、そして、その変化によって、その後、どのような処理を自動的に行わせたいのでしょうか。
特に、位置(行と列)を取得したいということですので、複数のセルに対して値の変化を監視しておきたいのではないかと思われますが、、、

「イベントリスナー」という基本的な機能を使っての実現は比較的容易なのですが、この場合のイベントリスナーについては、事前にマクロなどを実行してそのマクロなどの動作の中でイベントリスナーを登録する処理を行わす必要があります。

Calc ファイルを閉じると、そのイベントリスナーの登録は失われますので、Calc ファイルを開いた後、その作業を行う前に、あらかじめ一度、イベントリスナーを登録しなくてはなりません。Calc ファイルを開いた直後にマクロを起動させることは、「ツール」「カスタマイズ」の「イベント」タブで設定できます。

全体的な要求仕様がある程度わかれば、より的確なお答えをいただけるかもしれません。

なぜなら、以下のような、便利そうな機能は、今のところ Calc には実装されていないようですので。どうしても、何かしらの工夫をして実装する必要があるかと思います。
1. 一つのセルもしくは複数のセルを選択する
2. 「○○」メニューの「△△」を選択し、
3. イベントの種類として、「セルの値か変化したとき」を選択
4. そのイベントが発生したときに動作させるマクロを選択

その工夫においてはさまざまな方法やアイデアがあると思います。その方法やアイデアの中から要求仕様に沿った工夫を選んで実装すればよいのではないかと思います。

ご返事ありがとうございます

(2008-07-20 15:48:56 (日))

Kumaさん、ありがとうございます。
リンクの記事の内容を使用すれば、目的が達成しそうです。

Toraさん 自分が使いやすい機能をそなえた家計簿を作ろうとしています。
キーボードからの入力で、セルの値が変更された時、その行(費目、収入、支出など)と入力された値により、行を挿入したり、残高計算をしたりしたかったのです。

な〜るほど。

Tora (2008-07-20 21:19:10 (日))

そうですか。家計簿ですか。ありがとうございます。

でしたら、、、本題からはそれますが、
・入金伝票、出金伝票、振替伝票
もしくは
・仕分け伝票
のシートもしくはダイアログをあらかじめ用意しておいて、そこに貼り付けておいたボタンが押されることを契機にして、行の挿入や数式の設定、などを行うという方法でもよいかと感じました。

セルの値が変化した契機ですと、つまりは、セルの内容を編集し最後にリターンキーを押して確定すると何かしらの動作が始まるわけですよね。ってことは、そのセルに誤った数値を入力してしまっていたことに気が付いて、後からそのセルの数値を修正すると、またそのような動作が動いてしまいますよね。そんなこんなでてんやわんやになってしまいそうな気がちょいといたします。

とはいえ、まあ、やり方はいくらでもありますし。ご自身が楽しめる方法でやってみてくださいまし。陰ながら応援いたします。

サンプルプログラム

Tora (2008-07-20 22:40:38 (日))

試しに、少し作ってみました。

リスナーの登録。一回だけ実行します。二回実行しちゃうと、イベントハンドラが二回呼びだされるようになってしまいます。

Sub SetUp
        oDoc = ThisComponent
        oSheet = oDoc.getCurrentController.getActiveSheet()
        'oSheet = oDoc.getSheets().getByIndex(0)

        ' http://api.openoffice.org/docs/common/ref/com/sun/star/util/XModifyListener.html
        oListener = CreateUnoListener( "aaa_", "com.sun.star.util.XModifyListener")
        oRange = oSheet.getCellRangeByName("A1:A65536")
        oRange.addModifyListener(oListener)

        oListener = CreateUnoListener( "bbb_", "com.sun.star.util.XModifyListener")
        oRange = oSheet.getColumns().getByName("B")
        oRange.addModifyListener(oListener)

        oListener = CreateUnoListener( "ccc_", "com.sun.star.util.XModifyListener")
        oRange = oSheet.getColumns().getByName("C")
        For y = 0 To 9
                oCell = oRange.getCellByPosition(0, y)
                oCell.addModifyListener(oListener)
        Next y

'       oSheet.addModifyListener(oListener)
End Sub


イベントハンドラ。サブルーチン名は、CreateUnoListener で指定した接頭辞にイベント名を追加した名前にします。
セル範囲に対してイベントハンドラを登録すると、パラメータとしてはそのセル範囲が渡されてくるようです。

Sub aaa_modified(oEvent)
        oRange = oEvent.Source
        oSheet = oEvent.Source.getSpreadsheet()
        sAbsoluteName = oEvent.Source.AbsoluteName
        Print sAbsoluteName
End Sub

Sub bbb_modified(oEvent)
        aaa_modified(oEvent)
End Sub


セル一つずつにイベントハンドラを登録しておくと、パラメータにはその一つのセルを指し示すセル範囲が渡されてくるようです。

Sub ccc_modified(oEvent)
        oRange = oEvent.Source
        aRangeAddress = oRange.getRangeAddress()
        nStartColumn = aRangeAddress.StartColumn
        nStarRow = aRangeAddress.StartRow
        oCell = oRange.getCellByPosition(0, 0)
        sString = oCell.getString()
        nValue = oCell.getValue()
        sAbsoluteName = oRange.AbsoluteName
        Print sAbsoluteName, nStartColumn, nStarRow, sString, nValue
End Sub


カレントセレクションでセルの位置を取得する方法では、そのセルに手打ちした場合にはよいのですが、そのセルの内容が数式などの場合で他のセルの値の変更などを契機にしてそのセルの値が変化した場合には、セレクションで取得しようとすると、その他のセルを指し示してしまうので、ちょっとだけいまいちかなぁ。とも思います。
ただ、セル一つずつにイベントハンドラを登録するのは面倒ですから、手打ちするセルだけに限定するとして、例えば、シートや大きなセル範囲に対してイベントハンドラを登録しておき、そのイベントが発生したセルの位置の取得には、Kuma さんの方法でのセレクションによる取得方法が簡単な気もいたします。

ありがとうございました

(2008-07-21 12:50:58 (月))

今までは選択中のセルが変わった時に、一つ前のセルの位置を参照するという、バグが潜んでそうな処理を代用しようと思っていましたが、アドバイスのおかげで理想とする処理ができました。

Toraさんの言うとおり、まだ誤った入力やアンドゥ、セルの内容の削除など、対処しなければならない問題が多々ありますが、気長に試行錯誤していきます。

Kumaさん、Toraさん、本当にありがとうございました。m(_ _)mペコリ

お名前:
題名: