和風スパゲティのレシピ

日本語でコーディングするExcelVBA

Dictionaryに渡すセル「.Value」は省略できない

知らずに落ちると抜け出せなくなるVBAの落とし穴です。

  • Dictionaryが同じkeyを同一と判定してくれない
  • Existsメソッドが常にFalseを返してしまう

あたりにお悩みの方は、この落とし穴に落ちていないかご確認ください。

DictionaryのKey、Itemはオブジェクトも受け取る

Dicitonary(Collectionも同様)のkey/ItemはVariant型のため、
値でもオブジェクトでもどちらも入れることができます。


よってItemにセルを入れたり↓

Dic.Add "みかん", Range("A1")

 
KeyをシートにしてシートごとのItemを何か定義したり↓

Dic.Add Worksheets("○○"), △△

 
こんな風に自由にkey-itemのペアを設計することができます。


しかしVariant型である(値もオブジェクトも受け取る)ということは、
ただ渡すだけではデフォルトプロパティを参照してくれないということであり、
つまりセル ⇒ セル.Value に自動で読み取ってくれません。


例えば以下の表から「くだものごとの価格」をDictionaryに読み込むとします。

Dicitonaryで読み込みたい表

このとき、

Dic.Add Cells(R, 1), Cells(R, 2)

としてしまうと、
「みかん - 100円」という登録をしたつもりが、
「A2セル - B2セル」という登録になってしまっているため、
次にみかんが出てきても同一のkeyだと判定してくれません。


品物 - 価格 をペアとして登録する場合は、
以下のようにしっかりと.Valueを付ける必要があります。

Dic.Add Cells(R, 1).Value, Cells(R, 2).Value

 

このValueを書き忘れた場合に厄介なのが、
書き忘れても別にエラーは出ない」という点です。


Rangeオブジェクトにしてしまってもkeyとしては問題なく登録ができるため、
普通にマクロは実行でき、終了後に結果がおかしいことでようやく気付けます。


こういった「エラーが出てくれないのでどこがおかしいかわからない」系のバグは、
危険なポイントを知識として持っておくことが重要な対策になります。

Dictionaryを使用する場面のほとんどはセル値を使うと思いますので、
この「.Value」の書き忘れには十分注意してください。