WEBクエリを使用して為替情報を一分毎に取得しています。
問題はこのWEBクエリがフリーズする頻度が高いです。
24時間連続稼動で2~7日の間にフリーズが起こります。
フリーズの症状としてはExcelのみフリーズ(砂時計状態)でWindowsXPは他の操作が可能です。
帰宅後、発見時にExcelを再復帰させていますが数時間のロスになってしまします。
この場合に以下の回答をお願いします。
1、VBA-Aが「フリーズをしている」と認識するにはどう言った方法があるでしょうか?
2、VBA-Aがフリーズした場合、VBA-Aを強制終了させ再復帰させる事が可能でしょうか?
今、考えてる方法として上記の一連の動作管理をVBA-Bで行い
VBA-Aがフリーズした事を認識した時点で強制再復帰のパルスを送りたいと考えています。
ただこの場合のVBA-AとB間の連絡方法はどんな方法があるかが分からないです。
Windows同士でしたらPingやSoket等の方法があると思いますがExcel同士では何が適切な関数かも分からないです。
但しインターネット環境の事もあるでしょうが「OSやExcel自体が連続運転に向かない」という回答は避けてください。
以上、宜しくご教授お願いします。
まずフリーズと一言で言っても色々なパターンがありますので一概に言えません。Excel内のどのモジュールでどのような問題に陥っているのかがわからないと「フリーズしている」という外的事象だけで対処方法を出すことは難しいと思います。
ただし質問文から判断すると「砂時計が出ている」ということですので、Excelそのものが応答しなくなっていると思われます。(例えばウィンドウ右上の×ボタンも反応しないのではないでしょうか)
その場合、フリーズの要因を取り除くか、強制終了するしかありません。フリーズの要因を取り除けばVBAの動作が再開する可能性はありますが、フリーズの要因がわかっていないので取り除くことはできません。つまり、強制終了しか残されていません。
一般的にプログラム(VBAではなくて、Windowsのネイティブアプリケーション)から、あるプログラムがフリーズしているかどうかを判断するには、ウィンドウメッセージを送って反応が返ってくるかどうかで判定します。この処理はVBAでもDeclareを使ってWin32 APIを駆使すれば呼び出すことは可能ですが、C言語やWin32 APIの知識が必要となりますのでVBAのみの知識では実現できません。
またフリーズしていることがわかったとしても強制終了して、再立ち上げするくらいしか対処方法はありません。
一応質問に答えておきます。
1、VBA-Aが「フリーズをしている」と認識するにはどう言った方法があるでしょうか?
VBAがフリーズしているかどうかを判定することは不可能です。VBAが動作しているExcelが応答するかどうかはWin32 APIを使えば判定は可能です。
2、VBA-Aがフリーズした場合、VBA-Aを強制終了させ再復帰させる事が可能でしょうか?
フリーズしているアプリケーションに対して「何か再復帰のパルスを送って復帰させる」ようなことは不可能です。アプリケーションを強制終了して、再度実行しなおす他ありません。
厳密ではありませんが、Excelだけでできる代替方法としては、次のような仕組みが考えられます。
VBA-Aでは、一分ごとにWEBクエリを実行した後、毎回自分自身(xlsファイル)を保存するようにします。そうすることで、xlsファイルのタイムスタンプが更新されます。
VBA-BからVBA-Aのxlsファイルのタイムスタンプを監視して、長時間更新されないようならVBA-Aがフリーズしている可能性があるので、VBA-BからVBA-AのExcelウィンドウの強制終了をかけて、再度VBA-Aのxlsファイルをオープンすることは可能と思います。VBA-Aはxlsファイルのオープン時自動実行にしておけばよいでしょう。
urlはダミー
フリーズしているEXCELにパルス(?)を認識させることは無理でしょう。
EXCEL だけにこだわらなければ、下記のような方法でどうでしょうか。
(1)EXCEL A を起動後に自動で処理を開始するよう、Workbook_Open 等で設定をしておく(設定済みなら不要)
ここで定期的(例えば10分毎)にある特定のファイルC(C:\tmp\watchDog.txt)を作成する。
EXCEL 側のマクロはこんな感じ
Private Sub Workbook_Open() OnTimeSet '-- その他の処理 End Sub : : Sub OnTimeSet() Const WD_FILE = "C:\tmp\watchDog.txt" Dim ff As Integer If Dir( WD_FILE ) = "" Then ff= FreeFile Open WD_FILE For Output As #ff Print #ff, Now Close #ff End If Application.OnTime EarliestTime:=Now + TimeValue("00:10:00") , Procedure:="OnTimeSet" End Sub
http://www.moug.net/tech/exvba/0130013.htm
(2)タスクスケジューラで、スクリプトAを20分ごとにスケジュールする。
http://www.atmarkit.co.jp/fwin2k/win2ktips/335tasksched/tasksche...
タスクスケジューラで起動するスクリプトA(VBS)は下記のような感じ。
Const WD_FILE = "C:\tmp\watchDog.txt" Const XL_FILE = "C:\myProg.xls" Dim fso Set fso = CreateObject("Scripting.FileSystemObject") '--- ファイルがあれば、削除して何もしない If fso.fileExists( WD_FILE ) Then fso.deleteFile WD_FILE WScript.Quit End If '--- ファイルがなければ、EXCEL をいったん終了して再起動 Dim objShell Set objShell = CreateObject("WScript.Shell") objShell.Run "taskkill.exe /F /IM excel.exe",0 , True WScript.Sleep 1000 objShell.Run "excel.exe " & XL_FILE |vb|< http://itpro.nikkeibp.co.jp/free/NT/WinKeyWord/20040805/1/taskkill.shtml http://www.sophia-it.com/content/watchdog
回答ありがとう御座います。
ほぉ、こんな方法もあるんですね。
参考にさせて頂きます。
回答ありがとう御座います。
なるほど、タイムスタンプの更新方式ですね、参考になります。
Excelは完全に内部で停止している感じです、ですのでログを取る事さえ出来ないのです。
問題はフリーズしているExcelに強制終了がかけられるかですね。
引き続き、回答お待ちしています。