この記事でわかること
- VBAでデータ範囲を指定してグラフを自動作成できる(ChartObjects.Add)
- グラフの種類・タイトル・軸ラベル・凡例をコードで一括設定できる
- 月次売上データから棒グラフ+折れ線グラフの複合グラフを自動生成できる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
—
どんな場面で使う?
- 月次報告のたびに同じ形式の売上グラフを手作業で作り直しているとき
- 棒グラフ+折れ線グラフの複合グラフを毎月統一した書式で作りたい
- データ範囲が毎月増減するので、自動でグラフの範囲を追従させたい
- 作ったグラフをPNG画像として書き出してメールやPowerPointに貼りたい
—
完成イメージ(Before / After)
Before(毎月グラフを手作業で作成):
| 操作 | 所要時間 |
|---|---|
| データ範囲を選択 | 約30秒 |
| グラフの種類を選択 | 約30秒 |
| タイトル・軸ラベル・凡例を設定 | 約3分 |
| 書式を整える | 約5分 |
| 合計(1つのグラフ) | 約10分 |
After(VBAで自動作成):
| 操作 | 所要時間 |
|---|---|
| マクロを実行 | 数秒 |
| 書式設定済みのグラフが完成 | 自動 |
—
自分も以前、月次報告のたびにグラフを手作業で作っていた。データ範囲を選択して、グラフの種類を選んで、タイトルを入力して、軸ラベルを設定して……毎回同じ作業を繰り返すのが本当に面倒だった。VBAでグラフ作成を自動化してからは、マクロを実行するだけで書式設定済みのグラフが数秒で完成するようになった。月末の報告書作成が格段に速くなった。同じようにグラフ作成の繰り返しに時間を取られている人に、この記事で自動化を体験してほしい。
グラフの作成・書式設定は手作業だと毎回時間がかかる。VBAで自動化すれば数秒で統一された体裁のグラフが完成する。
なお、グラフに使うデータを事前にフィルターで絞り込みたい場合は 複数条件でデータを抽出してまとめる方法 を参照。
—
実行前の準備
バックアップを取る
既存のグラフがある場合、再実行するとグラフが重複する可能性がある。 必ずファイルのコピーを別フォルダに保存してから実行する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
シート構成を確認する(実務版で使用)
実務版コードは以下のシート構成を前提としている:
- データシート: シート名「売上データ」— A列に月、B列に売上、C列に前年比
基本版・応用版はデータが入っているシートであればシート構成を問わない。
—
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ マクロ名を選んで「実行」
ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。
—
コード(基本版)– ChartObjects.Add でグラフを作成
データ範囲を指定してグラフを作成する最もシンプルな形。まずはこれで動きを確認する。
'============================================================
' ■ データ範囲からグラフを作成する(基本版)
' → 指定したデータ範囲で埋め込みグラフを自動作成
'============================================================
Sub CreateChart_Basic()
'--- ★書き換えポイント ---
Dim wsName As String
wsName = "Sheet1" '← データが入っているシート名
Dim dataRange As String
dataRange = "A1:B13" '← グラフにするデータ範囲
'--- ★ここまで ---
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(wsName)
'--- グラフを作成(埋め込みグラフ)
Dim co As ChartObject
Set co = ws.ChartObjects.Add( _
Left:=ws.Range("D2").Left, _
Top:=ws.Range("D2").Top, _
Width:=400, _
Height:=300)
'--- データ範囲を設定
co.Chart.SetSourceData Source:=ws.Range(dataRange)
MsgBox "グラフを作成しました。", vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
wsName |
データが入っているシート名 | "Sheet1" |
dataRange |
グラフにするデータ範囲 | "A1:B13" |
コードの流れ
- データが入っているシートを取得
ChartObjects.Addでグラフの位置(Left, Top)とサイズ(Width, Height)を指定して作成SetSourceDataでデータ範囲を指定
ポイント: ChartObjects.Add は埋め込みグラフ(シート上に配置されるグラフ)を作成する。Charts.Add はグラフ専用シートを作成するので、通常は ChartObjects.Add を使う。
—
コード(応用版)– グラフの種類・タイトル・軸ラベルを設定
グラフを作るだけでなく、種類(棒・折れ線・円など)、タイトル、軸ラベルまで一括設定する。
'============================================================
' ■ グラフの種類・タイトル・軸ラベルを設定(応用版)
' → グラフ作成+書式設定を一括で実行
'============================================================
Sub CreateChart_Advanced()
'--- ★書き換えポイント ---
Dim wsName As String
wsName = "Sheet1" '← データが入っているシート名
Dim dataRange As String
dataRange = "A1:B13" '← グラフにするデータ範囲
Dim chartTypeSetting As Long
chartTypeSetting = 51 '← グラフの種類(51=集合縦棒 xlColumnClustered)
Dim chartTitle As String
chartTitle = "月次売上推移" '← グラフタイトル
Dim xAxisTitle As String
xAxisTitle = "月" '← 横軸(項目軸)のラベル
Dim yAxisTitle As String
yAxisTitle = "売上(万円)" '← 縦軸(値軸)のラベル
'--- ★ここまで ---
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(wsName)
'--- グラフを作成
Dim co As ChartObject
Set co = ws.ChartObjects.Add( _
Left:=ws.Range("D2").Left, _
Top:=ws.Range("D2").Top, _
Width:=480, _
Height:=320)
With co.Chart
'--- データ範囲を設定
.SetSourceData Source:=ws.Range(dataRange)
'--- グラフの種類を設定
.ChartType = chartTypeSetting
'--- タイトルを設定
.HasTitle = True
.ChartTitle.Text = chartTitle
'--- 横軸(項目軸)のラベルを設定
.Axes(xlCategory).HasTitle = True
.Axes(xlCategory).AxisTitle.Text = xAxisTitle
'--- 縦軸(値軸)のラベルを設定
.Axes(xlValue).HasTitle = True
.Axes(xlValue).AxisTitle.Text = yAxisTitle
'--- 凡例の位置を下に設定
.HasLegend = True
.Legend.Position = xlLegendPositionBottom
End With
MsgBox "グラフを作成しました(種類・タイトル・軸ラベル設定済み)。", vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
wsName |
データが入っているシート名 | "Sheet1" |
dataRange |
グラフにするデータ範囲 | "A1:B13" |
chartTypeSetting |
グラフの種類 | 51(集合縦棒) |
chartTitle |
グラフのタイトル | "月次売上推移" |
xAxisTitle |
横軸のラベル | "月" |
yAxisTitle |
縦軸のラベル | "売上(万円)" |
よく使うグラフの種類(ChartType定数)
| 定数 | 値 | グラフの種類 |
|---|---|---|
xlColumnClustered |
51 | 集合縦棒グラフ |
xlBarClustered |
57 | 集合横棒グラフ |
xlLine |
4 | 折れ線グラフ |
xlLineMarkers |
65 | マーカー付き折れ線 |
xlPie |
5 | 円グラフ |
xlArea |
1 | 面グラフ |
xlXYScatter |
-4169 | 散布図 |
コードの流れ
- データ範囲からグラフを作成
ChartTypeでグラフの種類を設定HasTitle = True→ChartTitle.Textでタイトルを設定Axes(xlCategory)で横軸、Axes(xlValue)で縦軸のラベルを設定Legend.Positionで凡例の位置を設定
ポイント: chartTypeSetting には定数名(xlColumnClustered)ではなく数値(51)を直接指定しても動作する。書き換えやすさを考えて数値で記載してある。
データ範囲を動的に取得したい場合は データの最終行・最終列を正確に取得する方法 を組み合わせると、データが増減しても正しい範囲でグラフが作れる。
—
コード(実務版)– 月次売上データから棒グラフ+折れ線グラフを自動生成
実務で多いパターン:売上を棒グラフ、前年比を折れ線グラフで表示する複合グラフ。既存のグラフを削除してから再作成するので、何度実行しても安全。
棒グラフと折れ線グラフを重ねた複合グラフを毎月手作業で作っていたのが、ボタン1つで完成するようになった。グラフの体裁も毎回統一されるので見栄えも良くなった。
'============================================================
' ■ 月次売上データから棒グラフ+折れ線グラフを自動生成(実務版)
' → 「売上データ」シートのA列=月、B列=売上、C列=前年比
' → 売上は棒グラフ(主軸)、前年比は折れ線グラフ(第2軸)
' → 既存グラフを削除してから作成(再実行対応)
'============================================================
Sub CreateComboChart()
'--- ★書き換えポイント ---
Dim wsName As String
wsName = "売上データ" '← データが入っているシート名
Dim monthCol As Long
monthCol = 1 '← 月が入っている列(A列=1)
Dim salesCol As Long
salesCol = 2 '← 売上が入っている列(B列=2)
Dim ratioCol As Long
ratioCol = 3 '← 前年比が入っている列(C列=3)
Dim dataStartRow As Long
dataStartRow = 2 '← データの開始行(1行目はヘッダー)
Dim chartTitle As String
chartTitle = "月次売上実績と前年比" '← グラフタイトル
'--- ★ここまで ---
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(wsName)
'--- 最終行を取得
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, monthCol).End(xlUp).Row
If lastRow < dataStartRow Then
MsgBox "データがありません。", vbExclamation
Exit Sub
End If
'--- 既存のグラフを削除(再実行対応)
Dim coOld As ChartObject
For Each coOld In ws.ChartObjects
coOld.Delete
Next coOld
'--- グラフを作成
Dim co As ChartObject
Set co = ws.ChartObjects.Add( _
Left:=ws.Cells(2, ratioCol + 2).Left, _
Top:=ws.Cells(2, ratioCol + 2).Top, _
Width:=540, _
Height:=360)
With co.Chart
'--- グラフの種類(まず棒グラフで作成)
.ChartType = xlColumnClustered
'--- データ範囲を手動で設定(系列ごとに指定)
.SetSourceData Source:=ws.Range( _
ws.Cells(1, monthCol), ws.Cells(lastRow, ratioCol))
'--- 売上(系列1): 棒グラフ(主軸)
.SeriesCollection(1).ChartType = xlColumnClustered
.SeriesCollection(1).AxisGroup = xlPrimary
'--- 前年比(系列2): 折れ線グラフ(第2軸)
.SeriesCollection(2).ChartType = xlLineMarkers
.SeriesCollection(2).AxisGroup = xlSecondary
'--- タイトル
.HasTitle = True
.ChartTitle.Text = chartTitle
.ChartTitle.Font.Size = 14
'--- 横軸(項目軸)
.Axes(xlCategory).HasTitle = True
.Axes(xlCategory).AxisTitle.Text = "月"
'--- 主軸(売上)
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Text = "売上(万円)"
.Axes(xlValue, xlPrimary).TickLabels.NumberFormat = "#,##0"
'--- 第2軸(前年比)
.HasAxis(xlValue, xlSecondary) = True
.Axes(xlValue, xlSecondary).HasTitle = True
.Axes(xlValue, xlSecondary).AxisTitle.Text = "前年比(%)"
.Axes(xlValue, xlSecondary).TickLabels.NumberFormat = "0%"
'--- 凡例
.HasLegend = True
.Legend.Position = xlLegendPositionBottom
End With
'--- グラフ名を設定(後から参照しやすくする)
co.Name = "月次売上グラフ"
MsgBox "月次売上グラフを作成しました。" & vbCrLf & _
"データ行数: " & (lastRow - dataStartRow + 1) & " 行", vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
wsName |
データが入っているシート名 | "売上データ" |
monthCol |
月が入っている列 | 1(A列) |
salesCol |
売上が入っている列 | 2(B列) |
ratioCol |
前年比が入っている列 | 3(C列) |
dataStartRow |
データの開始行 | 2(1行目はヘッダー) |
chartTitle |
グラフのタイトル | "月次売上実績と前年比" |
データ表の例
「売上データ」シートに以下のように記入する:
| A列(月) | B列(売上) | C列(前年比) |
|---|---|---|
| 4月 | 1200 | 105% |
| 5月 | 1350 | 110% |
| 6月 | 980 | 95% |
| 7月 | 1100 | 102% |
| 8月 | 1450 | 115% |
| 9月 | 1280 | 108% |
ポイント: 前年比はパーセント表示の数値(105%など)で入力する。セルの書式設定で「パーセンテージ」を選択しておくと、VBA側で NumberFormat = "0%" と一致する。
コードの流れ
- 最終行を取得(データの増減に自動対応)
- 既存のグラフを全削除(再実行時の重複を防止)
ChartObjects.Addでグラフを作成- 系列1(売上)を棒グラフ・主軸に設定
- 系列2(前年比)を折れ線グラフ・第2軸に設定
- タイトル・軸ラベル・軸の表示形式・凡例を設定
- グラフに名前を付けて後から参照しやすくする
データを条件で絞り込んでからグラフにしたい場合は 複数条件でデータを抽出してまとめる方法 も参考になる。
—
よくある落とし穴5選
1. 再実行したらグラフが重複して増えていく
自分も最初これに気づかず、マクロを何度か実行したら同じグラフが5枚重なっていた。
対策: 実務版コードのように、グラフ作成前に ChartObjects.Delete で既存グラフを削除する処理を入れる。
2. データ範囲を固定値にしたらデータが増えた時に反映されない
原因: dataRange = "A1:B13" のように最終行を固定すると、14行目以降のデータがグラフに含まれない。
対策: End(xlUp).Row で最終行を動的に取得する。実務版コードではこの方式を採用している。
3. ChartType の定数名を間違えてエラーになる
原因: xlColumnClustered を xlColumnCluster(末尾のedが抜け)と書くなど、定数名のスペルミス。
対策: 書き換えポイントでは数値(51, 4, 65など)でも指定できるようにしてある。迷ったらよく使うグラフの種類表を確認する。
4. 第2軸のスケールが合わずグラフが見にくい
原因: 主軸(売上:1000単位)と第2軸(前年比:100%前後)のスケールが大きく異なる場合、自動スケールだと見にくくなることがある。
対策: Axes(xlValue, xlSecondary).MinimumScale = 0.8 / .MaximumScale = 1.3 のように手動でスケールを設定する。
5. グラフの位置がデータと被って見にくい
原因: Left / Top の値が小さすぎてデータ表の上にグラフが乗ってしまう。
対策: Left:=ws.Range("D2").Left のようにセル位置を基準にすると、データ列の右側にグラフを配置できる。実務版コードでは ratioCol + 2 列目の位置を基準にしている。
VBAでグラフが作成されないときの対処法
「ChartObjects.Addを実行したのにグラフが表示されない」という場合、原因はデータ範囲が空であるか、SetSourceDataで指定した範囲にデータが入っていないことが多い。データ範囲をDebug.Printで確認し、ヘッダーとデータが正しく含まれているかチェックすること。
VBAで複合グラフの第2軸が表示されないときの対処法
「SeriesCollectionでAxisGroupをxlSecondaryに設定したのに第2軸が出ない」という場合、原因は .HasAxis(xlValue, xlSecondary) = True を設定していないことだ。第2軸を有効にするにはHasAxisで明示的にTrueを指定してから軸タイトルを設定する。
—
FAQ
Q1: グラフの種類を後から変更したい
ChartType プロパティを変更するだけで種類が切り替わる:
ActiveSheet.ChartObjects("月次売上グラフ").Chart.ChartType = xlLine
Q2: グラフの位置やサイズを調整したい
ChartObject の Left, Top, Width, Height を変更する:
With ActiveSheet.ChartObjects("月次売上グラフ")
.Left = 300
.Top = 50
.Width = 500
.Height = 350
End With
Q3: 既存のグラフを全部削除したい
ChartObjects をループして削除する:
Dim co As ChartObject
For Each co In ActiveSheet.ChartObjects
co.Delete
Next co
Q4: グラフを画像(PNG)として保存したい
Chart.Export メソッドで書き出せる:
ActiveSheet.ChartObjects("月次売上グラフ").Chart.Export _
Filename:="C:\出力先\月次売上グラフ.png", FilterName:="PNG"
Q5: 凡例を非表示にしたい / 位置を変えたい
HasLegend で表示・非表示、Legend.Position で位置を制御する:
With ActiveSheet.ChartObjects("月次売上グラフ").Chart
.HasLegend = True '← False で非表示
.Legend.Position = xlLegendPositionBottom '← 下に配置
End With
位置の定数: xlLegendPositionBottom(下)、xlLegendPositionTop(上)、xlLegendPositionRight(右)、xlLegendPositionLeft(左)
—
まとめ
- ChartObjects.Add: シート上にグラフを作成。Left/Top/Width/Heightで位置とサイズを指定
- SetSourceData: グラフのデータ範囲を設定
- ChartType: グラフの種類を指定(xlColumnClustered, xlLine, xlPieなど)
- タイトル・軸ラベル: HasTitle = True → ChartTitle.Text / AxisTitle.Text で設定
- 複合グラフ: 系列ごとにChartTypeとAxisGroupを切り替えて棒+折れ線の2軸グラフを作成
関連記事
- 複数条件でデータを抽出してまとめる方法 — 抽出データからグラフを自動作成
- データの最終行・最終列を正確に取得する方法 — データ範囲の動的取得でグラフの範囲指定を自動化
- ピボットテーブルをVBAで自動生成する方法 — グラフの元データをピボットで集計
- ExcelデータからPowerPointスライドを自動生成する方法 — 作成したグラフをPowerPointに貼り付け
- セルの書式を一括変更する方法 — グラフ元データの表示形式を統一
—
次にやりたくなること
- 複数条件でデータを抽出してまとめる方法: フィルターで絞り込んだデータをグラフ化
- セルの書式を一括変更する方法: グラフのデータ元となるセルの表示形式を統一
- ピボットテーブルをVBAで自動生成する方法: グラフの元データをピボットで集計してからグラフ化したい場合
- ExcelデータからPowerPointスライドを自動生成する方法: 作成したグラフをPowerPointに自動で貼り付けたい場合
- データの最終行・最終列を正確に取得する方法: データ範囲の動的取得でグラフの範囲指定を自動化したい場合
—
もっとカスタマイズしたい場合
「グラフの書式が複雑(色・フォント・データラベルの細かい設定)」「複数シートのデータを1つのグラフにまとめたい」「グラフをPowerPointに自動貼り付けしたい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。
相談時に伝えると話が早い情報:
- Excel のバージョン / OS
- 作成したいグラフの種類(棒・折れ線・円・複合など)
- データの構成(列数・行数・複数シートの有無)
- グラフの用途(報告書・プレゼン・ダッシュボードなど)


コメント