
動画でExcel 誰も教えてくれない、10分のガントチャート
今回は10分単位のGanttチャートを作成したいと思います。
今まで
ガントチャートをいろいろ作ってきて、今回の10分単位が一番難しいでしょう。
どこが難しいかというと、時間の捉え方が難しいようです。
小さなセルに9:10とか9:20などと書き込むのは難しいですし、 見づらいので上の行に時間を入れ、下の行に分を表す数値を入れることにします。

ところが、セルには0~、10~、20~、などと記載しています。これはその方が理解しやすいと考えたからです。1つのセルが10分間を表すという意味です。

始めに、上の行に時間を入れ、下の行に分を表す数値を入れています。時間も9時なら9を6個入れ、最初の9だけ見せて、他は文字色を白にしています。

そしてそのまま表示するのではなく、ユーザー定義で数値の後ろに~と表示する設定にしてあります。

今回は以下の変数を使います。
これらの変数は最終的にガントチャートのレクタングルを描画するための開始セルと終了セルを特定するために必要な変数となります。

開始セルと終了セルを特定する時間の書きかたですが、起点となるセルから何個オフセットするかを考えます。

With ws ~ End With に挟まれた部分が実際に操作するためのマクロコード部分です。

外側のFor文では、
i = 4 から CurrentRegion.Rows.Countで行数をカウントして、
それぞれの レクタングルに必要な、スタートタイムとエンドタイムとそしてセルの背景色と セルに書き込む テキストの値を取得しています。

そして、その次に来るFor文では、開始時間から終了時間までの間、対応する列を見つけるためのコードが書かれています。 j As Date のjはFor文の中で回していくために使う変数です。

' 開始時間から終了時間までの間、対応する列を見つける
For j = TimeValue("9:00:00") To TimeValue("18:00:00") Step TimeSerial(0, 10, 0)
If Round(j, 10) = Round(startT, 10) Then
startCol = .Cells(2, 6).Offset(0, (Hour(j) - 9) * 6 + Minute(j) / 10).Column
End If
If j >= startT And Round(j, 10) = Round(endT, 10) Then
endCol = .Cells(2, 6).Offset(0, (Hour(j) - 9) * 6 + Minute(j) / 10).Column - 1
Exit For
End If
Next j
For j = TimeValue("9:00:00") To TimeValue("18:00:00") Step TimeSerial(0, 10, 0)
というコードは、シートの分で表示されている部分と対応します。

次のコード、
If Round(j, 10) = Round(startT, 10) Then
startCol = .Cells(2, 6).Offset(0, (Hour(j) - 9) * 6 + Minute(j) / 10).Column
ですが、(j, 10) と(startT, 10)が同じだったらと言う事ですが、ROUND関数で丸めています。

人間の目で見たら同じと判断できますが、時間はシリアル値な為、どうやってその時間を作成したかによって、
実際には小数点以下の精度において誤差が生じる事が多々あります。
どんなに微小な誤差でも誤差があれば、同じだとみなされません。それを防ぐためにROUNDしています。

startCol = .Cells(2, 6).Offset(0, (Hour(j) - 9) * 6 + Minute(j) / 10).Column
これは開始時間が同じであれば、開始列はどこになるかというコードです。
9時00分ならば、.Cells(2, 6)でOffsetする必要はないのですが、それを式にすると上記のようになります。

9時10分ならば、分の方の値が1となるので、1つ分Offsetします。

9時20分ならば、分の方の値が2となるので、2つ分Offsetします。

終了時間の列を探す場合、考え方は一緒ですが、マイナス1してやります。

12時終了だとすると、実際には11時59分59秒・・・のように限りなく12時に近いけどその直前の意味であるとします。

開始列と終了列が見つかったらFor文を抜けます。

そして描画するために、セルのアドレスを取得してやります。列は分っているので、行を決めてセルアドレスに格納します。
レクタングルを描画するコードは今までのコードと同じです。

10分単位のガントチャートを描画するマクロを実行すると、以下の図のようにガントチャートを作成することができました。

'==============================================================
'=10分単位のガントチャート、TenMinutesGunttChart
'==============================================================
Sub TenMinutesGuntt_normal()
Dim ws As Worksheet
Dim i As Long, colorC As Long
Dim startT As Double, endT As Double
Dim shtext As String
Dim startCol As Long, endCol As Long, j As Date
Dim startCe As String, endCe As String
Set ws = ThisWorkbook.Worksheets("工程表")
With ws
For i = 4 To .Cells(3, 1).CurrentRegion.Rows.Count ' 表の状態で調整必要
startT = CDbl(.Cells(i, 3).Value)
endT = CDbl(.Cells(i, 4).Value)
colorC = .Cells(i, 5).Interior.Color
shtext = .Cells(i, 2).Value
startCol = 0
endCol = 0
' 開始時間から終了時間までの間、対応する列を見つける
For j = TimeValue("9:00:00") To TimeValue("18:00:00") Step TimeSerial(0, 10, 0)
If Round(j, 10) = Round(startT, 10) Then
startCol = .Cells(2, 6).Offset(0, (Hour(j) - 9) * 6 + Minute(j) / 10).Column
End If
If j >= startT And Round(j, 10) = Round(endT, 10) Then
endCol = .Cells(2, 6).Offset(0, (Hour(j) - 9) * 6 + Minute(j) / 10).Column - 1
Exit For
End If
Next j
' レクタングルの描画
If startCol > 0 And endCol > 0 Then
startCe = .Cells(i, startCol).Address
endCe = .Cells(i, endCol).Offset(0, 1).Address
With .Shapes.AddShape(msoShapeRectangle, .Range(startCe).Left, _
.Range(startCe).Top, .Range(endCe).Left - .Range(startCe).Left, _
.Range(endCe).Height)
.Fill.ForeColor.RGB = colorC
.TextFrame.Characters.Text = shtext
.TextFrame.Characters.Font.Size = 14
.TextFrame.Characters.Font.Bold = True
.TextFrame.Characters.Font.Name = "メイリオ"
End With
End If
Next i
End With
End Sub