- - PR -
Excel:自分で定義したFunctionを使用しているセルの自動再計算
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-01-07 11:03
Excel 2000でアドインを作成していますが、少し困ったことになってます。
自分で定義したFunctionを使用しているセルを自動的に再計算させようとしています。 アドインでやりたいことは以下のようなことです。 標準モジュール:
ワークシートのセルに書く計算式:
このような状態でMyTestが計算式に使用されているセルを自動的に再計算させたいのです。再計算のタイミングはCOM接続されたDLL(VC++で作成)で決定します。 考えた方法としては
などです。 1.の方法ならアドインの作り方は簡単ですが、MyTestを使うユーザは常に余分なセル(この例ではA1)を意識する必要があり、あまりスマートな書式には見えません。 2.の方法ならMyTestを使うユーザは純粋に自分が必要な情報だけを引数に指定すればいいので見た目はすっきりするのですが、パフォーマンス上の問題があります。 何かもっとスマートかつパフォーマンス上もさほど気にしないで済むような方法はないものでしょうか? セルの数が増えればたとえ1.の方法でもパフォーマンスが落ちるのは必至ですが、この場合は止むを得ないと考えてます。 [ メッセージ編集済み 編集者: Take-C 編集日時 2008-01-07 11:04 ] [ メッセージ編集済み 編集者: Take-C 編集日時 2008-01-07 11:05 ] | ||||||||||||
|
投稿日時: 2008-01-07 12:23
以下は、あまりプログラマーとしての回答ではなく、日頃 Excel を使っているエンドユーザーとしての回答になります。 1. は (MyTest(その他の引数) + セルA1) でも良いかもしれません。ダミーの引数にしなくても良いという程度です。数値か文字列かを意識しないといけないかもしれませんが。 ほかに思いつくのは、Excel は DDE クライアントですので、DDE サーバーを作ってそれと通信するようにすれば、セルを書き換えるのではなく、DDE で値を更新するやりかたでもできます。 もっとも、そんなややこしいことをしても、 (MyTest(その他の引数) + DDE用のパラメーター) となり、セルがDDE用のパラメーターに替わるだけで、それほど嬉しくはありませんが。 | ||||||||||||
|
投稿日時: 2008-01-07 15:42
unibonさん、ありがとうございます。
なるほど、そういう方法もありますね。ただ、やはり本来の処理とは関係ないセルを意識する必要性が残ってしまいますね。
DLLではなくDDEサーバを使って =MyAPP|MyTest!その他の引数 というような方法も考えたのですが、DDEはMicrosoft自身もあまり推奨していないようです。 http://office.microsoft.com/ja-jp/excel/HP030662101041.aspx それならOLEで、とも思ったのですが、セルの中の計算式からOLEリンクを参照する方法が見当たりません。 やはり最初の要求そのものに無理があるのでしょうかね。 | ||||||||||||
|
投稿日時: 2008-01-07 15:55
MyTest関数を使用しているRangeを取得してから、
一括で再計算させる手順はどうでしょうか。
Range取得を事前に済ませておけるなら、もう少し高速化できますし。 | ||||||||||||
|
投稿日時: 2008-01-07 17:27
Volatile メソッドをユーザー定義関数内で使うのでは目的に合わないのですか?
| ||||||||||||
|
投稿日時: 2008-01-07 17:56
こあらさん、ありがとうございます。
Excel 2000のRangeには残念ながらDirtyメソッドはないようです。 やるとすればこんな感じでしょうか。
実際には上記の処理をDLLからCOMを通じて行うことになります。
Range取得を事前にしておきたいのはやまやまなのですが、いつどのセルにユーザがこの関数をセルに書くかはまったく不明なため、毎回計算式があるセルを取得することになりそうです。 「そんな要求を満たすことは不可能です」とわかる資料があればいいんですが。
キナサイさん、ありがとうございます。 なんと、こんなメソッドがあったのですね。 再計算させるタイミングはユーザではなく別アプリケーションから制御したいので、そのタイミングの制御が難しそうですが、ちょっと調べてみます。 | ||||||||||||
|
投稿日時: 2008-01-07 18:08
よく読んでないんですが、MyTest()の中でActiveSheet.NameやActiveCell.Addressなどの情報をCollectionなどに登録し、更新するタイミングでそれらがまだセルに設定されているかどうかを確認しながら更新していくというのはどうでしょう?(セルに設定されていなかったらCollectionから除去する)
| ||||||||||||
|
投稿日時: 2008-01-07 18:30
大変失礼致しました。新しいメソッドだったのですね。 Excel2000では Application.CalculateFull で誤魔化すしかないかもしれません。 シートの状態にもよりますが、個々セルごとに代入するよりは速そうです。 |