業務効率化に役立つVBA/マクロのさまざまなTipsをコード例を交えて紹介していきます。今回は、AddChartメソッドのさまざまな引数で表示位置と大きさを指定する方法や、グラフの端をそろえるChartObjects.Leftプロパティ、大きさを統一するChartObjects.Width/Heightプロパティなどの使い方について。
今回は、グラフの表示位置と大きさを指定するVBAを紹介する。何も設定しなければ、グラフはデータの表示位置から遠くかけ離れた位置に表示され、グラフの大きさもデフォルト(?)の大きさで表示されるようだ。
Tips「折れ線、円、面、ドーナツ、3Dなど、さまざまな種類のExcelグラフの作り方」でグラフの表示位置を筆者が手動で移動させたのも、そのためだ。やはりグラフの表示位置や大きさは、データと関連してそれなりのものにしなければ、美しいグラフ付きの資料は作成できない。その美しい資料作りのためのグラフの表示方法を紹介しよう。
初めに、グラフの表示位置を指定する方法について解説する。
図1のような「担当者」と「売上金額」が入力されたセルと、グラフの表示位置を入力するセルと「実行」ボタンがあったとする(図1)。
図1のデータを基に、グラフを指定した位置に表示してみよう。
グラフの表示位置を指定する書式は下記のようになる。
{オブジェクト}.AddChart Left:={グラフの左端の位置},Top:={グラフの上端の位置}
{オブジェクト}には、Shapesオブジェクトを指定する。この書式を基に、実際にマクロを記述してみよう。
VBE(Visual Basic Editor)のメニューから、[挿入]→[標準モジュール]と選択する。プロジェクトに「Module1」が追加されるので、「Module1」をダブルクリックして、表示されるエディター画面内にリスト1のコードを記述する。
Option Explicit Sub 任意の位置にグラフを表示() Range("B3:C14").Select If ActiveSheet.ChartObjects.Count > 0 Then ActiveSheet.ChartObjects(1).Delete Else If Range("F2").Value = "" Then MsgBox ("位置を入力!") Else With Range(Range("F2").Value) ActiveSheet.Shapes.AddChart Left:=.Left, Top:=.Top End With End If End If End Sub
まず3行目でグラフ化する範囲、セル「B3」から「C14」までを選択している。この記述を忘れるとグラフは表示されない。
もしアクティブシートの上に、すでにグラフが存在している場合は、5行目で、そのグラフを削除するようにしている。グラフが存在していない場合は7〜13行目の処理を行う。
7行目で「位置指定」の入力欄に何か入力されているかどうか判定し、入力されていない場合は8行目でメッセージを表示し、正しく入力されていた場合は10〜12行目で指定したセルを左上とした位置にグラフを表示させる。
このマクロを図1の「実行」ボタンに関連付け実行すると、図2のように表示される。
「位置指定」で指定したセルを「左上」にしたグラフが表示される。特にグラフの種類を指定しなかった場合は、デフォルトの棒グラフで表示される。
次に、グラフの大きさを指定する方法を紹介しよう。新しく「グラフの大きさ」というシートを追加して、図1のデータと「位置指定」をコピーしておき、新たに「グラフの大きさ」という入力セルを追加する。「実行」ボタンも配置しておこう(図3)。
「グラフの大きさ」を指定する場合は、「セルの範囲」で指定する。例えば、VBAで「Range("E4:K14")」と指定すると、その範囲に収まるようにグラフが表示されるようになる。
ここで注意しなければならないのは、例えばグラフの大きさを「E4:K14」のセルの範囲に収まる大きさにする場合、「位置指定」には当然左上のセルである「E4」を指定することになる。そのため、「グラフの大きさ」には「K14」だけを指定すればいい。すると、「E4」セルを左上として、「E4:K14」のセルの範囲に収まるグラフが表示される。
グラフの大きさを指定する書式は下記のようになる。
{オブジェクト}.AddChart Left:={グラフの左端の位置},Top:={グラフの上端の位置},Width:=Range({グラフを表示する範囲の幅}).Width,Height:=Range({グラフを表示する範囲の高さ}).Height
{オブジェクト}には、Shapesオブジェクトを指定する。LeftとTopには、位置を指定し、WidthとHeightには、グラフの大きさを指定する。
先ほど追加したModule1内に、グラフの大きさを指定するリスト2のコードを追加しよう。
Sub グラフの大きさ() Range("B3:C14").Select If ActiveSheet.ChartObjects.Count > 0 Then ActiveSheet.ChartObjects(1).Delete Else If Range("F2").Value = "" Or Range("I2").Value = "" Then MsgBox ("位置または大きさを入力!") Else With Range(Range("F2").Value) ActiveSheet.Shapes.AddChart Left:=.Left, Top:=.Top, Width:=Range(Range("F2").Value & ":" & Range("I2").Value).Width, Height:=Range(Range("F2").Value & ":" & Range("I2").Value).Height End With End If End If End Sub
データをグラフ化する処理と、すでにグラフが存在していた場合、そのグラフを削除するのはリスト1と同じだ。
「位置指定」や「グラフの大きさ」のセルに値が入力されていない場合は、警告メッセージを表示する。それ以外は9〜11行目の処理を行う。
10行目では、書式にのっとって、「位置指定」に入力された位置を「左上」とし、「グラフの大きさ」は、「位置指定」に指定された値と、「グラフの大きさ」に指定されたセルの範囲に、グラフを表示している。WidthとHeightに指定する値は同じだ。図4の場合は「E4:K14」の範囲の大きさのグラフが表示される。
リスト2のマクロを図3の「実行」ボタンに関連付け実行すると、図4のように指定した位置で、指定した大きさの範囲(E4:K14)に、グラフが表示される。
続いて、グラフの端をそろえる方法について解説する。
図5のような各月の売上をグラフにしたデータと、「グラフの整列」というボタンがあったとしよう。
図5のデータを元に、「4月売上金額」のグラフを基準として、残り2つのグラフの左端をそろえてみよう。
下記は、グラフの端をそろえる書式だ。
ActiveSheet.ChartObjects.Left = {左にそろえる位置}
複数配置されているグラフを、全て同じ位置にそろえる場合は、ChartObjectsのLeftやTopプロパティの値を、基準とするグラフのLeftやTopプロパティに合わせる。今回は「4月売上金額」のグラフを基準としている。
これを基に、実際にマクロを記述してみよう。Module1内に、グラフの大きさを指定するリスト3のコードを追加しよう。
Option Explicit Sub グラフの左端をそろえる() Dim i As Integer If ActiveSheet.ChartObjects.Count = 0 Then MsgBox "グラフがありません。" Exit Sub Else For i = 2 To ActiveSheet.ChartObjects.Count ActiveSheet.ChartObjects(i).Left = ActiveSheet.ChartObjects(1).Left Next End If End Sub
まず3行目で、Integer型の変数「i」を宣言する。
次に4行目で、ChartObjectsのCountプロパティを使いアクティブシート上に配置されているグラフの個数を取得し、個数が0かどうか判定する。グラフがない場合は警告メッセージを発して処理を抜ける。それ以外は8〜10行目の処理を行う。
8〜10行目では、変数「i」を、2から配置されているグラフの個数分反復処理を行っている。2から開始するのは、1番目のグラフは基準となるグラフ(4月売上金額のグラフ)で、このグラフの左端をそろえる必要はないからだ。
9行目では、変数「i」に該当する、アクティブシートのChartObjectsのLeftプロパティを、1番目のグラフである「4月売上金額」のグラフの左端とそろえる。
このマクロを図5の「グラフの整列」ボタンに関連付け実行すると、図6のように表示される。
最後に、複数のグラフが配置されていて、グラフの大きさを統一する方法を紹介しよう。
「グラフの大きさをそろえる」という新しいシートを追加して、図5のデータをコピーしておき、大きさの異なったグラフを作成し、「グラフの大きさをそろえる」ボタンも配置しておく(図7)。今回も、1番目のグラフ(4月売上金額)を基準にして大きさをそろえてみよう。
この場合のグラフは、大きさは異なっているが、左端はそろっているものとする。また上の位置もデータの上の位置とそろっている必要がある(赤線)。
グラフの大きさを統一する場合は、ChartObjectsのWidthと、Heightプロパティを、基準とするグラフに合わせる。
ActiveSheet.ChartObjects.Width = {幅}
ActiveSheet.ChartObjects.Height = {高さ}
先ほど追加したModule1内にリスト4のコードを記述する。
Sub グラフの大きさをそろえる() Dim i As Integer If ActiveSheet.ChartObjects.Count = 0 Then MsgBox "グラフがありません。" Exit Sub Else For i = 2 To ActiveSheet.ChartObjects.Count ActiveSheet.ChartObjects(i).Width = ActiveSheet.ChartObjects(1).Width ActiveSheet.ChartObjects(i).Height = ActiveSheet.ChartObjects(1).Height Next End If End Sub
グラフが存在していなかった場合の処理はリスト3と同じだ。
7〜10行目で書式にのっとって、アクティブシートのChartObjectsの変数「i」に対応する、WidthとHeightプロパティの値を、1番目のグラフ(4月売上金額)のWidthとHeightと同じにする。これで、残り2つのグラフのサイズが1番目のグラフと同じになる。
もし、残り2つのグラフの左端がそろっていない場合は、リスト3のコードを追加する必要がある(後述)。その場合は、左端とグラフの大きさは期待通りに表示されるが、グラフが一部重なって表示される場合があるので、残り2つのグラフの位置をうまく調整しておく必要がある。
リスト4のマクロを図7の「グラフの大きさをそろえる」ボタンに関連付け実行すると、図8のようにグラフの大きさが1番目のグラフの大きさと同じに表示される。
図7で、左端がそろっていなかった状態のときは、リスト4に、リスト3で用いた下記コードを追加する必要がある。
ActiveSheet.ChartObjects(i).Left = ActiveSheet.ChartObjects(1).Left
しかし、これを追加しただけでは、「グラフの大きさをそろえる」ボタンをクリックすると、図9のようにグラフの一部が重なって表示されてしまう。
赤枠で囲った部分にグラフが重なってしまった。グラフの大きさは同じサイズで、左端もそろっているので、手動でドラッグ&ドロップして位置を調整するといいだろう。
これまでのTipsではグラフを表示する場合、筆者が個別に見栄えの良い位置まで移動させてスクリーンショットを撮っていたのだが、このように、任意の位置で、指定した範囲内の大きさでグラフが表示されれば、何の手間も掛けずに見栄えの良い資料が作成できる。
このサンプルでは「位置指定」「グラフの大きさ」を入力するセルをデータのそばに配置しているため、資料として使用する場合は、これらのセルは邪魔になる。そういった場合は、印刷範囲に収まる領域から、「位置指定」や「グラフの大きさ」を入力するセルを外して作成しておくと良い。
ぜひ今回紹介したTipsも、日常の業務に取り入れてもらいたいと思う。
薬師寺 国安(やくしじ くにやす) / 薬師寺国安事務所
薬師寺国安事務所代表。Visual Basicプログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。
1997年に薬師寺聖とコラボレーション・ユニット「PROJECT KySS」を結成。
2003年よりフリーになり、PROJECT KySSの活動に本格的に参加。.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。
Windows Phoneアプリ開発を経て、現在はWindowsストアアプリを多数公開中。
Microsoft MVP for Development Platforms - Client App Dev(Oct 2003-Sep 2012)。
Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。
Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。
Copyright © ITmedia, Inc. All Rights Reserved.