VBAでオブジェクトを関数の返却値に使う時に「オブジェクト変数またはWithブロック変数が設定されていません」というエラーになる場合の対処

VBAでオブジェクトを関数の返却値に使う時に「オブジェクト変数またはWithブロック変数が設定されていません」というエラーになる場合の対処

Posted at June 17,2014 1:33 AM
Tag:[Excel, VBA]

VBAでオブジェクトを関数の返却値に使う時に「オブジェクト変数またはWithブロック変数が設定されていません」というエラーになる場合の対処方法を紹介します。

1.問題点

Excel VBAで正規表現を使って文字列をマッチさせる方法」で、VBScript.RegExpを使った正規表現の文字列マッチ処理を紹介しました。

下記のコードはそのサンプルです。

Sub test()
    Dim str As String
    str = "foo Foo FOO"
    
    Dim regex
    Set regex = CreateObject("VBScript.RegExp")
    regex.Pattern = "foo"
    regex.Global = True
    regex.IgnoreCase = True
    
    Dim result
    Set result = regex.Execute(str)
    If result.Count > 0 Then
        For i = 0 To result.Count - 1
            MsgBox result(i)
        Next
    End If
 
    Set regex = Nothing
End Sub

上のコードから文字列マッチの処理だけを汎用的に使えるよう、別関数に切り出してみました。

Function exec_regex(data As String, pattern As String) As Object
    Dim regex
    Set regex = CreateObject("VBScript.RegExp")
    regex.pattern = pattern
    regex.Global = True
    regex.IgnoreCase = True
    exec_regex = regex.Execute(data)
End Function

本題からそれますが、文字列マッチ結果はMatchesコレクションになりますが、返却値にするにはFunctionに「As Object」を設定します。

Function exec_regex(data As String, pattern As String) As Object

そして次のコードから切り出した関数を起動してみました。関数パラメータは、マッチ文字列とマッチさせたいパターンです。

Sub test()
    Dim result
    Set result = exec_regex("foo Foo FOO", "foo")
    If result.Count > 0 Then
        For i = 0 To result.Count - 1
            MsgBox result(i)
        Next
    End If
End Sub

がこのコードを実行すると、タイトルのように「オブジェクト変数またはWithブロック変数が設定されていません」というエラーになります。

「オブジェクト変数またはWithブロック変数が設定されていません」というエラー

2.原因と対処

エラーの原因は、返却値を設定するときに「Set」を行っていなかったためです。

ということで、関数の返却値を設定するときに「Set」を追加することでエラーは解消しました。

Function exec_regex(data As String, pattern As String) As Object
    Dim regex
    Set regex = CreateObject("VBScript.RegExp")
    regex.pattern = pattern
    regex.Global = True
    regex.IgnoreCase = True
    Set exec_regex = regex.Execute(data)
End Function

ここではExecuteの実行結果を例にとりあげましたが、オブジェクトを返却値に利用するときは「Set」が必要となります。

また、ここで紹介したサンプルには最初から設定していますが、オブジェクトを受け取る側にも「Set」が必要ですので気をつけましょう。

Sub test()
    Dim result
    Set result = exec_regex("foo Foo FOO", "foo")
    If result.Count > 0 Then
        For i = 0 To result.Count - 1
            MsgBox result(i)
        Next
    End If
End Sub
関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)