質問: dateadd("s", 20, act時刻 ) application.ontime act時刻 , "next-job", 待ち時間 このタイマーが不正確(動作したりしなかったり)で 上の式は 2分待ちですが 1分以下だと 100%起動せず、 1分40秒以上でどうやら・・・ で、タイマー以外で シートにデータ送り込むvba(15分毎のタイマー)の続きに 計算完了、もしくは、セル式の仕事を止めないで、セル式計算完了を まって、”next-job” の 仕事をさせたいのですが セル式の仕事を止めない時間稼ぎは無いでしょうか
回答: (1/2) こんにちは。お邪魔します。 すみませんが、長くなるので連投します。 ニーズを正確に理解出来ている訳ではないので、それぞれのパーツの話、、、です。 > で、時間を稼ぎたいのですが、 > 今は、タイマーで > act時刻 = now > act時刻 = dateadd("n", 2, act時刻 ) > 待ち時間 = dateadd("s", 20, act時刻 ) > application.ontime act時刻 , "next-job", 待ち時間 > このタイマーが不正確(動作したりしなかったり)で 上の式は 2分待ちですが 1分以下だと 100%起動せず、 > 1分40秒以上でどうやら・・・ 本題とは関係ないですが、ontime メソッドの話から。 考え方として、 ×| earliesttime | ★ | latesttime |× earliesttime と latesttime の間★の期間に、【タイミング】が合えば、procedureは実行されます。 i)「ontime メソッドを実行したプロシージャ」 を抜け(の処理が終り)、 ii)「ontime メソッドを実行したプロシージャ、を呼び出した大元を含む実行中のすべてプロシージャ」 を抜け(の処理が終り)、 iii)「他に実行されるべきアプリケーションのタスク」 の処理が済んだ後 この【タイミング】が★の期間内に収まっていれば、procedureが実行されます。 ですから、earliesttimeを「早め」に設定し、latesttime「遅め」に設定し、★の期間を「長く」取った方が、 procedureは実行され易い、ということになります。 そういう意味では application.ontime now, "proc", dateadd("n", 20, now) 「今、から、20分後、まで」みたいに書いておけば、【タイミング】が来次第、procedureは実行されます。 しかし、今回の課題の意味からすると、引数latesttimeは指定しないで、 application.ontime now, "proc" のようなことがなさりたいのではないでしょうか? 引数latesttimeの意味、としては、指定した時刻を過ぎたら、procedureを実行しない、です。 もし、この点で不明瞭なのでしたら、今一度、vbaのヘルプ等で確認してみて下さい・ procedureが実行可能になる【タイミング】について補足しますが、 例えば、activexのコマンドボタンで呼び出すような場合、 1: コマンドボタン押下げ 2: private sub commandbutton1_click() 3: subproc 8: end sub 4: sub subproc() 5: application.ontime now, "proc" 6: 時間の掛かる処理 7: end sub 9:コマンドボタンの押下げ表示を元に戻す既定の処理 10:ontime メソッドで設定したprocedureが実行可能になる 11: sub proc() 12: 処理 13: end sub のような順番に処理されることになります。 直接的には、この順番を替えたり、割り込んだりすることは出来ません。 また、上の順番の中で8:9:を4:より前に済ませておく必要があるような場面など ある程度処理の順番を操作したい場合に、 有効な方法として用意されているのがontime メソッドでもあり、 この例では、3:の呼び出し部分をontime メソッドに書き換えるような使い方 が、重要度の高いontime メソッドの代表的な使用例でもあります。 たぶん、今回の課題は直接的にはontime メソッドとは無縁だと思います。 (5:6:の順が逆になるように書くことはあると思いますが、、、。) ただ、処理の流れを時系列で把握することは重要ですから、 概念提示という意味では、比較的解り易い例だったと思います。 どのタイミングで end sub を通るのか、ぐらいは把握していないと書けないものも多いですしね。 > シートにデータ送り込むvba(15分毎のタイマー)の続きに > 計算完了、もしくは、セル式の仕事を止めないで、 > セル式計算完了を まって、”next-job” の 仕事をさせたいのですが > セル式の計算 これって「ワークシート(セル範囲)の再計算」のことでいいしょうか? > セル式の仕事を止めない時間稼ぎは無いでしょうか "セルの仕事を止め"る、とは、再計算を中断または終了させる?という意味に読めますけど、 何故そんなことが問題になるのか私には理解できないので教えて頂けませんか。 例えば、セルa1の値を変更(追加)するとして、 値を入力し、enterキーを押しても、 直接・間接にa1を参照先に持つワークシート上のすべての再計算が終了するまで、 a1セルは確定しませんよね。 vbaでも同じで、 cells(1, 1) = "hoge" に追従する再計算が終了するまでは次の行の処理に進めません。 なので、次の行を実行する時には、前の行の処理に連動した再計算は終了しているのでは? これが普通で、それ以外は特殊、というのが、これまでの私の常識でしたので、 何か自信無くしそうですが、少し補足説明を戴けたら助かります。 sleep関数を使っていることも気になっているのですが、 再計算を非同期で実行させるような状況なのでしょうか? 私はマルチスレッドの再計算関連に詳しくないので、私が知らない何か、なのでしょうけれども、、、。 不躾ながら、 application.calculationstate が使える、というのも、私の理解の外ですが、 それなら、application_aftercalculate イベントを使って、 vbaの処理に割り込ませることが有効なケースもあろうかと。 これは本題に近い話だと思いますが、、、。 /// thisworkbook モジュール option explicit private withevents xlapp as application private sub workbook_open() set xlapp = application end sub private sub xlapp_aftercalculate() doevents end sub ///(workbook_open()を(が)実行すれ(されれ)ばxlapp_aftercalculate()が有効に) 仮に、doeventsだけを処理させていますが、 これは再計算時に、ひとつの参照チェーン毎に計算が終了する度に発生するイベントですので、 "セル式の仕事を止めない時間稼ぎ"という言葉の指す意味合いによっては有効な手段かも、です。 (再計算に掛かる時間が長過ぎて、pcがスリープしちゃうとか?) 実際には、publicなフラグ変数を用意しておいて、セル値の変更処理の度に フラグ=n → セル値変更 → 再計算 → _aftercalculate() → フラグ>0ならば、n番めの再計算終了と判断して 必要な処理 → フラグ=0 のようにしてみれば使い道は色々ありそうですけれど。 フラグ = n cells(1, 1) = "hoge" ↓ 再計算 ↓ ←ここに_aftercalculate()が割り込みます。 フラグ = n + 1 次の処理 (次の投稿に続きます) 参考url:http://msdn.microsoft.com/ja-jp/library/office/ff840621(v=office.15).aspx