【VBA】VBA-JSONで「KeyNotFoundError」エラーが発生する

VBA-JSONを使ってる時にエラー「KeyNotFoundError」が発生して解決に結構時間がかかったので備忘半分で原因と解消方法まとめてみました

VBA-JSONは何って話はコチラから

あわせて読みたい
VBAでJSONを扱う方法 VBA-JSONの使い方 ExcelVBAでJSONを扱うなら定番ライブラリ「VBA-JSON」がおすすめです、JsonConverter.basの導入から参照設定、ParseJsonでのパース、ConvertToJsonでの生成、配列やネストへのアクセスまで初心者向けにまとめました
目次

ある日突然エラーが発生した

まずはエラーメッセージから

KeyNotFoundError
Dictionary key not found: <KeyName>

そのまま受け取るとDictionary型の変数にKeyが無いと

ピンと来る理由もないので実際のエラーソースを見てみる

実際のエラー発生箇所

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

実際にエラーになるのは27行目の部分

なにもおかしなソースではないし、そもそも今までエラーにならなかったし同じVBA-JSONを使っているのに急にエラーになってしまう理由がやっぱりわからない・・・

原因は「Dictionary」でした

まず前提としてDictionary型と言われると連想することは参照設定だと「Microsoft Scripting Runtime」のことを指すと思いますし、私も思ってました

が、実は「Selenium Type Library」の中にもDictionary型があったのです

「Microsoft Scripting Runtime」のDictionary
「Selenium Type Library」のDictionary

つまり「Selenium Type Library」のDictionaryとして動作していたのでエラーになっていたわけです

解決方法

原因がわかれば対応方法は難しくなくて2パターンありますので状況に応じてお好きな方を

明示的に「Microsoft Scripting Runtime」のDictionaryとして宣言する

※※個人的にはコチラをおススメ※※

「Dictionary」を「Scripting.Dictionary」に置換してあげればOK

ちなみにVBA-JSONの中には別の箇所でも「Dictionary」の単語があってそこは置換すると別のエラーになるので「json_ParseObject」の型とそのソース内の1箇所だけを置換

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

    Set json_ParseObject = New 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

参照設定の優先順位を変える

半分原因の話にもなりますが「Dictionary」と宣言した時に「Microsoft Scripting Runtime」側になるように優先順位を変えるだけ

あとがき

APIとSeleniumBasicを使ったスクレイピングを併用したツールを作った時にこんな落とし穴があるとは知らず、解決するのに半日かかりました・・・

同じエラーに嵌った人の助けになれば幸いでございます


最後に・・・

クラウドワークスココナラでお仕事受け付けています!

PythonとExcelを中心に仕事に役立つ業務ツールや自動化、スクレイピングツールの作成を受注していて、クラウドワークスでは気が付けば100件以上のお仕事を受注してきました!

会社員をやりながらの副業なので時間の捻出は相応ですが、クライアントの方々と近い立場でこちらからも提案しながら活動していますのでお悩みあれば是非ご相談ください

ココナラのプロフィールページへ

"ココナラ"に新規登録する際は1,000Pもらえる紹介コード使ってください

78E62K

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

VBAとPythonを中心にユーザー側でできるITを自己学習しているので備忘録半分、学習履歴を残して同じ道を辿る人の参考になればとブログを始めました

副業でスクレイピングツール作成を中心にできることを色々やっていますのでご相談いただけるとありがたいです!


クラウドワークスのページへ


ココナラのページへ

コメント

コメント一覧 (2件)

  • 自分も同じエラーがかなり時間がかかっていたのですが、
    こちらを見て一瞬で解決しました。
    ありがとうございました。

コメントする

目次