LoginSignup
0
0

More than 1 year has passed since last update.

【Excel】VBA-Dictionaryを使用する際の注意点

Posted at

はじめに

Excelでwebブラウザの操作を自動化する最小機能のみ実装したフレームワークの「TinySeleniumVBA」があります。
これは今のところActiveXを使用しているため、Windows専用になっています。ActiveXの部分を取り除き代替部分をVBA-toolsライブラリー群を使えば、Mac上のExcelで動作するかもと取り組みました。

TinySeleniumVBAではDictionaryオブジェクトを使用する上でActiveXを使用しています。
ただ記述はNew Dictionaryとなっているため、移植する手間はありません。
※参照設定ダイアログで「Microsoft Scripting Runtime」にチェックを付けて使用する。

VBA-Dictionary

MacではActiveXが使用できません。しかし、今回紹介する「VBA-Dictionary」でDictionaryクラスを使用することで、WindowsでもMacでもDictionaryオブジェクトを同様に使うことができるようになります。
導入時に参照設定ダイアログで「Microsoft Scripting Runtime」にチェック付けてもらう必要もなくなります。

インストール

最新版を下記サイトからダウンロードし、解凍後にVBAプロジェクトに「Dictionary.cls」をインポートします。

サンプルコード

VBA-Dictionaryのサンプルコードそのままです。

Dim Dict As New Dictionary
Dict.CompareMode = CompareMethod.TextCompare

Dict("A") ' -> Empty
Dict("A") = 123
Dict("A") ' -> = Dict.Item("A") = 123
Dict.Exists "A" ' -> True

Dict.Add "A", 456
' -> Throws 457: This key is already associated with an element of this collection

' Both Set and Let work
Set Dict("B") = New Dictionary
Dict("B").Add "Inner", "Value"
Dict("B")("Inner") ' -> "Value"

UBound(Dict.Keys) ' -> 1
UBound(Dict.Items) ' -> 1

' Rename key
Dict.Key("B") = "C"
Dict.Exists "B" ' -> False
Dict("C")("Inner") ' -> "Value"

' Trying to remove non-existant key throws 32811
Dict.Remove "B"
' -> Throws 32811: Application-defined or object-defined error

' Trying to change CompareMode when there are items in the Dictionary throws 5
Dict.CompareMode = CompareMethod.BinaryCompare
' -> Throws 5: Invalid procedure call or argument

Dict.Remove "A"
Dict.RemoveAll

Dict.Exists "A" ' -> False
Dict("C") ' -> Empty

注意点

TinySeleniumVBAをVBA-Dictionaryに置き換えた際に、実行すると下記のエラーが出ました。
image.png

デバッグしていくとFor Eachでエラーになります。

For Each paramKey In parameters
    If VarType(parameters(paramKey)) = vbString Then
        path = Replace(path, "$" + paramKey, parameters(paramKey))
    End If
Next

VBA-Dictionaryって、For Eachが使えないのかと、Forに書き換えて動かしていました。

For i = 0 To parameters.Count - 1
    paramKey = parameters.Keys(i)
    If VarType(parameters(paramKey)) = vbString Then
        path = Replace(path, "$" + paramKey, parameters(paramKey))
    End If
Next

Issueもあるんだけど、最終的によく分からない。

VBA-Dictionaryを調べていたら下記サイトがあって、サンプルコードを見るとFor Eachを使用していました。

よく見ると、コレクションのところに.Keysが付いていました。
そこで、.Keysを付けたところ、エラーにもならず正しい動作をすることが分かりました。

For Each paramKey In parameters.Keys
    If VarType(parameters(paramKey)) = vbString Then
        path = Replace(path, "$" + paramKey, parameters(paramKey))
    End If
Next

Windows上でVBA-Dictionaryクラスを一旦解除して、元の「Microsoft Scripting Runtime」にチェックを付けた状態にしても、エラーにもならず正しい動作をすることが分かりました。
よって、TinySeleniumVBAのissueを書いたので、次のバージョンアップ時には修正されるかも知れません。

最後に

WindowsとMacの両方で動かすなら、.Keysを省略しない方がいいですよ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0