PR仕事がはかどる PCガジェット

プライム感謝祭10/19(月) 23:59まで

ポイントアップにエントリー最大10,000pt セールのおすすめをまとめて見る 📦 プライム30日無料体験 当ブログはAmazonアソシエイト・プログラムの参加者です。Amazonのアソシエイトとして、適格販売により収入を得ています。

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

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


WORK

ツール作成のご依頼を受けています

クラウドワークス・ココナラで受注200件以上
会社員の副業なので、対応は平日夜と土日です

頼めることと料金の目安を見る →

ココナラが初めての方は、紹介コード 78E62K で1,000円分のポイントがもらえます

はじめての方の会員登録(PR):クラウドワークス / ココナラ

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

この記事を書いた人

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

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


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


ココナラのページへ

コメント

コメント一覧 (2件)

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

コメントする

目次