Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ グラフの自動化 | テーブルとレポートの自動化
ビジネス自動化のためのExcel VBA

グラフの自動化

メニューを表示するにはスワイプしてください

グラフはワークシート上に配置された図形であり、本章の他の要素と同様に、書式設定ウィンドウで手動設定するすべてのプロパティにはVBAでの対応があります。

図4.4

グラフの作成

Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject
 
    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
 
    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent
 
    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub
各行の詳細解説
expand arrow
  • AddChart2 はチャートシェイプ自体を作成 — Style:=201 は組み込みのビジュアルスタイルを選択し、XlChartType:=xlColumnClustered は標準の集合縦棒グラフを選択、Left/Top/Width/Height でワークシート上の位置とサイズをポイント単位(Excel が内部的に図形配置に使用する単位)で指定;
  • AddChart2 は実際には ChartObject のコンテナではなく Chart オブジェクト自体を返す — 行末の .Chart.Parent でコンテナに戻る。これは chartObj が宣言されている型であり、この仕様は忘れやすいため正確にコピーする価値がある;
  • SetSourceData は、空のチャートシェイプにどのデータをプロットするかを指定するもの — tbl.ListColumns("Profit").Range を指定すると、Table のすべての表示行の Profit 列がグラフ化される;
  • HasTitle = True を設定してから ChartTitle.Text を割り当てる必要がある — タイトルがまだ有効でないチャートにタイトルテキストを設定しようとすると失敗する。

グラフデータの更新

基となるテーブルが拡張された場合、グラフを削除して作り直すのではなく SetSourceData で新しい範囲を指定することで、既存の手動書式設定を保持できる:

Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range

ChartObjects(1) はシート上の最初のチャートシェイプを位置で参照 — チャートが1つだけなら問題ないが、2つ目以降が追加されると「最初」の意味が変わるため脆弱。明示的に設定した名前で参照する(chartObj.Name = "ProfitChart" の後に ChartObjects("ProfitChart")))方が、複数チャートがある場合はより堅牢。

グラフの書式設定

With chartObj.Chart
    .ChartTitle.Font.Size = 14
    .ChartTitle.Font.Bold = True
    .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
    .Axes(xlValue).TickLabels.NumberFormat = "#,##0"
    .HasLegend = False
End With

SeriesCollection(1) は最初(ここでは唯一)のデータ系列 — その Format.Fill.ForeColor.RGB で実際の棒グラフの色を指定し、Chapter 1 の書式設定例と同じ RGB(...) 関数を使用。Axes(xlValue) は数値軸(xlCategory は地域名をリストする軸)を指し、NumberFormat を適用することで、その軸上の数値の表示形式を制御できる。HasLegend = False で凡例を完全に非表示にでき、系列が1つだけのグラフでは凡例が不要な情報を増やすだけなので推奨される。

タスク

  1. BuildProfitChart を実行し、全15行(3か月分、フィルターなし)の Profit を示す縦棒グラフが表示されることを確認。
  2. 上記例の通り、グラフの棒をダークグリーン(RGB(24,106,60))に着色し、凡例を削除する3行を追加。
  3. tblReports を1月だけにフィルターし、SetSourceDatatbl.ListColumns("Profit").Range に対して再実行 — グラフがフィルターを反映するか確認。
ヒント
expand arrow

1. BuildProfitChart の実行

  • この章で示された Sub をそのままコピーして実行 — この部分は変更不要。
  • レポートシートに、現在テーブルで表示されている各行の利益をプロットしたグラフが表示されるはず。

2. 棒グラフの色付けと凡例の削除

  • どちらのプロパティもワークシートではなくチャートオブジェクトに属する — chartObj.Chart がエントリーポイント(章の書式設定例と同様)。
  • 棒グラフの色は SeriesCollection(1) に設定(プロットされているデータ系列は利益のみ)— .Format.Fill.ForeColor.RGB が設定対象のプロパティ。
  • 凡例の削除は、塗りつぶしの設定とは別の単一のブールプロパティ(HasLegend)。

3. フィルター適用と SetSourceData の再実行

  • 月(AutoFilter)に「January」の Field:=1 を適用 — セクション4.2と同じ手法。
  • その後、SetSourceData で使ったのと全く同じ tbl.ListColumns("Profit").Range 式で BuildProfitChart を再度呼び出す — この行は変更不要。
  • その後のグラフの挙動をよく観察:1月の5地域だけに縮小されるか、それとも AutoFilter で非表示にした行も含めて全15行が表示され続けるか?この観察が本タスクの本質であり、単にコードを実行することが目的ではない。
解答例
expand arrow
Option Explicit

' Point 1 — run this exactly as shown in the chapter
Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")

    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent

    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub

' Point 2 — color the bars and remove the legend
Sub FormatProfitChart()
    Dim ws As Worksheet
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set chartObj = ws.ChartObjects(1)

    With chartObj.Chart
        .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
        .HasLegend = False
    End With
End Sub

' Point 3 — filter to January, then re-point the chart at the same range
Sub FilterJanuaryAndRefreshChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
    Set chartObj = ws.ChartObjects(1)

    tbl.Range.AutoFilter Field:=1, Criteria1:="January"

    chartObj.Chart.SetSourceData Source:=tbl.ListColumns("Profit").Range
End Sub

この順番で実行:BuildProfitChart、次に FormatProfitChart、最後に FilterJanuaryAndRefreshChart。特にポイント3では、実際に何が起こるかに注目。Excel のグラフは通常、アクティブな AutoFilter を自動的に反映し、フィルターで除外された行の棒グラフを非表示にする(SetSourceData を再実行しなくても)。ここで再実行するのは、グラフが正しく列全体を参照していることを確認するためであり、実際に表示を制御しているのはフィルター自体であって SetSourceData ではない。フィルターのオン・オフ両方で挙動を確認する価値あり。

Note
注意

BuildProfitChart を複数回実行すると、毎回新しいグラフが作成され、古いグラフは削除されずに重なっていく。そのため、ChartObjects(1) は常に最初に作成されたグラフを指し、後から作成された新しいグラフの下に隠れている場合がある。これが、書式変更が正常に実行されても見た目に変化がないように見える理由。

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 4.  4

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

セクション 4.  4
some-alt