このサイトの記事内では「アフィリエイト広告」などの広告を掲載している場合があります。
消費者庁が問題としている「誇大な宣伝や表現」とならないよう配慮しコンテンツを制作しておりますのでご安心ください。
問題のある表現が見つかりましたらお問い合わせよりご一報いただけますと幸いです。

[KeyNotFoundError] VBA-JSONのエラー原因と対策(VBA)

2024年9月12日

実行時エラー '0’:

KeyNotFoundError

Dictionary key not found: a

エラーメッセージ

久しぶりにVBA -JSONを使ったところ、画像のエラーが発生しました。
なお、以前に使ったときにはこのエラーが発生したことはありません。

もし、あなたも画像のエラーが発生しているようでしたら、十中八九同じ原因だと思います。

この記事を読めばエラー理由と解消法が分かりますので、順番に読んでみてください。

ちなみに、使用しているVBA-JSONは最新のVer.2.3.1です。(特にVer.は関係ありません)

VBAが難しいと感じたら
ココナラにてVBAの作成依頼を受け付けています。
ご依頼・ご相談はこちらから

[KeyNotFoundError] の発生箇所

Private Function json_ParseObject(json_String As String, ByRef json_Index As Long) As Dictionary
    Dim json_Key As String
    Dim json_NextChar As String

    Set json_ParseObject = New Dictionary
    json_SkipSpaces json_String, json_Index
    If VBA.Mid$(json_String, json_Index, 1) <> "{" Then
        Err.Raise 10001, "JSONConverter", json_ParseErrorMessage(json_String, json_Index, "Expecting '{'")
    Else
        json_Index = json_Index + 1

        Do
            json_SkipSpaces json_String, json_Index
            If VBA.Mid$(json_String, json_Index, 1) = "}" Then
                json_Index = json_Index + 1
                Exit Function
            ElseIf VBA.Mid$(json_String, json_Index, 1) = "," Then
                json_Index = json_Index + 1
                json_SkipSpaces json_String, json_Index
            End If

            json_Key = json_ParseKey(json_String, json_Index)
            json_NextChar = json_Peek(json_String, json_Index)
            If json_NextChar = "[" Or json_NextChar = "{" Then
                Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
            Else
                json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index) ' ここでエラーが発生
            End If
        Loop
    End If
End Function

KeyNotFoundErrorが発生しているのは、VBA -JSONのjson_ParseObjectというプロシージャ内です。

                json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index) ' ここでエラーが発生

この代入しようとする部分でエラーとなります。

変数json_ParseObjectを確認したところ、エラーメッセージの通りでこのキーはありませんでした。

しかし、これはDictionary型の仕様ではエラーにならないはずです。

Object.Item(キー) = アイテム

Dictionary型でこのようなコードを書いたとき、次のように処理されます。

  • キーが存在する: キーに紐づいたアイテムを再代入する
  • キーが存在しない: 新たにキーを作成してアイテムを代入する

そのため、キーが存在しなくてもエラーにならないはずです。

よく分からず調べたのですが、原因は全く違う部分にありました。

[KeyNotFoundError]VBA-JSONのエラー原因

エラー原因ですが、これはSeleniumBasicをインストールしたことでした。
以前VBA-JSONを使ったときにはSeleniumBasicはインストールしていません。

実は、SeleniumにもDictionaryという型があります。

このDictionaryという同じ名前の型がエラー原因です。

SeleniumのDictionary型にもitemプロパティがあるのですが、Scripting RuntimeのDictionary型とは違い、キーが存在しないとエラーになります。
(先ほど説明した「新たにキーを作成してアイテムを代入する」の動作とはなりません)

VBA-JSONでは、ScriptingのDictionary型を使ったプログラムを書いているのですが、VBAがSeleniumのDictionary型と処理していたためエラーが発生していたのです。

[KeyNotFoundError]VBA-JSONのエラー対策

エラー対策はとても簡単です。

Dictionaryと書くと、SeleniumかScripting Runtimeか暗黙の指定となってしまうため、明示的に指定するだけです。

Private Function json_ParseObject(json_String As String, ByRef json_Index As Long) As Scripting.Dictionary 'Scripting.Dictionaryに変更
    Dim json_Key As String
    Dim json_NextChar As String

    Set json_ParseObject = New Scripting.Dictionary 'Scripting.Dictionaryに変更
    json_SkipSpaces json_String, json_Index
    If VBA.Mid$(json_String, json_Index, 1) <> "{" Then
        Err.Raise 10001, "JSONConverter", json_ParseErrorMessage(json_String, json_Index, "Expecting '{'")
    Else
        json_Index = json_Index + 1

        Do
            json_SkipSpaces json_String, json_Index
            If VBA.Mid$(json_String, json_Index, 1) = "}" Then
                json_Index = json_Index + 1
                Exit Function
            ElseIf VBA.Mid$(json_String, json_Index, 1) = "," Then
                json_Index = json_Index + 1
                json_SkipSpaces json_String, json_Index
            End If

            json_Key = json_ParseKey(json_String, json_Index)
            json_NextChar = json_Peek(json_String, json_Index)
            If json_NextChar = "[" Or json_NextChar = "{" Then
                Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
            Else
                json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
            End If
        Loop
    End If
End Function

具体的には、上のコードのようにjson_ParseObjectプロシージャ内の2か所のDictionaryをScripting.Dictionaryに変えるだけです。

これで、エラーは解消します。

ちなみに、参照設定で優先順位を変えることでも解決できます。
(とはいえ、明示的に指定する方がベターだと思います)

[参考]Selenium.Dictionaryのメソッド/プロパティ一覧

参考にSelenium.Dictionaryのメソッド/プロパティ一覧をお見せします。

キーが存在しない時に、アイテムを追加するためにはItemでなく、AddもしくはSetメソッドを使う必要があります。

メソッドorプロパティ
Addメソッド
Clearメソッド
ContainsKeyメソッド
Countプロパティ
Getメソッド
Itemプロパティ(既定)
Keysメソッド
Setメソッド
ToExcelメソッド
Valuesメソッド
Selenium.Dictionaryのメソッド/プロパティ一覧

Scripting RuntimeのDictionaryと似たようなメソッドがありますが、名称がかなり異なっています。

VBA-JSONの使い方

VBA-JSONの使い方はこちらの記事をご覧ください。

《VBA上級者になりたい人へ》
VBA上級者を目指したい人にはパーフェクトExcel VBA一択です。
この本を読み切れば間違いなくVBA上級者になれます。

VBAが難しいと感じたら
ココナラにてVBAの作成依頼を受け付けています。
ご依頼・ご相談はこちらから

VBA

Posted by やろまい