Excel VBA 逆引き集 | 部分合計の作成

Excel VBA
スポンサーリンク

部分合計の作成

「グループごとに合計行を差し込む」「フィルタ後の表示分だけを合計する」「テーブルで合計行を出す」などの場面を、初心者向けに最短コードでまとめました。Excelの“部分合計”は大きく3系統です。Range.Subtotal(行を差し込む自動集計)、ワークシート関数SUBTOTAL(見えているセルの集計)、ListObject(テーブル)の合計行。用途に合わせて使い分けましょう。


基本1:行を差し込む「自動・見た目の部分合計」

Sub Subtotal_InsertRows_Basic()
    '見出しがA1、表はA1からの連続領域
    Dim rg As Range
    Set rg = Range("A1").CurrentRegion

    '前提:集計基準列(例:部門)が事前にソート済み
    rg.Sort Key1:=rg.Columns(2), Order1:=xlAscending, Header:=xlYes

    '部分合計を挿入(部門=2列目でグループ、金額=5列目を合計)
    rg.Subtotal GroupBy:=2, Function:=xlSum, TotalList:=Array(5), _
                Replace:=True, PageBreaks:=False, SummaryBelowData:=True
End Sub
VB
  • ポイント:
    • GroupBy: 見出しから数えて「何列目」でグループ化するか。
    • TotalList: 集計したい列の番号配列(複数列OK)。
    • ソート必須: GroupBy列を事前に並べておくと意図通りにまとまる。

基本2:フィルタや手動非表示に強い「SUBTOTAL関数」

Sub Subtotal_VisibleOnly()
    Dim last As Long
    last = Cells(Rows.Count, "E").End(xlUp).Row '金額=E列

    '見出しの右(G2)に「表示中だけ」の合計を出す
    Range("G2").Formula = "=SUBTOTAL(9,E2:E" & last & ")"
End Sub
VB
  • ポイント:
    • 9(SUM): 非表示行も含めた合計。
    • 109(SUM): フィルタや手動非表示を除外して「見えているセルだけ」合計。
    • VBAで値取得: WorksheetFunction.Subtotal(9, Range(“E2:E” & last)) でもOK。

目的別テンプレート

'1) フィルタで表示中だけの金額合計をセルへ(数式不要で即値)
Sub Sum_VisibleToCell()
    Dim last As Long, s As Double
    last = Cells(Rows.Count, "E").End(xlUp).Row
    s = Application.WorksheetFunction.Subtotal(109, Range("E2:E" & last))
    Range("G2").Value = s
End Sub

'2) 複数列を同時に部分合計挿入(部門ごとに数量・金額)
Sub Subtotal_InsertRows_MultiColumns()
    Dim rg As Range: Set rg = Range("A1").CurrentRegion
    rg.Sort Key1:=rg.Columns(2), Order1:=xlAscending, Header:=xlYes
    rg.Subtotal GroupBy:=2, Function:=xlSum, TotalList:=Array(4, 5), _
                Replace:=True, PageBreaks:=False, SummaryBelowData:=True
End Sub

'3) 部門ごとに小計行+最後に総合計行を追加
Sub Subtotal_WithGrandTotal()
    Dim rg As Range: Set rg = Range("A1").CurrentRegion
    rg.Sort Key1:=rg.Columns(2), Order1:=xlAscending, Header:=xlYes
    rg.Subtotal GroupBy:=2, Function:=xlSum, TotalList:=Array(5), _
                Replace:=True, PageBreaks:=False, SummaryBelowData:=True
    '最終行の次に総合計を出す(見出し除く全E列)
    Dim last As Long: last = Cells(Rows.Count, "A").End(xlUp).Row
    Cells(last + 1, "D").Value = "総合計"
    Cells(last + 1, "E").Formula = "=SUBTOTAL(9,E2:E" & last & ")"
End Sub
VB
  • ラベルのヒント:
    • 109の意味: フィルタなどで非表示のセルを除外。
    • Replace:=True: 既存の部分合計があれば置き換え。二重小計防止。
    • Grand total: SUBTOTAL(9, …) は非表示も含めた全体合計に便利。

テーブルでの部分合計(ListObject)

Sub Subtotal_ListObject_TotalsRow()
    Dim lo As ListObject
    Set lo = ActiveSheet.ListObjects("売上テーブル")

    '合計行(TotalsRow)を表示
    lo.ShowTotals = True

    '金額列の合計を設定(列名で指定)
    lo.ListColumns("金額").TotalsCalculation = xlTotalsCalculationSum
End Sub
VB
  • ポイント:
    • TotalsRow: テーブル下部に小計・平均などを表示。
    • 列名指定: 列を入れ替えても壊れにくい。
    • フィルタ連動: テーブルのフィルタ結果に連動して合計が変わる。

例題で練習

例題1:部門ごとの金額小計行を自動挿入して印刷

Sub Example_SubtotalAndPrint()
    Dim rg As Range: Set rg = Range("A1").CurrentRegion
    rg.Sort Key1:=rg.Columns(2), Order1:=xlAscending, Header:=xlYes
    rg.Subtotal GroupBy:=2, Function:=xlSum, TotalList:=Array(5), _
                Replace:=True, PageBreaks:=True, SummaryBelowData:=True
    ActiveSheet.PrintOut
End Sub
VB

例題2:今月の表示行だけ金額合計をG2へ(即値)

Sub Example_VisibleThisMonthSum()
    Dim rg As Range: Set rg = Range("A1").CurrentRegion
    Dim d1 As Date, d2 As Date
    d1 = DateSerial(Year(Date), Month(Date), 1)
    d2 = DateSerial(Year(Date), Month(Date) + 1, 0)
    rg.AutoFilter Field:=4, Criteria1:=">=" & d1, Operator:=xlAnd, Criteria2:="<=" & d2
    Dim s As Double
    s = Application.WorksheetFunction.Subtotal(109, rg.Offset(1).Resize(rg.Rows.Count - 1).Columns(5))
    Range("G2").Value = s
End Sub
VB

例題3:テーブル右下に合計行を出して金額合計

Sub Example_TableTotalsRow()
    Dim lo As ListObject: Set lo = ActiveSheet.ListObjects("売上テーブル")
    lo.ShowTotals = True
    lo.ListColumns("金額").TotalsCalculation = xlTotalsCalculationSum
End Sub
VB

SUBTOTAL の関数番号(よく使うもの)

  • 9(SUM): 合計。
  • 109(SUM): 合計(非表示を除外)。
  • 1(AVERAGE)/101: 平均(101は非表示除外)。
  • 2(COUNT)/102: 数値カウント。
  • 3(COUNTA)/103: 非空白カウント。

100番台は「フィルタや手動非表示のセルを除外」するモード。


実務の落とし穴と対策

  • 並べ替え忘れで小計が分散: GroupBy列は事前にソートしてから Range.Subtotal を実行。
  • 二重小計の混在: Replace:=True で置き換え、不要な小計行は ClearOutline/再適用。
  • Hiddenの扱い違い: SUBTOTALの9は非表示も含む、109は除外。用途に合わせて選ぶ。
  • フィルタ0件でエラー: SpecialCellsや対象範囲のサイズが0の可能性に備え、Nothingチェックや件数判定を入れる。
  • テーブルと通常範囲の違い: テーブルは TotalsRow を使うのが安全。通常の部分合計挿入は表構造を物理的に変える。
タイトルとURLをコピーしました