|
▼T.K さん:
[sheet1]に 以下のようにあるとします。
A B C D
1 class start end ID
2 chr1 1048371 1049797 ER_1_Carrol
3 chr1 1054645 1055778 ER_2_Carrol
4 chr1 1285749 1286349 ER_3_Carrol
5 chr1 243097903 243098610 ER_396_Carrol
6 chr1 243121865 243122466 ER_397_Carrol
7 chr1 243604797 243605398 ER_398_Carrol
8 chr2 250722 251323 ER_399_Carrol
9 chr2 1650212 1650812 ER_400_Carrol
10 chr2 1660654 1661254 ER_401_Carrol
11 chr3 58431890 58432547 ER_756_Carrol
12 chr3 61588283 61588993 ER_757_Carrol
13 chr3 61595330 61595989 ER_758_Carrol
14 chr3 61605662 61606263 ER_759_Carrol
15 chr3 61649269 61649870 ER_760_Carrol
16 chr3 61768126 61769266 ER_761_Carrol
17 chr3 62137944 62138544 ER_762_Carrol
コード【72606】を見てください。
Dictionary オブジェクトを作成したあとのコードは↓こうなってます。
> Set r = Worksheets("Sheet1").Cells(1).CurrentRegion
> v = Intersect(r, r.Offset(1)).Value
まず 「.Cells(1).CurrentRegion」で表領域[A1:D17]が変数rに
セットされます。2行目で この範囲から先頭行を除外した正味
データ範囲[A2:D17]の「Value を」変数v に格納します。
さてその次からDictionaryにデータを登録している部分ですが、
ここは込み入ってる(Dictionaryのなかで また子供のDictionary
を作ってそれを親のDictionaryのItemに登録しています)ので、
実際のコードでなく、外側の(最初宣言した)親Dictionaryのやっ
ていることを説明します。
外側のdicのやっていることは まずもってA列のclass名から
《重複しないclass名を取得する》ことです。
Dictionaryとはバケツの集合のようなものです。ただしそれぞれの
バケツ表面にはKeyと呼ばれるラベルが貼ってあり、このラベルは
他のバケツと重複した名前を持つことが許されてません。重複をカ
ットしたリストを得るにはDictionaryのこの性質を利用します。
具体的には
1 class
2 chr1
3 chr2
4 chr1
5 chr3
6 chr1
7 chr2
8 chr3
のようなリストがあるとき、
2行目から 8行目までLoopして順に
For i = 2 To 8
dic("i行目のデータ") = Empty
Next
という構文を使って処理します。たとえば 2行目なら
dic("chr1") = Empty
です。このとき Dictionaryのなかに "chr1" というラベルを
もったバケツが用意されます。右辺には バケツの中に容れたい
アイテムを書きますが、今回はとくに内容物は入れないので、
Emptyとしておきます。
3行目のとき
dic("chr2") = Empty
が実行され、これでDictionaryのなかは
┃ ┃ ┃ ┃
┃ ┃ ┃ ┃
┃ ┃ ┃ ┃
┃ ┃ ┃ ┃
┗━━━━┛ ┗━━━━┛
[chr1] [chr2]
のようなイメージになります。[chr1] や [chr2]のバケツに付された
ラベルのことを Key といい、内容物を Item といいます。今回は
Itemはどのバケツも「空」です。バケツの中には何でも入れることが
できます。数値でも、文字でも、なんでも。。。そう、Dictionary
のItemには またDictionaryオブジェクトを入れることだってできる
のです(→【72606】ではDictionaryのなかにDictionaryを入れてます)。
(簡単な例のほうにもどって)
4行目のとき またKeyは "chr1" で、
dic("chr1") = Empty
を実行しますが、このときは「すでに"chr1"というkeyは在るので
そのバケツに Empty を入れます」。つまり、何もしない、と同じこと
になります。こうしてDictionaryにまだ無いときだけ新しいラベル(
key)をもったバケツが追加されます。
8行目まで同様の処理を繰り返したあと辞書は以下のようになって
います。
┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┃
┃ ┃ ┃ ┃ ┃ ┃
┗━━━━┛ ┗━━━━┛ ┗━━━━┛
[chr1] [chr2] [chr3]
辞書に何項目入っているかは dic.Count でわかります。
Countプロパティは Keyの数を返します。→ 3
どんなKey が登録されているのかは Keys()メソッドでリスト
できます。
Dim v As Variant
For Each v In dic.Keys()
Debug.Print v
Next
こうするとイミディエイト・ウィンドウには
chr1
chr2
chr3
が表示されます。
DictionaryはKeyごとの出現回数を調べたいときなどにも
重宝します。
さきほどのサンプルデータを使って、
1 class
2 chr1
3 chr2
4 chr1
5 chr3
6 chr1
7 chr2
8 chr3
Keyごとの出現回数をカウントするには、
For i = 2 To 8
dic("i行目のデータ") = dic("i行目のデータ") + 1
Next
とします。これを実行した後、
Dim v As Variant
For Each v In dic.Keys()
Debug.Print v, dic(v)
Next
を実行すれば、イミディエイト・ウィンドウには こんどは
chr1 3
chr2 2
chr3 2
と表示されるはずです。dic(v) は dic.Item(v) の省略された
書き方で、この文によって vという名の(Keyの,バケツの) Item
(内容物)が指定されています。
先ほどいいましたように dicの Item には いろんなものを入れる
ことができます。
たとえば、"ER_1_Carrol" という名前(Key) のついたバケツに
{1048371, 1049797} という数値配列を入れるときは
dic("ER_1_Carrol") = Array(1048371, 1049797)
とします。
内容物を取り出すときは
dic("ER_1_Carrol")(0) とすると 1048371 が、
dic("ER_1_Carrol")(0) とすると 1049797 が取り出せます。
たとえば、"chr1"というバケツの内容物にDictionaryを入れようと
するときは
dic("chr1") = CreateObject("Scripting.Dictionary")
とします。
┃ ┃ ┃│ │ ┃
┃ ┃ ┃│ │ ┃
┃1049797 ┃ ┃│ │ ┃
┃1048371 ┃ ┃└──┘ ┃
┗━━━━┛ ┗━━━━━┛
[ER_1_Carrol] [chr1]
(とりあえず きょうはここまで)
|
|