のためにVBAでシェル機能をスピードアップする方法libc.dylib:私が使用する、VBA(execShell機能)内のシェルスクリプトを実行するために、この質問には、トップの答えから関数を使用してきたマック
VBA Shell function in Office 2011 for Mac
この関数内ではwhileループであり、popenよりもはるかに遅く実行されます。私はこの部分がシェル内で実行されていて、popenが初期化されていると推測していますが、実際に何をしているのか分かりません。
Time taken to run popen:
0.01171875 seconds
Time taken to run while loop:
0.8710938 seconds
実行に時間がかかる場合は、機能を中止するかタイムアウトすることができますか?複数の関数呼び出しを処理するために使用できるメソッドはありますか?シェルスクリプトのcurlコマンドにタイムアウトを追加しました。 "curl --connect-timeout 5 --max-time 10 --retry 2 --retry-delay 0 --retry-max-time 40 "
に追加され、各コールの前に0.1秒の遅延が追加されました。それがスムーズに動いた場合、それは問題ではないでしょうが、時には完全にロックアップしているように見えることがあります。カールのリクエストに長時間の遅延がある場合、私はそれを中止してスクリプトを続行することをお勧めします。おそらく、いくつかの連続した失敗がスクリプトを完全に終了させた後です。関数呼び出しは線形に処理されると思っていましたが、シェルスクリプトを同時に処理する可能性があり、これが問題の原因になる可能性があると考えています。理想的には、ステータスバーを使用して実装しようとしたスクリプトのステータスに関するフィードバックを得たいと思いますが、これは2011バージョンのExcelの制限のためには機能しませんでした。実行の開始時に、シートが更新され、すべてがスムーズに実行されていることがわかりますが、後でスクリプトが完了するまで凍結します。
もう1つの解決策は、MacScriptコマンドを使用することですが、このシェルスクリプトには "\"と複数引用符を含む正規表現が含まれています。これは、AppleScriptに変換するのが非常に難しいので、 。 system()コマンドの使用は、VBAスクリプトに出力が必要なため、オプションではありません。
Private Declare Function popen Lib "libc.dylib" (ByVal command As String, ByVal mode As String) As Long
Private Declare Function pclose Lib "libc.dylib" (ByVal file As Long) As Long
Private Declare Function fread Lib "libc.dylib" (ByVal outStr As String, ByVal size As Long, ByVal items As Long, ByVal stream As Long) As Long
Private Declare Function feof Lib "libc.dylib" (ByVal file As Long) As Long
Function execShell(command As String, Optional ByRef exitCode As Long) As String
Dim file As Long
file = popen(command, "r")
If file = 0 Then
Exit Function
End If
While feof(file) = 0
Dim chunk As String
Dim read As Long
chunk = Space(50)
read = fread(chunk, 1, Len(chunk) - 1, file)
If read > 0 Then
chunk = Left$(chunk, read)
execShell = execShell & chunk
End If
Wend
exitCode = pclose(file)
End Function
ご回答ありがとうございます。私はDoEventsをループに追加しました。さらにデバッグした後、私の問題は、スクリプトが遅すぎるということではなく、サーバーが一定時間後に要求をブロックし、数分後にブロックが削除され、スクリプトが続行されるということです。待ち時間を0.1秒から0.5秒に変更しましたが、その部分を解決しましたが、タイムアウトするとカールのエラーを設定する必要があります。私もconnect-timeoutを5秒から変更します。これは、一部の要求では十分ではありませんが、ほとんどの場合、1秒未満です。 – Matts