VBAの話。…最近、Webスクレイピングの手法を用いてHPから情報取得するマクロを作成していて思っていたんですけど、
Webスクレイピングは比較的長い間をかけて、プログラムを動かすことも多いから、VBAだとその間作り方によっては他の作業、
特にテキストエディタ等への文字入力へのキーレスポンスが非常に悪くなることも多いんですよね…orz。これはマクロを実行している間forなどでループ処理が入ると、
その間はCPUの制御権が完全にアプリケーション側(この場合はEXCEL等のMicrosoft Office)にいってしまうことが原因だと思うのですが。もっとも、ループ処理の場合はこまめにDoEvents関数をループ内に入れることでこの問題もある程度解決はできるんですけど。
…ただこれ、よく考えると他のケースでも割と当てはまること多いんですよね。
例えばWindowsAPIで提供されているSleep関数を用いて一定の待機時間を設ける処理を入れているところとか。
このSleep関数も関数が実行され指定した時間全体の処理が止まっている間、OSに制御権はないから、
↑のようにやっぱり文字入力は全然受け付けてくれない…orz。それに先に述べたループ処理と違って、VBA内で【何等かの処置】を施して、
強引に文字入力を受け付けさせるというようなこともできない。…でも、VBAでWebスクレイピングするのであれば、
HPへのアクセス等で、その都度一定の待機時間を設けるのであれば、正直お手軽に待機時間を作り出せるWinAPIのSleep関数が使い勝手が良いことも事実でして(-_-;。
…でもよくよく考えてみれば、WinAPIのSleep関数と同じようなことをする、それっぽい関数だったら結構簡単なロジックで作れてしまうのではないか?-。
と、そんな思い付きから、↓のようなそれっぽい関数を作ってみました(笑)。
もっとも、言語を問わずある程度プログラミングのコードが記述できる人だったら、↓ぐらいのものはささっと作れそうな気はしますけど(-_-;。
…しかもこれを書いていてさっき気づいたのですが、日付をまたいで↓の関数を実行すると、実質無限ループになってしまうような…orz。
…ということでこの分野、まだまだ研究が足りないようで…。
'OSへの制御権をなるべく残すために用意した疑似Sleep関数(あくまで正確に指定した時間処理を止めるわけではない…)
'引数:tmp/設定する待機時間(ミリ秒)
Public Sub SleepEx(ByVal tmp As Double)
tmp = tmp / 1000
Dim baseTime As Double, curTime As Double
baseTime = Timer
Do
curTime = Timer
DoEvents
Loop Until baseTime + tmp <= curTime
End Sub
Webスクレイピングは比較的長い間をかけて、プログラムを動かすことも多いから、VBAだとその間作り方によっては他の作業、
特にテキストエディタ等への文字入力へのキーレスポンスが非常に悪くなることも多いんですよね…orz。これはマクロを実行している間forなどでループ処理が入ると、
その間はCPUの制御権が完全にアプリケーション側(この場合はEXCEL等のMicrosoft Office)にいってしまうことが原因だと思うのですが。もっとも、ループ処理の場合はこまめにDoEvents関数をループ内に入れることでこの問題もある程度解決はできるんですけど。
…ただこれ、よく考えると他のケースでも割と当てはまること多いんですよね。
例えばWindowsAPIで提供されているSleep関数を用いて一定の待機時間を設ける処理を入れているところとか。
このSleep関数も関数が実行され指定した時間全体の処理が止まっている間、OSに制御権はないから、
↑のようにやっぱり文字入力は全然受け付けてくれない…orz。それに先に述べたループ処理と違って、VBA内で【何等かの処置】を施して、
強引に文字入力を受け付けさせるというようなこともできない。…でも、VBAでWebスクレイピングするのであれば、
HPへのアクセス等で、その都度一定の待機時間を設けるのであれば、正直お手軽に待機時間を作り出せるWinAPIのSleep関数が使い勝手が良いことも事実でして(-_-;。
…でもよくよく考えてみれば、WinAPIのSleep関数と同じようなことをする、それっぽい関数だったら結構簡単なロジックで作れてしまうのではないか?-。
と、そんな思い付きから、↓のようなそれっぽい関数を作ってみました(笑)。
もっとも、言語を問わずある程度プログラミングのコードが記述できる人だったら、↓ぐらいのものはささっと作れそうな気はしますけど(-_-;。
…しかもこれを書いていてさっき気づいたのですが、日付をまたいで↓の関数を実行すると、実質無限ループになってしまうような…orz。
…ということでこの分野、まだまだ研究が足りないようで…。
'OSへの制御権をなるべく残すために用意した疑似Sleep関数(あくまで正確に指定した時間処理を止めるわけではない…)
'引数:tmp/設定する待機時間(ミリ秒)
Public Sub SleepEx(ByVal tmp As Double)
tmp = tmp / 1000
Dim baseTime As Double, curTime As Double
baseTime = Timer
Do
curTime = Timer
DoEvents
Loop Until baseTime + tmp <= curTime
End Sub