はじめに
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に置き換えた際に、実行すると下記のエラーが出ました。
デバッグしていくと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
を省略しない方がいいですよ。