VBAでグラフをいじくる
VBAでグラフを操る
Excelグラフのオブジェクトモデルを探る
次のような表からグラフを作成し、いろいろいじくり回してみた。
これが元のグラフ。それぞれの選手の連対時決まり手を元に積み上げ横棒グラフを作ってみた。
んで、次のコードでこのグラフを加工してみた。
リスト1 標準モジュール
Public Sub testGraph() Dim Sh As Worksheet Set Sh = ActiveSheet Dim targetGraph As ChartObject Set targetGraph = Sh.ChartObjects(1) Dim i As Integer With targetGraph.Chart .ChartType = xlBarStacked With .Axes(xlCategory) .ReversePlotOrder = True '……(1)軸を反転させる' .Crosses = xlMaximum '……(2)横軸との交点を「最大項目」に' End With .ChartGroups(1).GapWidth = 20 '……(3)グラフの棒と棒の間隔' With .PlotArea .InsideHeight = 140 '……(4)プロットエリア内部の高さ' .InsideWidth = 280 '……(5)プロットエリア内部の幅' With .Format.Line '……(6)プロットエリアの枠線' .ForeColor.RGB = vbBlack '……(7)枠線の色' .Weight = 1.5 '……(8)枠線の太さ' End With End With For i = 1 To .SeriesCollection.Count With .SeriesCollection(i).Format '……(9)データ系列の書式' .Fill.ForeColor.RGB = vbBlack '……(10)塗りつぶしの色' .Fill.BackColor.RGB = vbWhite .Fill.Patterned (i - 1) * 5 + 1 '……(11)塗りつぶしのパターン' .Line.Visible = msoTrue .Line.ForeColor.RGB = vbBlack '……(12)枠線の色' .Line.Weight = 1 '……(13)枠線の太さ' End With Next End With End Sub
まずは(1)と(2)の
With targetGraph.Chart.Axes(xlCategory) .ReversePlotOrder = True '……(1)軸を反転させる' .Crosses = xlMaximum '……(2)横軸との交点を「最大項目」に' End With
分かりやすいようにWithで括った上位オブジェクトを補って記す。targetGraphは埋め込みグラフオブジェクトを表すChartObject型の変数。コイツを便宜的に最上位オブジェクトとして説明する。以下同様に。
何をしているのかはコードの中のコメントに記してあるので、実行後どうなっているのかを示す。
まず(1)でこうなって、
(2)でこうなる。
横棒グラフにしたときは、項目が上下逆になってしまうので、その現象への対応。
ちなみに、Axesメソッドの引数に「xlCategory」を指定するとタテ軸、「xlValue」にするとヨコ軸を指すっぽい。
(3)の
targetGraph.Chart.ChartGroups(1).GapWidth = 20 '……(3)グラフの棒と棒の間隔'
「20」の単位は%。
コイツを実行すると、
こうなる。
(4)から(8)の
With targetGraph.Chart.PlotArea .InsideHeight = 140 '……(4)プロットエリア内部の高さ' .InsideWidth = 280 '……(5)プロットエリア内部の幅' With .Format.Line '……(6)プロットエリアの枠線' .ForeColor.RGB = vbBlack '……(7)枠線の色' .Weight = 1.5 '……(8)枠線の太さ' End With End With
(4)、(5)でプロットエリアの大きさを決め、(6)で処理対象をプロットエリアの枠線に切り替えて(7)で枠線の色を黒に。
最後に(8)で枠線の太さを設定する。
(9)から(13)の
For i = 1 To .SeriesCollection.Count With .SeriesCollection(i).Format '……(9)データ系列の書式' .Fill.ForeColor.RGB = vbBlack '……(10)塗りつぶしの色' .Fill.BackColor.RGB = vbWhite .Fill.Patterned (i - 1) * 5 + 1 '……(11)塗りつぶしのパターン' .Line.Visible = msoTrue .Line.ForeColor.RGB = vbBlack '……(12)枠線の色' .Line.Weight = 1 '……(13)枠線の太さ' End With Next
では、Forループを使ってSeriesCollectionコレクションからそれぞれのSeriesオブジェクトにアクセスする。Seriesオブジェクトというのは、データ系列のことみたい。
1回目のループでは、グラフの中では「先行」のところ。山賀選手しか持っていないw
(9)でデータ系列の書式にアクセスし、(10)からの2行で前景色を黒、背景色を白に指定しているので、
まずはこうなる。
で、(11)で塗りつぶしのパターンを指定。Patternedメソッドに渡す引数の指定はテキトーです。この場合は「1」が渡ることになるので、「msoPattern5Percent」、すなわち「前景色5%」を指定することになる。
こうなる。
(12)では、枠線の色を黒に指定する。
こうなる。
あとは(13)で枠線の太さを「1」にする。
これをSeriesCollectionの要素数だけ繰り返すと、全ての系列について書式を変更することになる。
こんな感じ。
まとめ
オブジェクトブラウザーで調べたり、マクロ記録をしてみたりして上記のコードを作った。
その結果、グラフまわりのオブジェクト構造は、およそ
Worksheet ┗━[ChartObjects]ChartObject ┗━Chart┳[ChartGroups]ChartGroup ┣PlotArea━Format━Line ┗[SeriesCollection]Series━Format┳Fill ┗Line
こんな感じなんだろうな、ということが分かった。間違えているかも知れんけど。
まあ、そもそもグラフ自体をほぼやったことがなかったので、これからだんだん分かってくるかも知れない。