プロが教える店舗&オフィスのセキュリティ対策術

EXCEL VBAにて
Dictionaryオブジェクトを利用しようと思い
ネット検索して調べていると・・・

1)Dim MyDic As Object
Set MyDic=CreateObject("Scripting.Dictionary")

2) Dim MyDic As Scripting.Dictionary
Set MyDic = New Scripting.Dictionary

3) Dim MyDic
Set MyDic=CreateObject("Scripting.Dictionary")

4) Dim myDic As New Scripting.Dictionary

上記の4パターンが出てきました。
いずれも「連想配列」を使うものなのですが、

オブジェクト型、バリアント型、Newキーワードで宣言・・・

4つの違いがイマイチ理解できません。
違いを教えてください。

A 回答 (4件)

1)Dim MyDic As Object


Set MyDic=CreateObject("Scripting.Dictionary")
参照設定無しで扱う場合

2) Dim MyDic As Scripting.Dictionary
Set MyDic = New Scripting.Dictionary
有りで・・

3) Dim MyDic
Set MyDic=CreateObject("Scripting.Dictionary")
無しで

4) Dim myDic As New Scripting.Dictionary
有りで

だけでは分からないので、用途・環境の面で考えてみました。
今回の場合は、Scripting.Dictionary なのでWindows2000の頃からバージョンは変わっていないので
説明しやすくするために、AccessからExcelをオートメーションで扱う例で説明します。
Scripting.Dictionary → Excel.Applicationです。
Excelに参照設定を行う場合はバージョンによって、Microsoft Excel xx.x Object Libraryの
xx.x が変わってくるのはご存知かと思います。

参照設定を行ってコーディングすれば、Excelのプロパティなどが自動表示されるので非常に楽ちんです。
Excelの定数もそのまま使えます。
ただ、2003に参照設定して作成したものを2010がインストールされている環境で使おうとした時など
参照設定不可になりますので、改めて設定しなおす必要があります。
一方無しでコーディングするのは上記お助け機能が使えないので手間ですが
バージョンが異なってもある程度は差異を吸収してくれます。
なので不特定のPCで使う場合は、有りで作成し、最終的に無しで動くように変更しています。
自身で使われるだけでしたら、2)で良いかとも思います。
(Scripting.Dictionary自体Windows2000?の頃から変わっていないし)

3)については、VBScript がこのパターンです。
(元々変数の型宣言ができないので。)
VBAではVariant型で宣言したものを再度Setでやり直しているので二度手間です。

4)は2)を1行にまとめたものですが
2)の場合は、Set・・した時点でインスタンスが作成されますが
4)は参照しに行って初めて作成されます。
また、Set ・・ Nothing で 2)は解放され以後は使えなくなりますが
4)はNothingした後でも参照しに行けばゾンビのごとく新たに立ち上がります。

以下のをローカルウィンドウかウォッチウィンドウで確認しつつ実行してみてください。
1行目と2・3行目のコメントアウトを入れ替えてみた場合も。

Sub DicTest()
Dim myDic As New Scripting.Dictionary
'Dim myDic As Scripting.Dictionary
'Set myDic = New Scripting.Dictionary
Stop

myDic.Add 0, "zero"
myDic.Add 1, "one"
Debug.Print "count1=" & myDic.Count
Debug.Print myDic(1)

Set myDic = Nothing
Stop
Debug.Print "count2=" & myDic.Count 'ゾンビ?復活
Stop
End Sub

余計わけわかんなくなったらゴメン。
    • good
    • 0
この回答へのお礼

基本的に不特定多数のPC、かつExcelのバージョンも違うんで
個々で参照設定はしない(出来ていない)前提で
作りたいと思っていました。

>なので不特定のPCで使う場合は、有りで作成し、最終的に無しで動くように変更しています。
すみません、ちょっと具体的な手法が解らなくなりました

参照設定なしの状態ならば・・・1)が一番、無難でしょうか?

お礼日時:2013/07/09 13:28

VarType関数があるのは忘れてました。


Variant型はこの辺を参照。

参考URL:http://www5f.biglobe.ne.jp/~f-lap/tips_staticarr …
    • good
    • 1
この回答へのお礼

ん~私には・・・難しいです。

でも、勉強になる情報もあり、
ぜひ参考にします。

ありがとうございました。

お礼日時:2013/07/10 13:15

具体的な手法も何もありません。


参照設定しておいて問題なく機能するのを確認後に
参照設定のチェックを外して
Dim myDic As New Scripting.Dictionary
↑コメントアウト ↓コメントを外す
'Dim myDic As Scripting.Dictionary
'Set myDic = New Scripting.Dictionary
コンパイルや実行時エラーが出ないようにチマチマと修正。
・・・と私はやっています。
Dictionaryなら修正の必要はなさそうですね。

>参照設定なしの状態ならば・・・1)が一番、無難でしょうか?
1)しかありません。
    • good
    • 0
この回答へのお礼

すみません。
コメントをつけたり、はずしたりする意味だったんですね

1)しかないですよね。
本当にありがとうございました。

今からコーディングに励みます

お礼日時:2013/07/10 13:10

> 1)Dim MyDic As Object


実行時バインド

> 2) Dim MyDic As Scripting.Dictionary
事前バインド

> 3) Dim MyDic
実行時バインド
(Variant型のvtメンバがVT_DISPATCH)

> 4) Dim myDic As New Scripting.Dictionary
事前バインド
(参照セット時のもたつきがある)

速度的には
2 - 4 - 1 - 3
の順かなと。

事前バインドの 2 と 4 はメソッドやプロパティの呼び出し時には差がありませんが、実行時バインドの 1 と 3 は理論上、明確な差があります。
(体感出来る程でないにしても)
    • good
    • 0
この回答へのお礼

バイディングがイマイチ整理できてなかったので
とても参考になりました

>Variant型のvtメンバがVT_DISPATCH

これについては、勉強不足で・・・
ちょっと調べてみましたが、すぐに理解できず・・・
頑張って勉強します

ありがとうございました

お礼日時:2013/07/09 13:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!