VBA Excel:「ガントチャートをグラフで作る」
元ネタはこちらのサイトです。
参考:お手製 簡易ガントチャートをグラフで作ってみる。
http://edutainment-fun.com/excel/example/ganttchart.html
ここで記載されていたほかの方法は試したことがあるのですが、
これは面白そうなので試してみたらスゴイ苦労した・・orz
いえ、たぶんこれをゼロから説明するのが本当は大変なんでしょう。
TODOをWBS的なものにまで落とせるものをちょっと作ろうとしまして
勉強がてらVBA にて実現してみました。
というか、その手順のマクロ自動記録ですが、一部処理を書いています。
ということでいきなり全ソース。
わかりやすいように何してるかコメント書きました。
尚、デフォルト値の設定でもなんでも吐き出すのがマクロ記録なので
余計な設定も入っていますが、面倒なんであまり抜いてません。
(少し抜いたけど、ほんのちょっと。)
Option ExplicitSub Macro1()
Charts.Add
' --- チャートの作成
ActiveChart.ChartType = xlBarStacked ' 積み上げ式
ActiveChart.SetSourceData Source:=Sheets("概要").Range("K21") ' K21を一時的にデータソースに設定
' データ系列作成
ActiveChart.SeriesCollection.NewSeries ' データ系列1追加
ActiveChart.SeriesCollection.NewSeries ' データ系列2追加
' 入力データ及び名称データセル指定
ActiveChart.SeriesCollection(1).XValues = "=概要!R13C12:R15C12" ' 要素名
ActiveChart.SeriesCollection(1).Values = "=概要!R13C17:R15C17" ' 系列1データ
ActiveChart.SeriesCollection(1).Name = "=概要!R12C17" ' 系列1名称
ActiveChart.SeriesCollection(2).Values = "=概要!R13C20:R15C20" ' 系列2データ
ActiveChart.SeriesCollection(2).Name = "=概要!R12C20" ' 系列2名称
' 概要シートに移動
ActiveChart.Location Where:=xlLocationAsObject, Name:="概要"
' グラフ軸の設定
With ActiveChart
.HasAxis(xlCategory, xlPrimary) = False ' 要素名非表示
.HasAxis(xlValue, xlPrimary) = True ' 軸の値表示指定(ここでは年月日)
End With
ActiveChart.Axes(xlCategory, xlPrimary).CategoryType = xlAutomatic ' 軸の目盛り設定(自動に。)
' グラフの横軸設定(つまり要素用)
With ActiveChart.Axes(xlCategory)
.HasMajorGridlines = True ' 主軸を表示
.HasMinorGridlines = False ' 補助線は非表示
End With
' グラフの縦軸設定(つまり横に伸びる値用)
With ActiveChart.Axes(xlValue)
.HasMajorGridlines = True
.HasMinorGridlines = False
End With
ActiveChart.HasLegend = False ' グラフの凡例非表示
' 縦軸(つまり値用)の設定
ActiveChart.Axes(xlValue).MajorGridlines.Select
With ActiveChart.Axes(xlValue)
.MinimumScale = 40809 ' ここが重要
.MaximumScale = 40817 'ここが重要
.MinorUnitIsAuto = True ' 補助幅自動設定
.MajorUnitIsAuto = True ' 主軸幅自動設定
.Crosses = xlAutomatic ' 交差ポイント設定
.ReversePlotOrder = False ' ここは重要ではないが、反対にならないようにする。
.ScaleType = xlLinear
.DisplayUnit = xlNone ' 軸のラベルを表示するかどうか。
.TickLabelPosition = xlHigh ' これ重要。上に軸目盛り値を持ってくる
End With
' 系列の1つ目の設定
ActiveChart.SeriesCollection(1).Select
With Selection.Border
.Weight = xlThin
.LineStyle = xlNone ' 線非表示
End With
Selection.Shadow = False
Selection.InvertIfNegative = False ' 要素を反転するか。反転してはいけない。
Selection.Interior.ColorIndex = xlNone ' 塗りつぶしをなしにする。
' 系列2に対しての処理
ActiveChart.SeriesCollection(2).Select
With Selection.Border
.Weight = xlThin
.LineStyle = xlAutomatic
End With
Selection.Shadow = False
Selection.InvertIfNegative = False
Selection.Fill.OneColorGradient Style:=msoGradientHorizontal, Variant:=3, _
Degree:=0.939208056763561 ' 色を明るいほうへ少し変更しつつ2色でグラデ
With Selection
.Fill.Visible = True
.Fill.ForeColor.SchemeColor = 18
End With
' グラフチャート全体の設定
ActiveChart.ChartArea.Select
With Selection.Border
.Weight = 2
.LineStyle = 0 ' 枠線を非表示
End With
Selection.Interior.ColorIndex = xlNone ' 塗りつぶしもなしにする
ActiveSheet.ChartObjects(Replace(ActiveChart.Name, "概要 ", "")).Activate
ActiveSheet.Shapes(Replace(ActiveChart.Name, "概要 ", "")).Height = Range("K13").Height * 5 ' プロットエリアの高さも行の高さx(行数(要素数)+2)にする。
' プロットエリアの設定
ActiveChart.PlotArea.Select
With Selection.Border
.Weight = xlThin
.LineStyle = xlAutomatic
End With
Selection.Height = Range("K13").Height * 5 ' プロットエリアの高さも行の高さx(行数(要素数)+2)にする。
Selection.Interior.ColorIndex = xlNone
ActiveWindow.Visible = False
Windows("TODO化してみせる_まくろグラフ.xls").Activate
Range("X37").Select
End Sub
簡単にファイル構成を説明すると、
最後のほうの行の
Windows("TODO化してみせる_まくろグラフ.xls").Activate
にあるTODO化してみせる_まくろグラフ.xls てのが、マクロのファイル名。
シート構成は、概要というシートが1枚だけあります。
マクロ自体はmodule1(つまりマクロ記録そのまま)で、それのみです。
上記URLを参考にしていただくとわかりますが、
手順としては、先に下図のような入力欄を用意するところから始まります。
ここで必要なのは、
・開始日
・工数 ... 中身は (終了日-開始日)+ 1
関数ならDATEDIF(終了日,開始日,"D")+1 です。
・最短開始日、最長終了日それぞれのシリアル値
の4つです。
作業内容は、上記URLを参考にしてもらいつつ、
グラフに慣れていない人には、わかりにくいところを
補完した説明を図にしました。(手抜きww)
手順1
要は、積み立て横棒グラフを使うことでの応用なので
そこから始ります。
手順2
項目1に開始日のリスト
項目2に工数のリスト
をそれぞれ指定して、要素名とかしていしてみたり・・。
しかし、普通に作成しては想像とはかけ離れたものに。
ここまでをマクロで一気にやります。
途中で、グラフを何度も生成したとき用にグラフ名をせこく生成しています。
当然、シート名やセル位置、ファイル名を自分が作成したファイルに
あわせないと動きませんがこんな感じ。
で、作っているときから気づいていましたが
これでは予定線と実績線が書けません。
なので、このアイディアでガント化するのはやめるのですが、
まぁ勉強がてらというか、こういう発想もありなのか!
という参考になればと・・。
いえ、まずはこういうアイディアを考えてくださった
上記URLの管理人さんに感謝です。m(_ _)m