30分ごとの時間帯でGanttチャートを作成する

ユーザーフォーム講座 動画編 03回
30分ごとの時間帯でGanttチャートを作成する

動画でExcel 30分ごとの時間帯でGanttチャートを作成する

30分ごとの時間帯でGanttチャートを作成する

今回のGanttチャートは、 30分ごとの時間帯でGanttチャートを作成するにはというものです。
方法はいくつかありますが、まず始めに最初はFor文を使って、範囲の中を回していくというやりかたです。
そしてもう一つは、配列で行うケースです。

【タイムライン】

  • 目次
  • 00:00 - イントロ
  • 00:29 - 内容紹介、月単位のガントチャートの説明
  • 01:32 - 月単位のガントチャートを2通り作成
  • 02:22 - 該当月をひとつのレクタングルで作成する月単位のガントチャートのコード解説
  • 09:41 - 該当月のセルをひとつずつレクタングルで作成する月単位のガントチャートのコード解説
  • 14:14 - 次回30分単位のガントチャートの予告
  • 14:19 - コードタイム
  • 17:04- End

マクロ動画 30分ごとの時間帯でGanttチャートを作成する

https://youtu.be/GeOimeaSAEg

30分単位のガントチャートをFor文だけのマクロと、配列を利用したマクロで2種類

30分のガントチャートをFor文を利用して作るマクロと、配列を利用して作るマクロの2種類を紹介します。

30分単位のGantt chartをVBAマクロだけで作成する1

使うシートには工程表2という名前がついており、3行目には時間帯が30分単位で列見出しとして入力されています。
また4行目以降には、工程ナンバーと工程名が入力されており、開始時間と終了時間列見出しと同じく、30分単位で入力されています。

30分単位のGantt chartをVBAマクロだけで作成する2

最初にFor文で繰り返しながら工程表にレクタングルを描画するコードを見ていただきます。
最初に変数です。
Dim ws As Worksheet、wsはWorksheetを特定するために使う変数です。(変数について 動画内で説明しています。)
Dim startT As Double, endT As Double、これは開始時間と終了時間を表すための変数として使います。

30分単位のGantt chartをVBAマクロだけで作成する3

次に、工程表2をwsにセットします。
Set ws = Worksheets("工程表2")
これにより、With ws とwith構文を使う際のシート指定が簡単になります。
with構文の中でFor文を使ってレクタングル作成の為に必要なデータを取得します。
startT = CDbl(.Cells(i, 3).Value)
endT = CDbl(.Cells(i, 4).Value)
colorC = .Cells(i, 5).Interior.Color
shtext = .Cells(i, 2).Value
上記コードで、開始時間と終了時間を変数iで特定したセルから取得し、色と工程名も同様に取得します。

30分単位のGantt chartをVBAマクロだけで作成する4

開始時間と終了時間については、CDbl関数を使って、数値に変換しています。

30分単位のGantt chartをVBAマクロだけで作成する5

描画する列はどこか、For Each 構文で時間範囲を探す

ここからのコードが30分ガントチャートでは重要な部分です。
For Each TimRng In .Range("F3:AD3")
時間帯が入力されたレンジの中から、開始時間、終了時間と合致するレンジを探します。
これは列を特定する為です。値が同じだったら、その列を取得します。

30分単位のGantt chartをVBAマクロだけで作成する6

開始列と終了列が決まったらガントチャートのレクタングルを描画することができます。
以下のコードでは、開始セルと終了セル、セルのアドレスを作成しています。
' 開始列と終了列が決まったら、レクタングルを描画
If startCol > 0 And endCol > 0 Then
Dim startCe As String, endCe As String
startCe = .Cells(i, startCol).Address
endCe = .Cells(i, endCol).Address

30分単位のGantt chartをVBAマクロだけで作成する7

この部分はワークシートのShapes.AddShapeメソッドの引数に、必要なデータを当てはめてレクタングルを描画する部分のコードです。

30分単位のGantt chartをVBAマクロだけで作成する8
Shapes.AddShapeメソッド

以下が、この30分ガントチャートを作成するマクロのコード全体です。

30分単位のGantt chartをVBAマクロだけで作成する9
Sub GanttChart_30min_ver1()
    Dim ws As Worksheet
    Dim i As Long, colorC As Long
    Dim startT As Double, endT As Double
    Dim rng As Range, TimRng As Range
    Dim shtext As String
    Dim startCol As Long, endCol As Long

    Set ws = Worksheets("工程表2")
    Application.ScreenUpdating = False
    With ws
        For i = 4 To .Range("A4").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 Each TimRng In .Range("F3:AD3")
                If CDbl(TimRng.Value) = startT Then
                    startCol = TimRng.Column
                ElseIf CDbl(TimRng.Value) = endT Then
                    endCol = TimRng.Column - 1
                End If
            Next TimRng
            
        ' 開始列と終了列が決まったら、レクタングルを描画
            If startCol > 0 And endCol > 0 Then
            Dim startCe As String, endCe As String
            startCe = .Cells(i, startCol).Address
            endCe = .Cells(i, endCol).Address
                
                With .Shapes.AddShape(msoShapeRectangle, .Range(startCe).Left, _
                    .Range(startCe).Top, .Range(endCe).Offset(0, 1).Left - .Range(startCe).Left, _
                    .Range(endCe).Height)
                    .Fill.ForeColor.RGB = colorC
                    .TextFrame.Characters.Text = shtext
                    .TextFrame.Characters.Font.Size = 16
                    .TextFrame.Characters.Font.Bold = True
                    .TextFrame.Characters.Font.Name = "メイリオ"
                End With
                
            End If
        Next i
    End With
    Application.ScreenUpdating = True
End Sub
30分単位のGantt chartをVBAマクロだけで作成する20

配列を使ってガントチャートを作成する場合

配列を使ってガントチャートを作成する方法では、最初にシートから配列としてレクタングル作成のための情報と、シートの3行目のタイムレンジの情報を取得してしまいます。

これにより、処理速度が大幅に短縮されます。大量のガントチャートを作成する場合には、便利です。

30分単位のGantt chartをVBAマクロだけで作成する11

以下のコード部分が配列として取得しているコードです。
' シートからタスクデータと時間データを配列に格納
taskData = ws.Range("B4:D6").Value
timeData = ws.Range("F3:AD3").Value

30分単位のGantt chartをVBAマクロだけで作成する12

For i = LBound(taskData, 1) To UBound(taskData, 1)
配列taskDataのLBoundからUBoundまでを繰り返します。
開始時間と終了時間を配列から特定し、同様に描画する色と工程名を取得しています。

30分単位のGantt chartをVBAマクロだけで作成する13

以下の部分で配列timeDataから開始時間に合致する列を見つけます。
' 配列で時間を検索して開始列を見つける
For j = LBound(timeData, 2) To UBound(timeData, 2) '1 To 25
If CDbl(timeData(1, j)) >= startTime Then
startCol = j + 5 ' 列番号調整(F列から始まるため)
Exit For
End If
Next j

以下の部分で配列timeDataから終了時間に合致する列を見つけます。
For j = LBound(timeData, 2) To UBound(timeData, 2)
If CDbl(timeData(1, j)) >= endTime Then
endCol = j + 4
Exit For
End If
Next j

30分単位のGantt chartをVBAマクロだけで作成する15

あとは、レクタングルの開始列と終了列を決め、レクタングルを描画するという流れです。

30分単位のGantt chartをVBAマクロだけで作成する16

30分単位のGantt chartをVBAマクロだけで作成する17

30分単位のGantt chartをVBAマクロだけで作成する18

With構文の中で、
ws.Shapes.AddShapeメソッドを使い、ガントチャートのレクタングルを描画します。

30分単位のGantt chartをVBAマクロだけで作成する19

以下が、この30分ガントチャートを作成するマクロのコード全体です。

Sub GanttChart_30min()
    Dim ws As Worksheet
    Set ws = Worksheets("工程表1")
    Dim taskData As Variant, timeData As Variant
    Dim i As Long, j As Long
    Dim startTime As Double, endTime As Double
    Dim startCol As Long, endCol As Long
    Dim colorC As Long, shtext As String
    
    ' シートからタスクデータと時間データを配列に格納
    taskData = ws.Range("B4:D6").Value
    timeData = ws.Range("F3:AD3").Value
    
    For i = LBound(taskData, 1) To UBound(taskData, 1)
        startTime = CDbl(taskData(i, 2))
        endTime = CDbl(taskData(i, 3))
        colorC = ws.Cells(i + 3, 5).Interior.Color ' 行番号調整
        shtext = taskData(i, 1)
        
        ' 配列で時間を検索して開始列を見つける
        For j = LBound(timeData, 2) To UBound(timeData, 2) '1 To 25
            If CDbl(timeData(1, j)) >= startTime Then
                startCol = j + 5 ' 列番号調整(F列から始まるため)
                Exit For
            End If
        Next j
        
        For j = LBound(timeData, 2) To UBound(timeData, 2)
            If CDbl(timeData(1, j)) >= endTime Then
                endCol = j + 4
                Exit For
            End If
        Next j
        
        ' レクタングルの開始列と終了列
        Dim startCe As String, endCe As String
        startCe = ws.Cells(i + 3, startCol).Address
        endCe = ws.Cells(i + 3, endCol).Address
        ' レクタングルを作成
        With ws.Shapes.AddShape(msoShapeRectangle, _
                ws.Range(startCe).Left, ws.Range(startCe).Top, _
                ws.Range(endCe).Offset(0, 1).Left - ws.Range(startCe).Left, _
                ws.Range(endCe).Height)
            .Fill.ForeColor.RGB = colorC
            .TextFrame.Characters.Text = shtext
            .TextFrame.Characters.Font.Size = 12
            .TextFrame.Characters.Font.Bold = True
            .TextFrame.Characters.Font.Name = "メイリオ"
        End With
    Next i
End Sub

記事の説明で分かりにくい部分は、ぜひ動画をご覧ください。