|
▼こまつ さん:
>▼kanabun様
>
>元データに配列を格納の箇所をご教示願えないでしょうか?
どういう問題だったか忘れてしまったので、
もういちど整理してみました。
>D1〜K1まで日付が2009/3/2〜2009/3/9まで入っております。
▼
'--------------------------------------------------------------
' C D E F G H I J K
'1 3/2 3/3 3/4 3/5 3/6 3/7 3/8 3/9
'2 A
'3 B
'4 C
'5 D
'6 E
'--------------------------------------------------------------
▼
>D8〜D65536に同じく上記の範囲で日付が入っております。
>I8〜I65536には、A,B,C,D,Eがそれぞれランダムに入っております。
'--------------------------------------------------------------
' D列 ・・・ ・・・ I列
' 7 日付 種別
' 8 3月2日 A
' 9 3月2日 A
'10 3月2日 B
'11 3月2日 D
'12 3月2日 A
'13 3月2日 A
'14 3月2日 B
'15 3月3日 B
'16 3月3日 B
'17 3月3日 B
'18 3月3日 C
' : : :
' : : :
'
'
'--------------------------------------------------------------
▼
>D2: K6までに集計数を記入したい。
>D2は、Aの集計 D3はBの集計、D4はCの集計というように集計し日別表を
>作成したいのです。
つまり、日付別、種別でクロス集計したい、ということですね?
↓クロス集計後のイメージ
'--------------------------------------------------------------
' C D E F G H I J K
'1 3/2 3/3 3/4 3/5 3/6 3/7 3/8 3/9
'2 A 8 8 12 48 281 37 3 4
'3 B 7 6 9 41 234 31 2 3
'4 C 6 5 7 33 187 25 1 3
'5 D 10 15 15 72 421 57 4 7
'6 E 6 9 12 48 281 37 3 4
'--------------------------------------------------------------
CountIf的な考え方でいうと、
[D2]セルに D列のデータが 「3月2日」で、
かつ、I列のデータが「A」である行の数を、
[E2]セルに D列のデータが 「3月3日」で、
かつ、I列のデータが「A」である行の数を、
[D3]セルに D列のデータが 「3月2日」で、
かつ、I列のデータが「B」である行の数を、
という風に 2条件で CountIfしたい、ということですね?
余談(
Excel2007 で登場したCountIfs関数を使うと、
[D2] =COUNTIFS(D8:D6000,D8:D6000,D1,I8:I6000,C2)
ということですね?)
数式はセル単位にセットされますから、
[D2]セルの数式が答えを得るために元データを上から下まで走査し、
[D3]セルの数式が答えを得るためにまた元データを上から下まで
走査しています。
集計表の各セルが同じ集計範囲を個々の条件で走査していますから
表がおおきいと重くなります。
こういう集計はピボットテーブル機能が得意とするところであること
はさておいて、
「連想配列」による方法は考え方を変えて、元データのほうを
一回だけ走査して、D列の日付とI列の種別を組みとして、各組みの
出現回数をカウントします。
元データが
> D列 ・・・ ・・・ I列
> 7 日付 種別
> 8 3月2日 A
> 9 3月2日 A
>10 3月2日 B
>11 3月2日 D
のようにあるとき、
最初のレコード(8行目)は 日付が「3月2日」で種別が「A」ですから、
「3月2日A」というラベルのついた入れ物をひとつ用意し、この容器の
なかに 数値1 を代入しておきますと、「3月2日A」というキーは1回
出現したとCountされたことになります。
次の行(9行目)のレコードからラベル(キー)を作ると 最初のレコード
同様、「3月2日A」というラベルです。このラベルのついた容器はすでに
用意されているので、「3月2日A」というラベルの入れ物に +1 してやり
ます。
次の行(10行目)のレコードからラベル(キー)を作ると「3月2日B」と
なります。そしたら 「3月2日B」の容器に +1 してやればいいわけです
(「3月2日B」という容器はまだ作られていませんでしたが、
「3月2日B」という容器に+1しなさい
>> ss = aryDate(i, 1) & aryKind(i, 1) '容器のラベル(キー)
>> dic(ss) = dic(ss) + 1 'その容器に1を加算
とコードを書いておけば、まだそういう名前の容器が存在しなければ
自動で用意してくれます。)
といった手順で、全レコードを「日付と種別」別に用意された容器内に
出現回数を入れておきますと、
あとは集計表の 列見出しと行見出しをみて
[D2] = 「3月2日A」という容器のなかの数量
[D3] = 「3月2日B」という容器のなかの数量
...
と集計表の各セルに答え(カウント結果)を転記していけばいいわけです。
したがいまして、
>> '元データを配列に格納
>> Set r = Range("D8", Cells(Rows.Count, "D").End(xlUp))
> →変数rにDの最終行からD8までを代入する。
↑ちょっとちがいます
⇒Range型の変数r にD8からD列最終行までの範囲を「Set」する
ということです。
>> aryDate = Application.Text(r, "mmdd")
> →変数aryDateは、変数rに代入した配列の表示形式をmmddとする?
> →"mmdd"とは〇〇月〇〇日のことでしょうか?
> →元データの表示形式は、2009/3/1です。その場合は"yyyymd"
> でいいのでしょうか?
⇒表示形式は何でもかまいません。準備するカウント用容器につける
ラベル名(これを Key といいます)が一意に識別できる文字列で
あれば、なんでもいいです。
日付データが2年間にわたるものであれば、年度の情報も必要となり
そのばあいは "yyyymd" とかにしてください。
>> aryKind = r.Offset(, Asc("I") - Asc("D")).Value
> →変数aryKindには、変数rのどこがはいるんだろうか?
> Range("A1").Offset(1,1)はB2ですよね?
> Asc("I")-Asc("D")っていくつになるんですか?
⇒r はいま D列の範囲です。
rの実際の範囲が[D8:D6000]としますと、
r.Offset(, 1) は [E8:E6000] ですよね?
おなじように、
r.Offset(, Asc("I") - Asc("D") は どこになりますか?
|
|