アプリ版:「スタンプのみでお礼する」機能のリリースについて

エクセル2000です。
教えてください。
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/v … というサイトで

 「myDic.Add Cells(i, 1).Value, Cells(i, 2).Value は 
 myDic(Cells(i, 1).Value) = Cells(i, 2).Value と書くこともできます。 」

という記述を見つけました。
試してみたところ

Sub test01()
Dim myDic As Object
Dim myAr()
Set myDic = CreateObject("Scripting.Dictionary")
For i = 2 To 7
If Not myDic.exists(Cells(i, 1).Value) Then
myDic.Add Cells(i, 1).Value, Cells(i, 2).Value
End If
Next i
myAr() = myDic.Keys
MsgBox Join(myAr())
End Sub

Sub test02()
Dim myDic As Object
Dim myAr()
Set myDic = CreateObject("Scripting.Dictionary")
For i = 2 To 7
myDic(Cells(i, 1).Value) = Cells(i, 2).Value
Next i
myAr() = myDic.Keys
MsgBox Join(myAr())
End Sub

上記2つのマクロは、Keyに関してはまったく同じ働きをするようです。
ところがItemに関しては、Keyが重複した場合、あとから出てきた方に上書きされるようです。

これはtest01では、Keyの重複を排除しているためItemは最初に出たものが残る、test02は重複の場合、無条件でKeyが上書きされ(ても値は変化しないけど)、したがってItemも上書きされるという理解でよろしいのでしょうか?
ならば、Itemを気にしない場合、わざわざ
If Not myDic.exists(Cells(i, 1).Value) Then
myDic.Add Cells(i, 1).Value, Cells(i, 2).Value
End If
と、3行も費やして重複のチェックをしなくとも
myDic(Cells(i, 1).Value) = Cells(i, 2).Value
のわずか一行で済むということですよね?

A 回答 (4件)

> 3行も費やして重複のチェックをしなくとも



Dictionary については、その通りです。ただ、好みとなっちゃうのかなぁ

If Not dic.Exists(sKey) Then
  dic.Add Key:=sKey, Item:=vbEmpty
End If

の方がソースとしてわかりやすい気がするけど。
Item を無視してよいなら多分、
  
  dic(sKey) = vbEmpty

の方が高速でしょう。
    • good
    • 0
この回答へのお礼

KenKen_SPさま、いつもありがとうございます。
dic(sKey) = vbEmpty とはItemには何も入れないという意味というように理解してよろしいでしょうか?

Sub test03()
Dim myDic As Object
Dim myAr(), myAr2()
Set myDic = CreateObject("Scripting.Dictionary")
For i = 2 To 7
myDic(Cells(i, 1).Value) = vbEmpty
Next i
myAr() = myDic.Keys
myAr2() = myDic.Items
MsgBox Join(myAr()) & vbLf & Join(myAr2())
End Sub

で試したら、Join(myAr2())が0の行列になりましたので。

> ソースとしてわかりやすい気がするけど。

確かにそうですね、myDic(Cells(i, 1).Value) = Cells(i, 2).Value
って書いたら、後で見て自分でもわからなくなりそうです。
(^^;;

お礼日時:2009/03/09 18:19

>Itemを気にしない場合、


>myDic(Cells(i, 1).Value) = Cells(i, 2).Value
>のわずか一行で済むということですよね?
キーに対して最終アイテムを必要としている場合ならOKでしょうね。

逆に最初のアイテムを必要とするのなら、
>test01では、Keyの重複を排除しているためItemは最初に出たものが残る
こちらでしょうね。

それぞれは何を必要とするかで使い分けると思いますよ。
あくまで一例に過ぎないと思いますけど、ご参考になれば。
    • good
    • 0
この回答へのお礼

なるほど!
最終Itemか最初のItemのどちらが必要かで書き分けるべきなんですね!
理解しました。
ありがとうございました。

お礼日時:2009/03/09 18:21

#2です。



例えば、
>If Not myDic.exists(Cells(i, 1).Value) Then
>myDic.Add Cells(i, 1).Value, Cells(i, 2).Value
>End If
の使い方としては、

If Not myDic.Exists(Cells(i, 1).Value) Then
myDic(Cells(i, 1).Value) = Cells(i, 2).Value
Else
myDic(Cells(i, 1).Value) = myDic(Cells(i, 1).Value) + Cells(i, 2).Value
End If
のように
・キーがなければキーに値をセットする。
・キーがあればそのアイテムに新しい値を加算していく。
と言った場合に、存在しないキーによるエラー回避の意味もあるでしょうか。
    • good
    • 0
この回答へのお礼

なんとItenの加算が出来るんですね!
文字列の場合は結合されるんですね!驚きました。

Sub test04()
Dim myDic As Object
Dim myAr(), myAr2()
Set myDic = CreateObject("Scripting.Dictionary")
For i = 2 To 7
If Not myDic.Exists(Cells(i, 1).Value) Then
myDic(Cells(i, 1).Value) = Cells(i, 2).Value
Else
myDic(Cells(i, 1).Value) = myDic(Cells(i, 1).Value) + Cells(i, 2).Value 'Itemデータを加算
End If
Next i
myAr() = myDic.Keys
myAr2() = myDic.Items
MsgBox Join(myAr()) & vbLf & Join(myAr2())
End Sub

お礼日時:2009/03/09 18:28

>test02は重複の場合、無条件でKeyが上書きされ(ても値は変化しないけど)


>したがってItemも上書きされるという理解でよろしいのでしょうか?

ちょこっと、否、だいぶ違うみたい。。。(^^;;;

>myDic(Cells(i, 1).Value) = Cells(i, 2).Value

これは、一体、何をしているのでしょう。
それは、

myDic.Item(Cells(i, 1).Value) = Cells(i, 2).Value

のように、Itemプロパティが省略された形で
キーのセットではなくて
既にキーに関連付けされた項目の変更をしていることになります。

キーが無いときはどうするのじゃ、と疑問が生じるでしょうが、
その場合には以下のようにちゃんとキーを作ってくれるのです。

「項目を変更するときに引数 key の値が見つからない場合は
引数 newitem で指定された項目(今回は右辺のCells(i, 2).Value)
と関連付けられた新しいキーが作成されます」

ここら辺りはヘルプに詳しく書いてあります。
お暇なときには、ヘルプで遊びませう。。(^^;;;
 
以上です。

 
    • good
    • 0
この回答へのお礼

こんばんは、onlyromさま。
いつもありがとうございます。
日本まけちゃいましたね、残念です。

myDic(Cells(i, 1).Value) = Cells(i, 2).Valueは
キーがないときには新しいキーが作成され、あるときは既にキーに関連付けされたItemを変更するということですね。
よく分かりました。
ありがとうございます。

お礼日時:2009/03/09 22:08

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