サーチ…
前書き
コンパイルされたコードは、実行時にエラーに陥ることがあります。このトピックでは、最も一般的なもの、その原因、およびそれらを回避する方法について説明します。
実行時エラー '3':GoSubなしの戻り値
不正なコード
Sub DoSomething()
GoSub DoThis
DoThis:
Debug.Print "Hi!"
Return
End Sub
なぜこれは機能しませんか?
実行はDoSomethingプロシージャに入り、 DoThisラベルにジャンプし、 "Hi!"を表示します。デバッグ出力には 、 GoSub呼び出しの直後に命令に戻り 、「Hi!」を出力します。また、 Returnステートメントに遭遇しましたが、 GoSubステートメントでここに来なかったので、ここに戻ることはありません。
正しいコード
Sub DoSomething()
GoSub DoThis
Exit Sub
DoThis:
Debug.Print "Hi!"
Return
End Sub
なぜこれは機能しますか?
導入することでExit Sub の前に命令をDoThis行ラベル、我々は分離しているDoThis手順本体の残りの部分からサブルーチンを-実行する唯一の方法DoThisサブルーチンを経由するGoSubジャンプ。
その他の注意事項
GoSub / Returnは推奨されていませんので、実際のプロシージャコールのために避けてください。プロシージャには、エラーハンドラ以外のサブルーチンを含めることはできません。
これは、 実行時エラー '20'に非常に似ています 。 エラーなしで再開します 。どちらの状況においても、 通常の実行パスが明示的なジャンプなしにサブルーチンに入ることができないようにすることです( On Error GoToは明示的ジャンプとみなされます)。
実行時エラー '6':オーバーフロー
コードが正しくありません
Sub DoSomething()
Dim row As Integer
For row = 1 To 100000
'do stuff
Next
End Sub
なぜこれは機能しませんか?
Integerデータ型は、32,767の最大値を持つ16ビット符号付き整数です。それ以上のものに割り当てると型がオーバーフローし 、このエラーが発生します。
正しいコード
Sub DoSomething()
Dim row As Long
For row = 1 To 100000
'do stuff
Next
End Sub
なぜこれは機能しますか?
代わりにLong (32ビット)整数を使用することで、カウンタ変数の型をオーバーフローさせることなく、32,767回以上反復するループを作成できるようになりました。
その他の注意事項
詳細は、「 データ型と制限」を参照してください。
実行時エラー '9':範囲外の下付き文字
コードが正しくありません
Sub DoSomething()
Dim foo(1 To 10)
Dim i As Long
For i = 1 To 100
foo(i) = i
Next
End Sub
なぜこれは機能しませんか?
fooは10個の項目を含む配列です。 iループカウンタが11の値に達すると、 foo(i)は範囲外です。このエラーは、その配列またはコレクションに存在しないインデックスで配列またはコレクションにアクセスするたびに発生します。
正しいコード
Sub DoSomething()
Dim foo(1 To 10)
Dim i As Long
For i = LBound(foo) To UBound(foo)
foo(i) = i
Next
End Sub
なぜこれは機能しますか?
使用LBoundとUBoundはそれぞれ、アレイの下部および上部境界を決定するために機能します。
その他の注意事項
インデックスが文字列、たとえばThisWorkbook.Worksheets("I don't exist")場合、このエラーは指定された名前が照会されたコレクションに存在しないことを意味します。
実際のエラーは実装固有のものですが、 Collectionは、実行時エラー5 "無効なプロシージャ呼び出しまたは引数"代わりに発生します。
Sub RaisesRunTimeError5()
Dim foo As New Collection
foo.Add "foo", "foo"
Debug.Print foo("bar")
End Sub
実行時エラー '13':型の不一致
コードが正しくありません
Public Sub DoSomething()
DoSomethingElse "42?"
End Sub
Private Sub DoSomethingElse(foo As Date)
' Debug.Print MonthName(Month(foo))
End Sub
なぜこれは機能しませんか?
VBAは本当に"42?"を変換しようとしてい"42?"引数をDate値に変換します。失敗した場合、VBAは渡す日付を知らないため、 DoSomethingElseの呼び出しを実行できません。したがって、引数の型が予想される型と一致しないため、実行時エラー13 型の不一致が発生します暗黙のうちに変換されることもありません)。
正しいコード
Public Sub DoSomething()
DoSomethingElse Now
End Sub
Private Sub DoSomethingElse(foo As Date)
' Debug.Print MonthName(Month(foo))
End Sub
なぜこれは機能しますか?
Dateパラメーターを必要とするプロシージャーにDate引数を渡すことで、呼び出しは成功します。
実行時エラー '91':オブジェクト変数またはWithブロック変数が設定されていません
コードが正しくありません
Sub DoSomething()
Dim foo As Collection
With foo
.Add "ABC"
.Add "XYZ"
End With
End Sub
なぜこれは機能しませんか?
オブジェクト変数が参照を保持し、参照が使用して設定する必要がSetたキーワードを。このエラーは、参照がNothingであるオブジェクトに対してメンバー呼び出しが行われるたびに発生します。この場合、 fooはCollection参照ですが、初期化されていNothingため、参照にはNothingが含まれています.Addには.Addを呼び出すことはできませNothing 。
正しいコード
Sub DoSomething()
Dim foo As Collection
Set foo = New Collection
With foo
.Add "ABC"
.Add "XYZ"
End With
End Sub
なぜこれは機能しますか?
Setキーワードを使用してオブジェクト変数に有効な参照を割り当てることにより、 .Add呼び出しが成功します。
その他の注意事項
多くの場合、関数またはプロパティはオブジェクト参照を返すことができます。一般的な例はExcelのRange.Findメソッドで、これはRangeオブジェクトを返します。
Dim resultRow As Long
resultRow = SomeSheet.Cells.Find("Something").Row
しかし、関数はNothing (検索語が見つからない場合)を返すことができるため、連鎖された.Rowメンバ呼び出しが失敗する可能性があります。
オブジェクトメンバーを呼び出す前に、参照がIf Not xxxx Is Nothing条件で設定されていることを確認します。
Dim result As Range
Set result = SomeSheet.Cells.Find("Something")
Dim resultRow As Long
If Not result Is Nothing Then resultRow = result.Row
実行時エラー '20':エラーなし再開
コードが正しくありません
Sub DoSomething()
On Error GoTo CleanFail
DoSomethingElse
CleanFail:
Debug.Print Err.Number
Resume Next
End Sub
なぜこれは機能しませんか?
DoSomethingElseプロシージャがエラーを発生させると、実行はCleanFail行ラベルにジャンプし、エラー番号を出力し、 Resume NextのResume Next命令はエラーが発生した行の直後の命令にジャンプします。この場合、 Debug.Print命令:エラー処理サブルーチンはエラーコンテキストなしで実行されており、 Resume NextのResume Next命令に達すると、再開する場所がないため実行時エラー20が発生します。
正しいコード
Sub DoSomething()
On Error GoTo CleanFail
DoSomethingElse
Exit Sub
CleanFail:
Debug.Print Err.Number
Resume Next
End Sub
なぜこれは機能しますか?
導入することでExit Subの前に命令をCleanFail行ラベル、我々は分離しているCleanFail手順本体の残りの部分からエラー処理サブルーチンを-エラー処理サブルーチンを実行するための唯一の方法は、経由でOn Errorジャンプ。したがって、実行パスは、エラーコンテキスト外のResume命令には到達せず、実行時エラー20を回避します。
その他の注意事項
これは、 実行時エラー '3'と非常によく似ています 。どちらの状況においても、 通常の実行パスが明示的なジャンプなしにサブルーチンに入ることができないようにすることです( On Error GoToは明示的ジャンプとみなされます)。