サーチ…
前書き
コンパイルされたコードは、実行時にエラーに陥ることがあります。このトピックでは、最も一般的なもの、その原因、およびそれらを回避する方法について説明します。
実行時エラー '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
は明示的ジャンプとみなされます)。