集計表からグラフを自動作成・更新する(月別売上の棒+利益率の折れ線)

公開日:2026年10月7日 執筆:Takuya カテゴリ:帳票・メール連携

月別の集計表から、売上を棒グラフ、利益率を第2軸の折れ線グラフにした複合グラフを VBA で作成します。2回目以降は同じグラフのデータ範囲だけを更新する書き方も解説します。

どんな場面で使うか

月次の会議資料で、売上の推移と利益率を1つのグラフにまとめて見せることはよくあります。毎月データが1行ずつ増えるたびにグラフの範囲を手で直していると、範囲の指定漏れで最新月がグラフに出ていない、といったミスが起きがちです。

このマクロは、集計表の最終行を毎回調べて、グラフがなければ新しく作り、あれば同じグラフのデータ範囲だけを付け替えます。何度実行してもグラフが増え続けることはありません。

前提とする集計表

「月別集計」シートに、次のような表があるものとします(説明用の例です)。1行目が見出し、2行目から月ごとのデータです。利益率は 0.25 のような小数で入れ、表示形式でパーセントにしておきます。

  • A列:年月(「2026/04」などの文字列、または日付)
  • B列:売上
  • C列:利益率

コード

グラフには名前を付けておき、その名前で既存のグラフを探します。見つからなければ ChartObjects.Add で作成します。データ範囲は SetSourceData で売上と利益率の2列を指定し、横軸の項目(年月)は各系列の XValues に明示的に設定しています。

Sub UpdateSalesChart()
    Const CHART_NAME As String = "月別売上グラフ"
    Dim ws As Worksheet, co As ChartObject, ch As Chart
    Dim lastRow As Long, i As Long

    Set ws = ThisWorkbook.Worksheets("月別集計")
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    If lastRow < 2 Then MsgBox "集計データがありません": Exit Sub

    ' 既存のグラフを名前で探す(なければ Nothing のまま)
    On Error Resume Next
    Set co = ws.ChartObjects(CHART_NAME)
    On Error GoTo 0

    If co Is Nothing Then
        With ws.Range("E2")
            Set co = ws.ChartObjects.Add(Left:=.Left, Top:=.Top, Width:=520, Height:=300)
        End With
        co.Name = CHART_NAME
    End If

    Set ch = co.Chart
    ch.ChartType = xlColumnClustered
    ch.SetSourceData Source:=ws.Range("B1:C" & lastRow), PlotBy:=xlColumns

    ' 横軸の項目を年月の列にそろえる
    For i = 1 To ch.SeriesCollection.Count
        ch.SeriesCollection(i).XValues = ws.Range("A2:A" & lastRow)
    Next i

    ' 2つ目の系列(利益率)を第2軸の折れ線にする
    With ch.SeriesCollection(2)
        .ChartType = xlLineMarkers
        .AxisGroup = xlSecondary
    End With

    ch.HasTitle = True
    ch.ChartTitle.Text = "月別売上と利益率"
    ch.HasLegend = True
    ch.Legend.Position = xlLegendPositionBottom
    ch.Axes(xlValue, xlPrimary).TickLabels.NumberFormatLocal = "#,##0"
    ch.Axes(xlValue, xlSecondary).TickLabels.NumberFormatLocal = "0%"
End Sub

コードのポイント

ChartObjects.Add の位置と大きさはポイント単位で指定します。セルの Left と Top を使うと「E2 セルの位置に置く」という指定ができ、列幅を変えてもおおよその位置がずれにくくなります。

SetSourceData に年月の列まで含めると、年月が数値や日付で入っている場合に、Excel がそれを「系列」の1つとして扱ってしまうことがあります。そこで、数値の列だけを SetSourceData に渡し、横軸の項目は XValues で別に指定しています。こうしておけば、年月の入れ方に関係なく同じグラフになります。

既存のグラフを名前で探して使い回すため、2回目以降はデータ範囲と書式だけが更新されます。グラフの位置や大きさを手で調整した場合も、その調整は保たれます。

よくある失敗と注意点

On Error Resume Next でグラフを探したあと、On Error GoTo 0 に戻し忘れると、その後のエラーがすべて無視され、グラフが崩れていても気付けません。エラーを無視するのは、存在確認の1行だけにします。

  • グラフ名を変えると「見つからない」と判定され、新しいグラフが追加される
  • 系列の順番は SetSourceData に渡した列の順なので、列を入れ替えると折れ線になる系列も変わる
  • 利益率をパーセントの数字(25 など)で入れると、第2軸の表示が 2500% のようになる
  • 日付の軸は、間のない月があると自動で日付軸になり、棒の間隔が空くことがある(その場合は年月を文字列にする)

応用

部門別に同じ形式のシートがある場合は、このマクロのシート名を引数にして、シートごとに呼び出せばまとめてグラフを更新できます。作成したグラフを報告書に貼るときは、co.Chart.Export でファイル名を指定すると PNG 画像として保存することもできます。

※グラフの種類を表す定数(xlColumnClustered など)は Excel のバージョンによって見た目が多少異なります。

ほかの記事