Excel VBAで合計値からパーセントを計算する方法|配列集計コードに割合計算を追加する例

Visual Basic

Excel VBAで複数列の数値を配列に読み込み、合計値を求めるコードがすでにある場合、その結果を利用してパーセント(割合)を計算することも可能です。

ただし、「黄色い部分をパーセントにしたい」という場合、画像や実際のセル配置が確認できないと、何を分子、何を分母として割合を求めたいのかまでは確定できません。例えば「実績÷目標」「各項目÷合計」「A÷(A+B+C)」では、必要なVBAコードがそれぞれ異なります。

ここでは、提示されているaa6・aa4の配列集計コードを読み解きながら、合計だけでなく割合を計算する基本形と、3列1組のデータからパーセントを出す場合の実装例を解説します。

まず提示されたVBAコードが何をしているか確認する

aa6では、A3から最終行までを基準として12列分の値を配列xへ読み込み、列ごとに縦方向の合計をBoxへ格納しています。最後にA12から右方向へ結果を書き出しています。

中心となる処理は「Box(1, i) = Box(1, i) + x(j, i)」です。これは現在のBoxの値へ各行の値を順番に加算しているため、最終的に各列の合計になります。

一方のaa4では18列のデータをBoxへ読み込み、jを1、4、7……と3列ずつ進めながら、同じ位置にある列をAnsの1~3列へ加算しています。つまりA・D・G……、B・E・H……、C・F・I……というように、3列単位のデータを同じグループごとに集計する構造です。

パーセント計算の基本は「分子÷分母」

VBAだから特別な計算方法が必要になるわけではありません。例えば実績が80、目標が100で達成率を計算したいなら「80 / 100」で0.8が得られます。Excel上で表示形式をパーセントにすれば80%と表示できます。

例えばセルA1の値をB1の値で割ってC1へ結果を入れるだけなら、基本形は「Range("C1").Value = Range("A1").Value / Range("B1").Value」です。

重要なのは、計算結果そのものを100倍して「80」という値にする方法と、0.8という数値をセルへ入れて表示形式を「0%」や「0.0%」にする方法を混同しないことです。Excelで後から計算に使うなら、通常は0.8を保存してセルのNumberFormatをパーセント表示にする方法が扱いやすくなります。

3列1組なら「実績÷合計」などの割合を追加できる

aa4ではAns(i, 1)~Ans(i, 3)に3種類の合計が入ります。そのため、例えば1列目を実績、2列目を目標として「実績÷目標」を4列目へ出したいなら、Ansを4列へ増やして割合を計算できます。

考え方を分かりやすくすると、次のような処理になります。

ReDim Ans(1 To UBound(Box), 1 To 4)

For i = LBound(Box) To UBound(Box)
    For j = 1 To UBound(Box, 2) Step 3
        For a = 0 To 2
            Ans(i, 1 + a) = Ans(i, 1 + a) + Box(i, j + a)
        Next a
    Next j

    If Ans(i, 2) <> 0 Then
        Ans(i, 4) = Ans(i, 1) / Ans(i, 2)
    End If
Next i

Range("M3").Resize(UBound(Box), 4).Value = Ans
Range("P3").Resize(UBound(Box), 1).NumberFormat = "0.0%"

この例ではM・N・O列へ3種類の合計を出し、P列へ「M相当の合計÷N相当の合計」を出す想定です。黄色いセルで求めたい割合の意味がこれと違う場合は、分子と分母だけを変更します。

「各項目が全体の何%か」を求めたい場合

もう一つよくあるのが、3つの集計結果について、それぞれが合計の何%を占めるか求めるケースです。例えばAが20、Bが30、Cが50なら全体は100なので、それぞれ20%・30%・50%となります。

この場合は「A÷(A+B+C)」という計算になります。aa4で集計済みのAnsを使うなら、まずTotalへ3列の合計を入れ、その後で割合を求められます。

Dim Total As Double

Total = Ans(i, 1) + Ans(i, 2) + Ans(i, 3)

If Total <> 0 Then
    Rate1 = Ans(i, 1) / Total
    Rate2 = Ans(i, 2) / Total
    Rate3 = Ans(i, 3) / Total
End If

つまり「パーセントを計算したい」というだけでは計算式は一つに決まりません。黄色いセルが何を基準にした割合なのかを先に決めることが重要です。

aa4を整理して割合まで計算するサンプル

例えばA~R列が3列×6組のデータで、各行について3種類の合計をM~O列へ出し、さらに「1種類目÷2種類目」をP列へパーセント表示したいと仮定すると、次のように整理できます。

Sub aa4_Percent()

    Dim i As Long
    Dim j As Long
    Dim a As Long
    Dim Box As Variant
    Dim Ans() As Variant
    Dim LastRow As Long

    LastRow = Cells(Rows.Count, "A").End(xlUp).Row

    Box = Range("A3:R" & LastRow).Value

    ReDim Ans(1 To UBound(Box, 1), 1 To 4)

    For i = 1 To UBound(Box, 1)
        For j = 1 To UBound(Box, 2) Step 3
            For a = 0 To 2
                If IsNumeric(Box(i, j + a)) Then
                    Ans(i, 1 + a) = Ans(i, 1 + a) + Box(i, j + a)
                End If
            Next a
        Next j

        If Ans(i, 2) <> 0 Then
            Ans(i, 4) = Ans(i, 1) / Ans(i, 2)
        Else
            Ans(i, 4) = ""
        End If
    Next i

    Range("M3:P" & Rows.Count).ClearContents
    Range("M3").Resize(UBound(Ans, 1), 4).Value = Ans
    Range("P3").Resize(UBound(Ans, 1), 1).NumberFormat = "0.0%"

End Sub

このコードなら、元の「3列ごとの足し算」という構造を残しながら、P列へ割合を追加できます。ただしP列で必要なのが「1列目÷2列目」ではない場合は、Ans(i, 1) / Ans(i, 2)の部分を目的に合わせて変更する必要があります。

0で割るエラーには必ず注意する

割合計算をVBAへ追加するときに特に注意したいのが、分母が0の場合です。「Ans(i, 1) / Ans(i, 2)」でAns(i, 2)が0なら、実行時エラーになります。

そのため「If Ans(i, 2) <> 0 Then」のように、割り算の前に0ではないことを確認します。0だった場合は空欄にする、0%にする、「計算不可」と表示するなど、表の目的に応じて決めます。

例えば「0なら0%として扱う」という仕様ならElse側で「Ans(i, 4) = 0」とできます。ただし、分母0は数学的に割合を定義できないため、業務上の意味として0%でよいかは確認したほうが安全です。

元コードでは変数宣言も整理しておくと安全

提示コードの「Dim i, j As Long」は、VBAではiとjの両方がLongになる書き方ではありません。この場合、jはLongですがiはVariantになります。両方をLongにしたいなら「Dim i As Long, j As Long」とそれぞれ型を指定します。

同様に、aもループ変数として使用しているので「Dim a As Long」と明示しておくのがおすすめです。モジュール先頭に「Option Explicit」を記述すると、宣言していない変数の入力ミスも発見しやすくなります。

また「Rows.Count」「Cells」などはActiveSheetを暗黙的に参照します。複数シートを扱うブックでは「Worksheets("Sheet1").Cells」のように対象シートを明示すると、別シートを選択して実行したときの誤動作を防ぎやすくなります。

黄色いセルの位置だけではなく計算式を確認することが重要

添付画像の黄色い部分へパーセントを表示したい場合、コードを完成させるために必要なのは色そのものではなく、そのセルに入るべき計算式です。

例えば「黄色部分=M÷N」なら上記のサンプルで対応できます。「黄色部分=N÷M」「黄色部分=M÷(M+N+O)」「黄色部分=前月との増減率」なら、それぞれ別の式になります。

求めたい値 計算例
達成率 実績 ÷ 目標
構成比 項目 ÷ 全体合計
前年比 今年 ÷ 前年
増減率 (今年-前年)÷ 前年

例えば前年100、今年120なら「今年÷前年」は120%ですが、「(今年-前年)÷前年」で求める増加率は20%です。この2つは似ているようで意味が異なるため、目的を明確にしてからコードへ組み込む必要があります。

まとめ:足し算の配列コードにもパーセント計算は追加できる

Excel VBAで現在のaa6・aa4のように配列を使って合計を計算している場合でも、その集計結果を分子・分母として使えばパーセントを計算できます。計算結果を0.8などの値でセルへ書き込み、「NumberFormat = "0.0%"」などを指定すれば80.0%のように表示できます。

特にaa4は3列ずつの値をAnsへ集計しているため、その集計後に「Ans(i, 1) / Ans(i, 2)」などの計算を追加する形が分かりやすいでしょう。分母が0の場合の処理も忘れないことが重要です。

最終的なコードを決めるには、「黄色いセル=どの数値÷どの数値なのか」を明確にする必要があります。セル位置と期待する計算例、例えば「100と80から80%を出したい」といった具体例が分かれば、既存コードの構造を維持したまま目的に合った割合計算へ変更できます。

コメント

タイトルとURLをコピーしました