3種類の方法を使ってマクロでグラフを新規作成する
Excelではワークシートの情報をもとにグラフやピボットグラフを作成する事ができます。
という事はVBAでもグラフを作成する事ができます。
グラフ作成は面倒なので工数を減らす為に実際にVBAを使ってグラフを用意したことがある方はたくさん居るはずです。
しかしVBAを使ってグラフを作るとなると非常に分かりにくいので止めてしまう方が多い様です。
グラフは関連オブジェクトが分かりにくい
なぜ分かりにくいのかをヒアリングしたところ返ってきた回答は1択でした。
「関連オブジェクトが複雑でとにかく分かりにくい」という回答でした。
特に新規作成時にどうやってグラフを準備したら良いのか分かりません。
関連オブジェクトが複雑で分かりにくい原因を見つける為に調査を進めてみると2つのポイントが見つかりました。
- グラフを表示させる場所は2箇所(グラフシートとワークシート)
- グラフを表示させるコードは3つ(キーとなるオブジェクトが別々)
2つのポイントを意識しながら各要素の区別、住み分けが理解できてないので難しく感じている様です。
本記事ではグラフの「新規作成時」に絞って2つのポイントを深堀りしていきます。
記事を読むとグラフを表示させるための3つのコードの住み分けが理解出来るようになります。
最終的にはVBAで簡単にグラフを作成することが出来るようになりますよ。
関連記事
ピボットテーブルからピボットグラフを作る方法を紹介しています。
このあと紹介する方法の中から1つを使ってグラフを表示させています。
自動でグラフを用意する【応用編】ExcelVBAでピボットテーブルと連動したグラフを自動で作成する
関連書籍
グラフは関連オブジェクトが理解出来るとロジカルに考えることが出来るのですが最初は難しいです。
こちらの書籍はグラフに関する情報量が非常に多いです。加えて分かりやすく説明してあるのでおすすめの一冊です。
電子書籍はこちらです。内容のしっかりした書籍はどうしても重たくなります。
私はこの本は電子書籍向きだと感じています。是非ご検討ください。
Excelにおけるグラフとは
まずはグラフの定義の確認です。グラフに関する情報をMicrosoftのドキュメントから引用しました。
グラフでは、対象ユーザーに最も大きな効果がある方法でデータを可視化できます。
推奨されるグラフからドキュメントを開始することができます。
また 事前に構築されたグラフ テンプレートのコレクションからドキュメントを選択することもできます。
Microsoftサポート:グラフを作成するから抜粋、一部加工
引用ブロックの左下のリンク先には動画もあります。作業がイメージできるので是非ご覧ください。
引用の中に書かれている事を自分なりに解釈してまとめると以下の様になります。
グラフについてはExcelユーザーの多くが見た事がある要素です。よって深く説明する必要は無いですよね。
あくまで確認レベルで情報を用意した次第です。このぐらいで定義の説明は終了しておきましょう。
続いて冒頭で紹介した様にVBAでグラフを用意するにあたり何が分かりにくいのかを整理してみます。
VBAを使ってグラフを作る時の問題点を整理する
VBAでグラフを作成、操作するにあたり問題となっているポイントは2つでしたね。
- グラフを表示させる場所は2箇所(グラフシートとワークシート)
- グラフを表示させるコードは3つ(キーとなるオブジェクトが別々)
問題点を整理する為に表と画像を用意しました。順番に確認していきましょう。
整理:表を作って情報を切り分ける
まずは新規作成時の操作に絞って表を作成してみました。
番号 | グラフの表示場所 | 詳細 |
---|---|---|
1 | グラフシート | Chartsプロパティ→SheetsオブジェクトのAdd2メソッド使ってグラフを表示させる |
2 | ワークシート | ShapesオブジェクトのAddChart2メソッドを使ってグラフを表示させる |
3 | ワークシート | ChartObjectsオブジェクトのAddメソッドを使ってグラフを表示させる |
表にして並べることで体系的に理解することができますね。加えて内容も具体的になってきました。
詳細欄のオブジェクト関連の話は記事後方の解説で説明していますのでまずはグラフの表示場所を見ていきましょう。
グラフシートにグラフを用意する時は1番のコード1択です。(グラフシートはシート全体がグラフのワークシートです)
これでグラフシートを新規作成する際にコードの選択で迷うことはなくなりましたね。
しかしワークシートにグラフを新規作成する場合は2つのコードのうちどちらのコードを採用したら良いのか分かりません。
という事はワークシートに表示させる2つのグラフについてはもう少し掘り下げる必要がありそうですね。
比較:ワークシートに対応している2つのコードを比較する
次はグラフを作成する場所がワークシートになっている2つのコードについて考えてみましょう。
それぞれのコードの中にあるオブジェクトの並びを中心にコードを比較していきます。
2つのコードを提示した後に共通点に注目すると色々なことが見えてきますよ。
Shapesオブジェクト(コレクション)を使った時
まずはShapesオブジェクト(コレクション)を使った時の画像を用意しました。
各オブジェクトがどうやって繋がっているのかはコードを紹介した後に解説します。(先に解説が見たい方はこちら)
まずはパッと見で理解できるところだけ認識しましょう。特徴を3つ挙げておきます。
- 外側の枠はWorksheetオブジェクト
- 内側の枠はChartオブジェクト
- 階層は4つ
ChartObjectsオブジェクト(コレクション)を使った時
続いてChartObjectsオブジェクト(コレクション)を使った時のコードの構成は画像の通りです。
各オブジェクトがどうやって繋がっているのかはコードを紹介した後に解説します。(先に解説が見たい方はこちら)
Shapesオブジェクトの時と同じ様にパッと見で理解できるところだけ認識してください。特徴を3つ挙げておきます。
- 外側の枠はWorksheetオブジェクト
- 内側の枠はChartオブジェクト
- 階層は4つ
ポイント
画像からは読み取れないポイントを1つ提示しておきます。
プログラミングでコンテナというのは任意のオブジェクトを格納する箱のようなものをイメージしてください。
Wikipediaには以下の様な説明があります。「コレクション」でイメージ出来る人が何人か居るかもしれませんね。
「ChartObjectオブジェクトはChartオブジェクトを格納する為の箱」というイメージを持ってください。
コンピュータプログラミングにおいて、コンテナ(英: container)とはオブジェクトの集まりを表現するデータ構造、抽象データ型またはクラスの総称である。
コレクション(英: collection)とも言う。
コンテナには複数の種類があり、それぞれ独自の方法でオブジェクトを組織的に格納する。
Wikipedia:コンテナ (データ型)より抜粋
難しい時はこうすると理解できるかもしれません。
「Chartオブジェクトの情報を表示させる為にChartObjectオブジェクトという土台が必要」だと考えてみてください。
検討:2つのコードの共通点
2つのコードの共通点は「始点がWorksheetオブジェクトで終点がChartオブジェクト」です。
ここから終点のChartオブジェクトに注目してみます。グラフ内の要素を指示するのはChartオブジェクトです。
よってグラフを作るためのコーディングにおいてはChartオブジェクトに必ず到達する必要があります。
このような環境の中で2つのコードは使用するオブジェクトは違いますが最後はChartオブジェクトに到達できています。
よってChartObjectsオブジェクト、Shapesオブジェクトのどちらを使ってもグラフを用意することができます。
階層はどちらのコードも結果として同じ4階層となりました。特に意味は無いのでこの点は考えないようにします。
3通りのコードが話を難しくしている
グラフを用意するまでのルートは2本あるので作業時は2つのコードをしっかり分けて考える必要があります。
しかし知識が曖昧な人はどちらのコードでどのオブジェクトを使うのかが分からず悩んでしまう様です。
多くの皆様が「グラフは関連オブジェクトが分かりにくい」と言われる点はここにあります。
道が2つあるという事は一見メリットの様に感じてしまうのですがしっかり理解できてないとデメリットになります。
最終的にはグラフシートに関連するオブジェクトもあるので3つのコードを分けて理解しないといけません。
結論:私はこうやって使い分けています
このままだとコードを理解するのが難しくなるのでコードを使い分ける為に一定の決まりを提示します。
私は操作対象となるグラフの表示場所を考慮してコードを使い分けています。
- Sheetsオブジェクトを使用したコード ・・・ グラフシートにグラフを用意する時(新規、既存含)
- Shapesオブジェクトを使用したコード ・・・ ワークシートにグラフを用意する時(新規、既存含)
- ChartObjectsオブジェクトを使用したコード ・・・ 基本的には使わない
3番を使わず2番のShapesオブジェクトを使う理由は単純です。グラフを新規作成、説明する際に「楽だから」です。
私がShapesオブジェクトを使ったコードを選ぶ理由はこの2つです。
この後コードを用意して解説していきます。解説を見るとShapesオブジェクトを使ったコードを選ぶ理由が分かります。
では座学はここまでにして実際に事例の中でコードを使ってグラフを用意してみましょう。
私はChartObjectsオブジェクトを使ったコードは実質使わないのですが使い方だけは説明することにします。
事例
実際にグラフを用意しましょう。インプット、コード、解説、アウトプットの順に説明していきます。
インプット
まずはコード実行前のワークシートの状態を確認しておきます。
202402という名前のワークシートにセルA5起点でデータソースが表示されています。
セルA5のデータソースをもとに数値を集計します。結果をセルG5起点でピボットテーブルとして用意しています。
ここに3つのグラフを用意します。それぞれ別のコードを使ってグラフを用意していきます。
グラフの種類は折れ線グラフ、散布図など色々な種類がありますが今回は棒グラフ(集合棒線)を使うことにします。
- Sheetsオブジェクトを使用したグラフ
- Shapesオブジェクトを使用したグラフ
- ChartObjectsオブジェクトを使用したグラフ
データソースを1つにして3つの方法を使ってグラフを用意することで各コードの差を認識してください。
差がわかる様になってくるとそれぞれのコードを使い分けることが出来るようになりグラフの理解が進みます。
コード
続いてコードを紹介します。ボタンをクリックする事でコードをコピーすることが出来ます。
Sub グラフ作成()
Dim wbk As Workbook 'ワークブックを格納
Dim wst As Worksheet 'ワークシート(ファイル)を格納
Dim rng As Range 'グラフの対象にするセルの範囲を格納
Dim cht As Chart 'Chartオブジェクトを格納
Set wbk = ThisWorkbook
Set wst = ActiveSheet
Set rng = wst.Range("G5").CurrentRegion
'***********************************************
'WorkbookオブジェクトのChartsプロパティから呼び出される
'Sheetsオブジェクトを使ってグラフを新規作成
wst.Activate
Set cht = wbk.Charts.Add2(After:=Worksheets(Worksheets.Count))
With cht
.Name = "202402_Charts" 'グラフシートの名前
.HasTitle = True 'タイトルの枠
.ChartTitle.Text = "販売数_Charts" 'タイトル
.HasLegend = True '凡例
.SetSourceData rng 'データソース
End With
Set cht = Nothing '使い回すので一旦開放
'***********************************************
'Shapesオブジェクトを使ってグラフを新規作成
wst.Activate
Set cht = wst.Shapes.AddChart2(, xlColumnClustered, 30, 230, 580, 326.25).Chart
With cht
.Parent.Name = "202402_Shapes" 'グラフの名前
.HasTitle = True 'タイトルの枠
.ChartTitle.Text = "販売数_Shapes" 'タイトル
.HasLegend = True '凡例
.SetSourceData rng 'データソース
End With
Set cht = Nothing '使い回すので一旦開放
'***********************************************
'ChartObjectsオブジェクトを使ってグラフを新規作成
wst.Activate
Set cht = wst.ChartObjects.Add(730, 230, 580, 326.25).Chart
With cht
.Parent.Name = "202402_ChartObjects" 'グラフの名前
.HasTitle = True 'タイトルの枠
.ChartTitle.Text = "販売数_ChartObjects" 'タイトル
.HasLegend = True '凡例
.SetSourceData rng 'データソース
End With
End Sub
サンプルとして用意した3つの方法の中にはWithステートメントが用意されています。内容はどれも同じです。
サブルーチンを使えばもう少し綺麗にコードを用意できますが今回はグラフを作成することがメインです。
よってできるだけ簡単な仕様にしています。ご了承ください。サブルーチンについてはこちらの記事をご覧ください。
サブルーチンについて【マトリクスで理解する】プロシージャを分割したマクロを用意する方法
解説
1つのプロシージャの中に3つの方法を使ってグラフを用意しています。
- Sheetsオブジェクトを使用したコード
- Shapesオブジェクトを使用したコード
- ChartObjectsオブジェクトを使用したコード
以降で順番に解説していきます。
1_Sheetsオブジェクト
ポイントになるコードはこちらです。最終的には変数chtにChartオブジェクトを格納しています。
まずはなぜこのコードがSheetsオブジェクトを使用したコードなのかを説明する必要があります。
WorkbookオブジェクトのChartsプロパティはSheetsオブジェクト(コレクション)を生成します。
その後SheetsオブジェクトのAdd2メソッドを使ってグラフを作っています。
よってコード内ではSheetsオブジェクトの文字は居ないのですがオブジェクトとしては活きている要素です。
このことから記事内では「Sheetsオブジェクトを使ったコード」と表現しています。
続いてイコールの後のコードを確認していきます。まずは変数wbkです。中身はWorkbookです。
よってWorkbookオブジェクトからどうやってコードをつなぐのかを順番に説明していきます。
生成されたSheetsオブジェクト(コレクション)のAdd2メソッドを使って新しいグラフ シートを追加します。
上の画像では戻り値がオブジェクトになっていますね。グラフシート自体がChartオブジェクトとして返ってきます。
返ってきたオブジェクトをChart型の変数chtで受けています。画像はローカルウインドウの状態を示しています。
最後はグラフシートを追加する場所です。既存のワークシートをカウントしてその後ろに配置する様にしました。
このコードのポイントはやはりグラフシートです。3つのコードの中でこのコードだけグラフシートが関連していますね。
少々難しいのですが何度かご自身で作業していただくと理解できるようになります。ぜひチャレンジしてみてください。
あとはChartオブジェクトが持っているプロパティに値を代入することでグラフを用意することができます。
2_Shapesオブジェクト
続いてShapesオブジェクトを使ったコードです。キーになるコードはこちらです。
続いてイコールから右側のコードについて考えていきます。
wstはワークシートを格納している変数です。変数wstからどうやってコードをつなぐのかを順番に説明していきます。
最初はWorksheetオブジェクトでShapesプロパティを選びShapesオブジェクトを呼び出します。
続いてShapesオブジェクトのAddChart2メソッドを使ってShapeオブジェクトを用意します。
AddChart2メソッドではグラフのデザインや位置、サイズ(大きさ)などの項目を指定することができます。
AddChart2メソッドのポイントを1つ挙げます。メソッド内のStyleというパラメータでグラフのデザインを指定できます。
このポイントが私がShapesオブジェクトを使ったコードを選ぶ理由の中の1つです。(最適なStyleを見つける方法)
最後にShapeオブジェクトのChartプロパティを選ぶことでChartオブジェクトを呼び出して変数chtに格納します。
以降はChartオブジェクトが保持しているプロパティに値を代入することでグラフの中身が形成されていきます。
3_ChartObjectsオブジェクト
最後にChartObjectsオブジェクトを使ったコードを紹介します。キーになるコードはこちらです。
続いてイコールから右側のコードについて考えていきます。
wstはワークシートを格納している変数です。変数wstからどうやってコードをつなぐのかを順番に説明していきます。
最初はWorksheetオブジェクトでChartObjectsメソッドを使いObjectを呼び出します。
ここで呼び出されるObjectというのは「ChartObjectsオブジェクト(コレクション)」です。
ソースはMicrosoftのドキュメントです。ここを他者に説明するのが難しいので「使わない」という判断をしています。
1 つの埋め込みグラフ ( ChartObject オブジェクト) またはシート上のすべての埋め込みグラフ ( ChartObjects オブジェクト) のコレクションを表すオブジェクトを返します。
Worksheet.ChartObjects メソッド (Excel)より抜粋
ChartObjectsオブジェクト(コレクション)のAddメソッドを使ってChartObjectオブジェクトを用意します。
Addメソッドではグラフの位置、大きさを指定することができます。
最後にChartObjectオブジェクトのChartプロパティを選ぶことでChartオブジェクトを呼び出して変数chtに格納します。
以降はChartオブジェクトが保持しているプロパティに値を代入することでグラフの中身が形成されていきます。
アウトプット
まずはChartsオブジェクトのグラフです。グラフシートとタイトルにはChartsという文字を使ってグラフを用意しました。
続いてShapesオブジェクト、ChartObjectsオブジェクトです。ワークシート上にグラフを用意できました。
それぞれの方法で用意されているデフォルトのデザインが異なるので3つ共に少しだけデザインが違いますね。
余談ですが3つのコードの中でShapesオブジェクトのAddChart2メソッドだけは最初からデザインを指定できます。
最終的にはグラフ完成後もデザインは変えられますのでご安心ください。
今回はできるだけ少ないシート数ですべてを表示させたいので各オブジェクト間が込み合った状態になっています。
読者の皆様がご自身の仕事でコードを用意する際はオブジェクト間の配置にゆとりを持ったコードを書いてください。
まとめ
VBAを使ってグラフを用意する3つの方法を解説しました。
今回はキーとなるオブジェクトを3つ用意してグラフを新規作成するところまで説明させていただいた次第です。
まずは3つのオブジェクトを使った各コードの違いをしっかり理解できるようにしてください。
新規でグラフを用意することに慣れてきたら次は既存のグラフをメンテナンスすることを考えましょう。
当然ですがグラフは作成してからメンテナンスをすることもありますよね。
よって既存のグラフの情報を書き直すという作業も考える必要があります。
需要次第ですが既存のグラフの情報を書き直すためのコードも用意していくことを考えています。