サーチ…


前書き

コンパイルされたコードは、実行時にエラーに陥ることがあります。このトピックでは、最も一般的なもの、その原因、およびそれらを回避する方法について説明します。

実行時エラー '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

なぜこれは機能しますか?

使用LBoundUBoundはそれぞれ、アレイの下部および上部境界を決定するために機能します。

その他の注意事項

インデックスが文字列、たとえば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であるオブジェクトに対してメンバー呼び出しが行われるたびに発生します。この場合、 fooCollection参照ですが、初期化されてい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 NextResume Next命令はエラーが発生した行の直後の命令にジャンプします。この場合、 Debug.Print命令:エラー処理サブルーチンはエラーコンテキストなしで実行されており、 Resume NextResume 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明示的ジャンプとみなされます)。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow