|
▼こまつ さん:
> Const COL店舗CD = 1 ' 店舗CDの列
> Const COL分類CD = 3 ' 分類CDの列
> Const COL売上額 = 10 ' 売上額
Const とは 「定数」(プログラムのなかで変化することのない固定値)
を宣言しているわけですね。
Constステートメントについては
ヘルプの目次 より
≪VisualBasic プログラミングのヒント≫ のなかの
≪定数の宣言≫ というトピックを参照してください。
>→Const name = 1でなぜ、1列目みてるのでしょうか?
というか、
> Const COL店舗CD = 1 ' 店舗CDの列
で唱っていることは、このプロシージャのなかで「COL店舗CD」という
文字列に出喰わしたら、そこを数値1 に置き換えて処理するように、と
定義しているわけです。で、「COL店舗CD」という定数Constantがどこで
使われているか見てみると、
> .Cells(r, COL店舗CD)
のように使われている。
では、そもそも
> →Cells(r,COL店舗CD)とは、なんですか?
となる。
そこでまたもや ヘルプの Cellsプロパティの項を開いてみると、
▼Worksheet.Cells プロパティ
ワークシートのすべてのセル (現在使用されていないセルも含む) を
表す Range オブジェクトを返します。
とあり、ワークシート上のすべてのセルの集合(コレクション)を取得
できるものであるらしいことが(一応)解る。
では
> Cells(r,COL店舗CD)
のように、Cellsのうしろのカッコのなかにある2つのパラメータは何か?
Cellsコレクションの解説を読んでいくと、Itemプロパティによってコレ
クション内の個別要素を指定できるらしいことが書いてある。
↓
>Cellsキーワードの後に続けて行および列のインデックスを指定できます。
↓
ということは、Cells(r,COL店舗CD) は Cells.Item(r,COL店舗CD) が省略
されたものであり、ワークシートのすべてのセルの集合のなかの一つの要
素Item (具体的にその位置は 行番号が r で、列番号が COL店舗CD と
いう位置)を指定していることが分かる。。
というわけで、
> Cells(r,COL店舗CD)
は、 COL店舗CD = 1 (列番号) とプログラムの先頭で宣言してあるから、
Cells(r,1) …… 全セルのなかでの要素(r行目、1列目) の単一セル
のことだと分かる?
>MaxRow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row ' 最終行を求める
> →なぜ上の文で最終行を取得できるのでしょうか?
> Rows.Count,1とは、どこをみてるのでしょうか?
Sheet1.Cells(Rows.Count, 1) とは
Sheet1.Cells.Item(Rows.Count, 1) ということで、これは
行番号が ワークシートの全行数(Rows.Count)
列番号が 1
のセル( Cells(65536, 1) ですから セル[A65536] )のことです。
そのあとの .End(xlUp) は キーボードから [Ctrl] + [↑]を押下した動作に
なります。Cells(65536, 1) から [Ctrl] + [↑] としてA列でデータのある
最後のセルにジャンプする操作をマクロ記録してみてください。
すぐ分かります。
同じように、1行目でシートの一番右端 [IV1] に行ってそこから 1行目で
データのあるいちばん左端のセルへジャンプするには [Ctrl] + [←]ですが、
これをコードにするとどうなりますか?
答えは マクロ記録してみるとすぐ分かります。
dicT(key) = dicT(key) + .Cells(r, COL売上額) ' 売上額
> →一回目のdicTには、108400という数字が入ってます。
> →なぜ上の数式で売上額になるのでしょうか?
連想配列 dictionary というものobjectを一から説明するのは至難の業で
す。まず、単独変数ではなく「配列」変数がどういうときに利用されるか
を理解する必要があるでしょう。
あまりいい例ではないのですが、
dim 支店名(1 to 3) as string
dim 売上高(1 to 3) as double
とすると、普通の配列を2個用意したことになります。
そこに、ある月の売上高を代入していくときは = を使います。
支店名(1) = "東京本社"
支店名(2) = "大阪支店"
支店名(3) = "札幌支店"
売上高(1) = 332400
売上高(2) = 65900
売上高(3) = 33240
札幌支店の売り上げは? 「札幌支店」の配列内のIndexが 3であるこ
とが分かっていれば、 MsgBox 売上高(3)
で答えが求まります。では 「札幌支店」の配列内のIndexが 分からない
ときは どうしますか?
for idx = 1 to UBound(支店名)
if 支店名(idx) = "札幌支店" then
MsgBox "札幌支店のIndexは " & idx & " です"
exit for
end if
next
みたいに 支店名配列内から indexを求めておいて 得られたindexを
使って
MsgBox "札幌支店の当月の売上高は " & 売上高(idx)
とします。
では、支店名も分からないとき、さらに、売上高が集計されていない
以下のような表データのときはどうしますか?
A B C
東京本社 3000 2009/1/15
大阪支店 3200 2009/1/15
東京本社 9000 2009/1/20
大阪支店 3000 2009/1/20
札幌支店 4500 2009/1/10
名古屋支店 12300 2009/1/25
このようなときは 連想配列を使います。
dictioanryでは 最初に宣言するのはobjectの使用宣言だけです。
> Set dicT = CreateObject("Scripting.Dictionary")
サイズ(dimension)は宣言しません。そして
レコードの代入は次のように、キーとアイテムのペア(組み)で
レコードをセットします。(↓最初のデータ)
dicT("東京本社") = 3000
これは "東京本社" というラベルをもつ容器に 3000というアイテム
を放り込むことを意味します。一番初めは「東京本社」というラベル
名の容器は存在しませんから、この一行で「東京本社」というラベル
をもった容器が用意され、そのなかに 3000 という数値が入れられる
ことになります。
2度目の「東京本社」のときは すでに 「東京本社」というラベルの
容器は存在しますから、9000を加算すればいいのですが、
dicT("東京本社") = 9000
ではまずいことは分かりますね? この構文では、すでに「東京本社」
容器内にある 3000 という数字が 9000 に置き換えられて、常に最後の
売上高しか残りません。そこで、あなたのコードにあるように、
dicT("東京本社") = dicT("東京本社") + 9000
に修正します。
こう書いておくと、
1回目の「東京本社」データのときには、
dicT("東京本社") = 0 + 3000
2回目の「東京本社」データのときには、
dicT("東京本社") = 3000 + 9000
:
:
のように、支店名別に用意された入れ物に アイテム(売上高)が加算さ
れて集計ができることになります。
連想配列については
Wikipedia より
連想配列(れんそうはいれつ)とは、プログラミング言語において、
添え字にスカラー数値以外のデータ型(文字列型等)も使用できる
配列である。… 連想リスト、連想コンテナ、辞書とも呼ばれる。
連想配列を使う
ht tp://officetanaka.net/excel/vba/tips/tips52.htm
Dictionaryオブジェクトを使って重複しないリストを作成する
ht tp://officetanaka.net/excel/vba/tips/tips80.htm
などが、とっかかりとなるでしょう。
> dicT("東京本社") = dicT("東京本社") + 9000
という記述法以外の書き方もそこに書いてあります。
ま、こういうことはたくさん例題をこなして行くうち、螺旋的に分かって
くることが多いので、分かるところから 実践でどんどん使って慣れてください。
ではでは。
|
|