基本統計量の計算
Excelには合計,平均,分散などといった基本統計量を計算するためのワークシート関数が用意されていますが,ここではそれらの関数は使用せずにVBAで各統計量を計算するプログラムコード書いてみましょう。
1. 合計を計算するためのVBAコード
Sub sum_prog() Dim R As Range, result As Range Dim dat As Variant Dim i As Integer, n As Integer Dim goukei As Double MsgBox "データは行方向に入力されており,かつ1列である必要があります" Set R = Application.InputBox(prompt:="データ範囲を選択", Title:="合計の計算", Type:=8) n = R.Rows.Count dat = R '合計の計算 goukei = 0 For i = 1 To n goukei = goukei + dat(i, 1) Next '結果の表示 Set result = Application.InputBox(prompt:="結果を表示するセル", Title:="合計の計算", Type:=8) result = goukei End Sub
2. 平均を計算するためのコード
上の合計を求めるプログラムコードと同じものを書いてもしょうがないので,少し発展して,データ入力されているセル範囲が2列以上であり,かつ選択したセル範囲内に空白があっても計算できるようにしてみた。
Sub sum_prog() Dim R As Range, result As Range Dim dat As Variant Dim i As Integer, j As Integer Dim nrow As Integer, ncol As Integer, n As Integer Dim kuhaku As Integer, a As Range Dim goukei As Double, heikin As Double Set R = Application.InputBox(prompt:="データ範囲を選択", Title:="合計の計算", Type:=8) nrow = R.Rows.Count 'セル範囲の行数をカウント ncol = R.Columns.Count 'セル範囲の列数をカウント kuhaku = 0 For Each a In R '選択したセル範囲において,もし空白があればカウントしていく If a.Value = "" Then kuhaku = kuhaku + 1 Else End If Next n = (nrow * ncol) - kuhaku 'データ数の取得 dat = R '選択したセル範囲のデータをdatに代入 '合計の計算 goukei = 0 For i = 1 To ncol For j = 1 To nrow goukei = goukei + dat(j, i) Next Next heikin = goukei / n '平均の計算 '結果の表示 Set result = Application.InputBox(prompt:="結果を表示するセル", Title:="合計の計算", Type:=8) result = heikin End Sub
3. 分散を計算するためのVBAコード
実際には上のコードに数行コードを追加するだけで分散の計算が可能である。しかし,選択したセル範囲に空白があると分散は計算できないので,さらに改良したものをあえて紹介する。
今回は分散を計算するためのサブプロシージャとメインとなるプロシージャの2つが用意されている。下のものはサブプロシージャをメインプロシージャの下側に書いても問題ないが,C言語の名残で私はサブプロシージャは上に書くようにしている。
ちなみにメインプロシージャは最後の1行を除いて,前述した平均を求めるためのプロシージャと全く同じである。
'分散を計算するためのサブプロシージャ Sub var(dat As Variant, n As Integer, nrow As Integer, ncol As Integer, heikin As Double) Dim i As Integer, j As Integer, myCount As Integer Dim mySum As Double, bunsan As Double Dim result As Range Dim myData() As Double ReDim myData(n) '配列の大きさを指定 'datに格納されているデータをmyDataに代入し直す myCount = 0 For i = 1 To ncol For j = 1 To nrow myCount = myCount + 1 If dat(j, i) <> "" Then '空白でない場合 myData(myCount) = dat(j, i) ElseIf dat(j, i) = "" Then '空白である場合 myCount = myCount - 1 End If Next Next '分散の計算 For i = 1 To n mySum = mySum + (myData(i) - heikin) ^ 2 Next bunsan = mySum / n '結果の表示 Set result = Application.InputBox(prompt:="結果を表示するセル", Title:="合計の計算", Type:=8) result = bunsan End Sub 'メインとなるプロシージャ Sub sum_prog() Dim R As Range Dim dat As Variant Dim i As Integer, j As Integer Dim nrow As Integer, ncol As Integer, n As Integer Dim kuhaku As Integer, a As Range Dim goukei As Double, heikin As Double Set R = Application.InputBox(prompt:="データ範囲を選択", Title:="合計の計算", Type:=8) nrow = R.Rows.Count 'セル範囲の行数をカウント ncol = R.Columns.Count 'セル範囲の列数をカウント kuhaku = 0 For Each a In R '選択したセル範囲において,もし空白があればカウントしていく If a.Value = "" Then kuhaku = kuhaku + 1 Else End If Next n = (nrow * ncol) - kuhaku 'データ数の取得 dat = R '選択したセル範囲のデータをdatに代入 '合計の計算 goukei = 0 For i = 1 To ncol For j = 1 To nrow goukei = goukei + dat(j, i) Next Next heikin = goukei / n '平均の計算 Call var(dat, n, nrow, ncol, heikin) '分散の計算をするためのプロシージャを呼び出す End Sub
コードの解説
'datに格納されているデータをmyDataに代入し直す myCount = 0 For i = 1 To ncol For j = 1 To nrow myCount = myCount + 1 If dat(j, i) <> "" Then '空白でない場合 myData(myCount) = dat(j, i) ElseIf dat(j, i) = "" Then '空白である場合 myCount = myCount - 1 End If Next Next
これは2次配列(=行列)に格納されているデータを1次配列(=ベクトル)に格納し直している。理由は空白を無くすためである。空白があると分散の計算過程,すなわち
(i番目のデータ - データの平均)^2
の部分で (0 - データの平均)^2 と同じことになってしまい,正しい分散値が計算できないのである。
この問題を解決するために「もし空白でなければ格納されているデータをmyDataに格納しなおす」,あるいは「もし空白であれば(データが格納されていなければ)何もせずに処理を続ける」というコードを書いている。
まぁ,実際にはこのような面倒なコードを書く必要はない。なぜなら空白を作らないようにデータを入力すれば済むということだけの話だからだ。