パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)

各種データの集計

必要に迫られて作ったデータ集計用のマクロを2個紹介します。ちょっとアレンジすれば、いろんな
ケースのデータ集計、整理に応用できるでしょう。

1 前回との差を計算する

これは、おじさんのホームページの各ページのページビューの累計データ(多い順に並んでいる)から、
前回(前月)との差を計算するために作ったものです。差をとることにより、今回(今月)のアクセス数を
割り出させる目的で作りました。ページ数が100以上になっているので、自分で手計算はかったるい
です絶対やらないでしょう)。こういうものはEXCELにやらせるのが一番です。非常に短いシンプルな
マクロですが、いろんな例に応用できるでしょう。

例えば、得点順に並んでいるテストのデータから、前回との得点差を計算させる、というようなケース
にはほとんど手直しなしで使えます。(図1の例)
データが名簿順に並んでいれば、セルに簡単な計算式を入れて計算させるだけで済みますが、得点順
にデータが並んでいると、そう簡単にはいきません。同一人物を見つけ出して、手計算して1個1個、差を
求めるという気の遠くなる作業が待っています。もしデータが500もあったらお手上げですね。
そんなときは、マクロを組んでEXCELにやらせましょう。

(図1)


VBAのコードは以下の通りいたってシンプルです。
標準モジュール Module1はUserForm1を表示するだけです。

UserForm1
@からDは、TextBoxに入力された列のデータ("A"とか"B"とか)をA列なら1, B列なら2になるように
変換しています。これはアスキーコードで大文字のAが65、Bが66、Cが67となっていることをうまく利用
しています。Cellsメソッドを上手に使うためにEXCELでよく使う技のひとつです。
ここではかなり手を抜いたコードにしているので列は"A"から"Z"までしか有効に使えません。
もっと多くの列(AA以降)を使えるようにするには、どうしたらいいかは皆さんで工夫して下さい。

E、Fはデータの入っている終端セルを探す常套手段ですね。詳しくはセル関連基本マクロ1に終端セル
取得方法について記述してありますので、参考にして下さい。

Gから始まるFor ループでは、キーが一致したら、そこの値の差をとるという作業をしています。

標準モジュール Module1
Sub Form_show()
UserForm1.Show
End Sub


フォーム UserForm1
Private Sub CommandButton1_Click()
keya = TextBox1.Text: c1 = Asc(keya) - 64   '@
keyb = TextBox2.Text: c2 = Asc(keyb) - 64   'A
Vala = TextBox3.Text: c3 = Asc(Vala) - 64    'B
valb = TextBox4.Text: c4 = Asc(valb) - 64    'C
out = TextBox5.Text: c5 = Asc(out) - 64     'D
e = ActiveSheet.Cells(65536, c1).End(xlUp).Row  'E
f = ActiveSheet.Cells(65536, c2).End(xlUp).Row  'F
For i = 1 To f                       'G
For j = 1 To e
If Cells(i, c2).Value = Cells(j, c1).Value Then
Cells(i, c5).Value = Cells(i, c4).Value - Cells(j, c3).Value
End If

Next j
Next i

End Sub



2 正規表現で一致したデータを集計する

営業の売り上げデータなどをEXCELで管理することがあるかと思います。ここで紹介するのは、案件毎に
記入された売り上げデータから、営業担当や製品をキーに、tanakaならtanakaだけの、CobolならCobolだけの
売り上げ、利益を抽出し集計するマクロです。

これもEXCELに備わっている各種機能や、セルに計算式を入れていけばできるものですが、営業担当が
複数名ついたり、製品が複数だったりすると結構やっかいなことになります。
そこで、以下の図2のようにまとめられたデータから、担当別、製品別の集計を簡単に出すための汎用的
なマクロを組みました。
図2では、担当者(Name)をキーとし、"kato"が関わっている(単独あるいは、複数で担当)した案件の
売り上げ(Sales)と利益(Margine)を集計させました。利益はほんとうはProfitとすべきでしょうが、ま、
いいじゃないですか




UserForm1
@からの3行で検索する範囲に入力されたデータをCellsメソッドに渡せるように数値データに変換しています。
例えば上記のようにTextBox1に"A2"、TextBox2に"A12"を入力すると、列データと行データに分解し、
c1=1, r1=2, c2=1, r2=12 を得ます。

A変数q にキーワードを代入します。

BこのForループでキーワードに合致する項の値を集計します。キーワードと合致するかどうかは
a Like ("*" + q + "*") という条件式で判定しており、キーワードを含んでいれば合致すると判定
しています。
上記の例では、"kato"そのものだけでなく、"kato"を含む全ての項("takano/kato"など)を集計しています。

以下同様に、3列分の集計ができるようになっています。

Sub user_Form_show()
UserForm1.Show

End Sub


Private Sub CommandButton1_Click()
l1 = Len(TextBox1.Text): l2 = Len(TextBox2.Text)                      '@
c1 = Asc(Mid(TextBox1.Text, 1, 1)) - 64: r1 = Val(Mid(TextBox1.Text, 2, l1 - 1))
c2 = Asc(Mid(TextBox2.Text, 1, 1)) - 64: r2 = Val(Mid(TextBox2.Text, 2, l2 - 1))

q = TextBox3.Text                 'A

If TextBox4.Text <> "" Then
c4 = Asc(Mid(TextBox4.Text, 1, 1)) - 64

t = 0
For i = r1 To r2                   'B
a = Cells(i, c1).Text
If a Like ("*" + q + "*") Then
t = t + Val(Cells(i, c4).Value)
End If
Next
TextBox7.Text = Str$(t)

End If

If TextBox5.Text <> "" Then
c5 = Asc(Mid(TextBox5.Text, 1, 1)) - 64
t = 0
For i = r1 To r2
a = Cells(i, c1).Text
If a Like ("*" + q + "*") Then
t = t + Cells(i, c5).Value
End If
Next
TextBox8.Text = Str$(t)
End If

If TextBox6.Text <> "" Then
c6 = Asc(Mid(TextBox6.Text, 1, 1)) - 64
t = 0
For i = r1 To r2
a = Cells(i, c1).Text
If a Like ("*" + q + "*") Then
t = t + Cells(i, c6).Value
End If
Next
TextBox9.Text = Str$(t)
End If

End Sub









TopPage > Visual BasIc&Excel活用研究目次