AutoItでRPAチックな自動化アプリを作成していると、開発PCでは出ないのにテストPCだと出る、なんてことがよく(?)あります。
で、メッセージ的には「the requested action with this object has failed」そしてアプリが落ちる。
・・・いやいや、これだと追っかけようにもどうしたらいいのかわからないでしょ・・・
1. 出るタイミングがつかめない
同じ個所で出るのではなく、場所やタイミングが違って尚更困るという。
エクセルにループ内で書き込み(Excel UDF使用しても使用しなくても)で起きています。
COMオブジェクトを使う時にエラーが出ている模様。

2. Excel UDFを見る
AutoItインストールフォルダのinclude\Excel.au3を見てみましょう。
各関数最初にエラーひっかけていますね。
Local $oError = ObjEvent("AutoIt.Error", "__Excel_COMErrFunc")
ではこの__Excel_COMErrFuncが何やってるかと、Excel.au3の一番下を見ると関数あるけど中身なしです。
Func __Excel_COMErrFunc() EndFunc
というか、Excel UDFの関数は最初に毎回呼んでいますが・・・これいいの?って感じです。
いや、よくないからうまくエラーをハンドル出来ないんですね。
3. エラーがわかるようにしてみる ObjEvent
ObjEvent関数リファレンス(日本語)を見てみましょう。
ObjEvent( “AutoIt.Error” [, “function name”] ) と2番目に書いてあり、
「2番目のフォーマットはCOMのエラーをハンドリングするために使用します。COMのエラーが発生すると、指定した関数が呼び出されます。
2番目のパラメータを省略すると、(存在する場合は)現在のエラーハンドリング関数を返します。」と書いています。
更にその下に COMエラーハンドリングサンプル があります。IEの例ですが、今回はExcelで。Excel UDFはやめて、自分でエクセルと接続していきましょう。
WorkSheets.Item(“存在しないシート”)でエラー出してみます。
Global $oExcel = ObjCreate("Excel.Application") Global $g_eventerror = 0 ;COMエラーが起きたかどうかチェック用、ハンドリング後にリセット必要 Global $oMyError = 0 ;errorオブジェクト $oMyError = ObjEvent("AutoIt.Error", "ComErrorFunc") ;COMエラーハンドラ初期化 $wb = $oExcel.Workbooks.Add $sheet = $wb.WorkSheets.Item("存在しないシート") Func ComErrorFunc() Msgbox(0, "AutoIt ComError", "COMエラーが起きています " & @CRLF & _ "err.description is : " & @TAB & $oMyError.description & @CRLF & _ "err.windescription:" & @TAB & $oMyError.windescription & @CRLF & _ "err.number is: " & @TAB & hex($oMyError.number,8) & @CRLF & _ "err.lastdllerror is: " & @TAB & $oMyError.lastdllerror & @CRLF & _ "err.scriptline is: " & @TAB & $oMyError.scriptline & @CRLF & _ "err.source is: " & @TAB & $oMyError.source & @CRLF & _ "err.helpfile is: " & @TAB & $oMyError.helpfile & @CRLF & _ "err.helpcontext is: " & @TAB & $oMyError.helpcontext _ ) Local $err = $oMyError.number If $err = 0 Then $err = -1 $g_eventerror = $err EndFunc

確かにハンドルできました。一度ObjEvent呼べばいいのにExcel UDFでは関数呼ぶ度に毎回呼んでいます。まぁ、他のUDFでCOMエラーハンドリングするからなのかもしれませんが、Excel UDFだけではExcel操作足りない事が多々出てくるので、自分でハンドリングしたいですね。
最終的にはExcel.au3を見ながら自分でエクセル操作関数作成するのが良さそうです。
筆者は_Excel_RangeWrite()内で$oExcel.Transpose($vValue)でよくエラー出ていたことがわかり、_ArrayTranspose($vValue)にするなどしました。
3.1 Excel UDFもbForceFunc=Trueで_ArrayTranspose()を使う
後日知ったのですが、$oExcel.Transpose($vRange.Value)で失敗するのは、255文字超えたセルのTransposeは未対応とのこと。各配列で255文字超えてるのチェックするなら$bForceFunc=Trueセットしたほうがいいですね。_Excel_RangeRead(),_Excel_RangeWrite()などですね。
コメント