EXCEL VBA シフト管理を簡単に!自動生成マクロの紹介・従業員のシフト表を自動生成(テクニック)

 

EXCEL VBA シフト管理を簡単に!自動生成マクロの紹介・従業員のシフト表を自動生成(テクニック)

 

●はじめに

今回説明するのは、Excel VBAを使用したシフト管理マクロをご紹介します。このコードを使うことで、従業員のシフトスケジュールを簡単かつ効率的に作成する事ができます。会社の従業員の人数や日数に応じて柔軟に対応できるため、さまざまな業種で活用できます。また、土日の赤字表示やシフトの自動割り当てなど、効率化と利便性が向上します。手作業でシフト表を作成する手間を大幅に削減し、業務効率化に貢献できると思います。あくまでも簡易的なプログラムなために参考にしていただけると嬉しいです。それでは、順番に説明をいたします。

 

●【EXCEL VBA 氏名からメールアドレスを自動生成・名前情報からメールを作成・業務効率化パスワードについては、下記を参照して下さい】

●【EXCEL VBA パスワードの自動作成・ランダムパスワードの生成については、下記を参照して下さい】

 

 

 

 

EXCEL VBA シフト管理を簡単に!従業員のシフト表を自動生成(月曜日~日曜日のシフト表)

 

●プログラム説明 (サンプル①)

下記のプログラムは、従業員のシフト表を自動生成します。月曜日~日曜日までのシフト表を自動生成します。具体的なこのプログラムは、従業員名、シフトの種類(午前、午後、休み)、曜日をもとにして、ランダムにシフトを割り当て、書式設定を行い、シフト表ワークシートに出力することができます。

【プログラムの流れ】

  1. 変数の宣言
  2. 従業員リスト、シフトの種類、曜日リストを配列に格納
  3. シフト表ワークシートを選択
  4. シフト表をクリア
  5. セルに従業員名を入力
  6. セルに曜日を入力
  7. セルにシフトをランダムに割り当て
  8. セル書式設定
  9. 印刷範囲の設定

【プログラム実行条件・注意事項】

  1. 実行条件:このコードは、ExcelにてVBAマクロを実行可能な環境が必要です。また、「シフト表」という名前のワークシートが存在していることが前提です。
  2. 注意事項:シフトの割り当てが完全にランダムで行われるため、実際の業務要件や従業員の希望などは考慮されません。また、コードを実行する度にシフト表がクリアされ、新しいシフト表が作成されるため、適切なタイミングで実行してください。
  3. 完全にランダムで行われるため、実際の業務要件や従業員の希望などは考慮されません。

★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● Shift_schedule01(サンプルプログラム)

 

 

Option Explicit

Sub CreateShiftSchedule()
    Dim ws As Worksheet
    Dim i As Integer
    Dim j As Integer
    Dim employees As Variant
    Dim shifts As Variant
    Dim days As Variant
    
    ' 従業員リストを配列に格納
    employees = Array("山田 太郎", "佐藤 次郎", "鈴木 三郎", "高橋 四郎", "伊藤 五郎")
    
    ' シフトの種類を配列に格納
    shifts = Array("午前", "午後", "休み")
    
    ' 曜日リストを配列に格納
    days = Array("月", "火", "水", "木", "金", "土", "日")
    
    ' シフト表ワークシートを選択
    Set ws = ThisWorkbook.Worksheets("シフト表")
    
    ' シフト表をクリアします。
    ws.Cells.Clear
    
    ' セルに従業員名を入力
    For i = LBound(employees) To UBound(employees)
        ws.Cells(i + 2, 1).Value = employees(i)
    Next i
    
    ' セルに曜日を入力
    For i = LBound(days) To UBound(days)
        ws.Cells(1, i + 2).Value = days(i)
    Next i
    
    ' セルにシフトをランダムに割り当て
    For i = LBound(employees) To UBound(employees)
        For j = LBound(days) To UBound(days)
            ws.Cells(i + 2, j + 2).Value = shifts(Int((UBound(shifts) + 1) * Rnd()))
        Next j
    Next i
    
    ' セル書式設定
    With ws.Range("A1").Resize(UBound(employees) + 2, UBound(days) + 2)
        .Cells(1, 1).Value = "氏名/曜日"
        .Rows(1).Interior.Color = RGB(255, 255, 153)
        .Borders.LineStyle = xlContinuous
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Columns(1).ColumnWidth = 15
        .Rows(1).RowHeight = 20
        .Rows(1).Font.Bold = True
    End With
    
    ' 印刷範囲の設定
    ws.PageSetup.PrintArea = ws.Range("A1").Resize(UBound(employees) + 2, UBound(days) + 2).Address
End Sub

 

●実行前~実行後 ※プログラムを実行すると、指定された従業員と曜日に対してランダムなシフトが割り当てられたシフト表が作成されます。シフト表ワークシートに従業員名、曜日、シフトの割り当てが整形されて出力されます。【注意】:シフト表の内容は、完全にランダムで行われるため、実際の業務要件や従業員の希望などは考慮されません。

 

 

 

 

EXCEL VBA シフト管理を簡単に!従業員のシフト表を自動生成(シフト表/開始日・作成日数を設定)

 

●プログラム説明 (サンプル②)

下記のプログラムは、従業員のシフトスケジュールを自動的に作成し、Excelワークシートに表示するためのものです。シフトの開始日と日数を指定し、従業員の名前とシフトの種類をもとに、ランダムにシフトを割り当てます。また、土日の日付と曜日を赤字で表示し、シフト種類の日別計をカウントして表示します。シフトの開始日と作成日数を指定することで、柔軟に従業員のシフトスケジュール表を作成する事ができます。

【プログラムの流れ】

  1. 変数を宣言し、従業員リストとシフトの種類を配列に格納します。
  2. 開始日と日数をInputBoxで入力し、変数に格納します。
  3. シフト表ワークシートを選択し、内容をクリアします。
  4. 従業員名をセルに入力します。
  5. 日付と曜日を入力し、土日を赤字で表示します。
  6. シフトをランダムに割り当てます。
  7. セルの書式設定を行います。
  8. シフト種類の日別計をカウントし、表示します。
  9. 印刷範囲を設定します。

【プログラム実行条件・注意事項】

  1. 実行条件: Excelがインストールされており、VBAが利用可能であること。また、このコードを実行するワークブックには、”シフト表”という名前のワークシートが存在している必要があります。
  2. 注意事項: 開始日と日数は正しい形式で入力する必要があります。また、従業員リストやシフトの種類を変更する場合は、コード内の配列を編集してください。
  3. 完全にランダムで行われるため、実際の業務要件や従業員の希望などは考慮されません。

★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● Shift_schedule02(サンプルプログラム)

 

Option Explicit
'
'
Sub CreateShiftSchedule02()
    Dim ws As Worksheet
    Dim i As Integer
    Dim j, k As Integer
    Dim employees As Variant
    Dim shifts As Variant
    Dim startDate As Date
    Dim totalDays As Integer
    
    ' 従業員リスト
    employees = Array("山田 太郎", "佐藤 次郎", "鈴木 三郎", "高橋 四郎", "伊藤 五郎")
    
    ' シフトの種類
    shifts = Array("午前", "午後", "休み")
    
    ' 開始日・日数をInputBoxで登録
    startDate = InputBox("シフト表の開始日を入力してください(例: 2023/4/22):", "開始日")
    totalDays = InputBox("シフト表の日数を入力してください(例: 30):", "日")
    

    ' シフト表ワークシートを選択
    Set ws = ThisWorkbook.Worksheets("シフト表")
    ' シフト表をクリアします。
    ws.Cells.Clear
    
    ' セルに従業員名を入力
    For i = LBound(employees) To UBound(employees)
        ws.Cells(i + 3, 1).Value = employees(i)
    Next i
    
    ' 日付と曜日を入力
    For i = 0 To totalDays - 1
        ws.Cells(1, i + 2).Value = DateAdd("d", i, startDate)
        ws.Cells(2, i + 2).Value = Format(ws.Cells(1, i + 2).Value, "[$-411]aaa")
        
        ' 土日は赤字にする
        If Weekday(ws.Cells(1, i + 2).Value) = 1 Or Weekday(ws.Cells(1, i + 2).Value) = 7 Then
            ws.Cells(1, i + 2).Font.Color = RGB(255, 0, 0)
            ws.Cells(2, i + 2).Font.Color = RGB(255, 0, 0)
        End If
    Next i
    
    ' シフトをランダムに割り当て
    For i = LBound(employees) To UBound(employees)
        For j = 0 To totalDays - 1
            ws.Cells(i + 3, j + 2).Value = shifts(Int((UBound(shifts) + 1) * Rnd()))
        Next j
    Next i
    
    ' セル書式設定
    With ws.Range("A1").Resize(UBound(employees) + 4, totalDays + 1)
        .Cells(1, 1).Value = "日付"
        .Cells(2, 1).Value = "曜日"
        .Rows(1).Interior.Color = RGB(255, 255, 153)
        .Rows(2).Interior.Color = RGB(153, 255, 255)
        .Borders.LineStyle = xlContinuous
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Columns(1).ColumnWidth = 15
        .Rows(1).RowHeight = 20
        .Rows(1).Font.Bold = True
        .Rows(2).Font.Bold = True
    End With
    
    ' シフト種類の日別計をカウント
        ' シフト種類の日別計をカウント
    For j = 0 To totalDays - 1
        For k = LBound(shifts) To UBound(shifts)
            ws.Cells(UBound(employees) + 4, j + 2).Value = ws.Cells(UBound(employees) + 4, j + 2).Value & Application.WorksheetFunction.CountIf(ws.Range(ws.Cells(3, j + 2), ws.Cells(UBound(employees) + 2, j + 2)), shifts(k)) & shifts(k) & " "
        Next k
    Next j

    ' 印刷範囲の設定
    ws.PageSetup.PrintArea = ws.Range("A1").Resize(UBound(employees) + 4, totalDays + 1).Address
End Sub
'
'

 

 

●実行前~実行後 ※プログラムを実行すると、指定された開始日と日数に基づくシフトスケジュールが作成されます。従業員名、日付、曜日、ランダムに割り当てられたシフトが表示され、土日の日付と曜日は赤字で表示されます。また、シフト種類の日別計がカウントされ、表示されます。

 

 

EXCEL VBA シフト管理を簡単に!従業員のシフト表を自動生成(シフト表/開始日・作成日数を設定)

 

 

●プログラム説明(サンプル③)

下記のプログラムは、従業員のシフトスケジュールを自動的に作成し、Excelワークシートに表示するためのものです。サンプル②と同様にシフトの開始日と日数を指定し、従業員の名前とシフトの種類をもとに、ランダムにシフトを割り当てます。また、土日の日付と曜日を赤字で表示し、シフト種類の日別計をカウントして表示します。今回のシフト表は、従業員名の追加やシフト種類(追加不可)も名称を変更する事ができます。更に、シフト種類ごとに日別の合計を集計する事ができます。スケジュール表も縦型に変更して長期日数のシフト表も作成する事ができます。

【プログラムの流れ】

  1. 開始日と日数をInputBoxで取得する。
  2. シフト表ワークシート(ws)および設定ワークシート(wsSettings)を選択する。
  3. シフト表ワークシートをクリアする。
  4. 日付と曜日をシフト表ワークシートに入力する。土日は赤字で表示する。
  5. 従業員名をシフト表ワークシートに入力する。
  6. シフトをランダムに割り当てる。
  7. セル書式を設定する。
  8. シフト種類の日別集計を行う。
  9. 印刷範囲を設定する。

【プログラム実行条件・注意事項】

  1. シフト表ワークシート(”シフト表”)および設定ワークシート(”設定”)が存在する必要があります。
  2. 設定ワークシートには、従業員名とシフトタイプがそれぞれ入力されている必要があります。
  3. 開始日と日数は、適切な形式で入力する必要があります(例: 2023/4/22、30)。
  4. 完全にランダムで行われるため、実際の業務要件や従業員の希望などは考慮されません。
    ※従業員は追加ができますが、シフト種類は3つ固定となっております。名所変更はOK

★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● Shift_schedule03(サンプルプログラム)

 

 

Option Explicit

'
'
Sub CreateShiftSchedule03()
    Dim ws As Worksheet, wsSettings As Worksheet
    Dim i As Integer, j As Integer, k As Integer
    Dim startDate As Date
    Dim totalDays As Integer
    
    ' 開始日をInputBoxで登録
    startDate = InputBox("シフト表の開始日を入力してください(例: 2023/4/22):", "開始日")
    totalDays = InputBox("シフト表の日数を入力してください(例: 30):", "日")
    
    ' シフト表ワークシートを作成・選択
    Set ws = ThisWorkbook.Worksheets("シフト表")
    ' 設定ワークシートを選択
    Set wsSettings = ThisWorkbook.Worksheets("設定")
    'ワークシート「シフト表」のクリア
    ws.Cells.Clear
    
    ' 日付と曜日を入力
    For i = 0 To totalDays - 1
        ws.Cells(i + 2, 1).Value = DateAdd("d", i, startDate)
        ws.Cells(i + 2, 2).Value = Format(ws.Cells(i + 2, 1).Value, "[$-411]aaa")
        
        ' 土日祝日は赤字にする
        If Weekday(ws.Cells(i + 2, 1).Value) = 1 Or Weekday(ws.Cells(i + 2, 1).Value) = 7 Then
            ws.Cells(i + 2, 1).Font.Color = RGB(255, 0, 0)
            ws.Cells(i + 2, 2).Font.Color = RGB(255, 0, 0)
        End If
    Next i
    
    ' セルに従業員名を入力
    i = 0
    Do While wsSettings.Cells(i + 2, 1).Value <> ""
        ws.Cells(1, i + 3).Value = wsSettings.Cells(i + 2, 1).Value
        i = i + 1
    Loop

    ' シフトをランダムに割り当て
    For i = 0 To totalDays - 1
        For j = 0 To wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row - 2
            ws.Cells(i + 2, j + 3).Value = wsSettings.Cells(Int((wsSettings.Cells(wsSettings.Rows.Count, 2).End(xlUp).Row - 1) * Rnd() + 2), 2).Value
        Next j
    Next i
    
    ' セル書式設定
    With ws.Range("A1").Resize(totalDays + 1, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + wsSettings.Cells(wsSettings.Rows.Count, 2).End(xlUp).Row)
        .Rows(1).Interior.Color = RGB(255, 153, 255)
        .Cells(1.1).Value = "日付"
        .Cells(1, 2).Value = "曜日"
        .Borders.LineStyle = xlContinuous
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Columns(1).ColumnWidth = 15
        .Rows(1).RowHeight = 20
        .Rows(1).Font.Bold = True
        .Columns(2).ColumnWidth = 5
    End With
    
    ' シフト種類の日別計をカウント
    For i = 0 To totalDays - 1
        For k = 0 To wsSettings.Cells(wsSettings.Rows.Count, 2).End(xlUp).Row - 2
            ws.Cells(i + 2, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + k + 2).Value = Application.WorksheetFunction.CountIf(ws.Range(ws.Cells(i + 2, 3), ws.Cells(i + 2, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + 1)), wsSettings.Cells(k + 2, 2).Value)
            ws.Cells(1, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + k + 2).Value = wsSettings.Cells(k + 2, 2).Value
        Next k
    Next i
    
    ' 印刷範囲の設定
    ws.PageSetup.PrintArea = ws.Range("A1").Resize(totalDays + 1, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + wsSettings.Cells(wsSettings.Rows.Count, 2).End(xlUp).Row).Address
    
    End Sub
'
'

 

 

●実行前~実行後 ※プログラムを実行すると、指定された期間にわたるシフトスケジュールが作成されます。各従業員にランダムにシフトが割り当てられ、土日は赤字で表示されます。また、シフトの日別集計も行われます。

 

 

 

EXCEL VBA シフト管理を簡単に!従業員のシフト表を自動生成・シフトの人数を適正に管理する。

 

●プログラム説明(サンプル④)

下記のプログラムは、従業員のシフトスケジュールを自動的に作成し、Excelワークシートに表示するためのものです。サンプル③の改良版です。サンプル③では、ランダムでシフト表を生成するため日によっては、Aシフト・Bシフト・休みの偏りが発生します。子の偏りをなくすためにシフト表を生成する際に条件を設定してシフト表の偏りを無く仕組みを追加しました。

【シフト表を生成する条件】
① Aシフト・Bシフト・共に1名以上シフト表に登録される。
② 7日間に1回は休みのシフトを登録する。
※ ①②の条件で作成していますが、詳細にチェックしていませんので、従業員数の増減により条件を満たされない可能性もありますので、ご了承ください。

【プログラムの流れ】

  1. シフト表と設定ワークシートをそれぞれ ws と wsSettings に設定
  2. シフト表ワークシートをクリア
  3. 開始日とシフト表の日数をInputBoxで入力
  4. 従業員名を設定ワークシートからシフト表ワークシートにコピー
  5. 日付と曜日をシフト表ワークシートに入力し、土日の文字色を赤に変更
  6. シフトを割り当てるロジックに基づいて、シフトをシフト表ワークシートに入力
  7. シフト表ワークシートの書式を整える
  8. シフト種類の日別集計を行い、シフト表ワークシートに入力
  9. 印刷範囲を設定

【プログラム実行条件・注意事項】

  1. シフト表ワークシート(”シフト表”)および設定ワークシート(”設定”)が存在する必要があります。
  2. 設定ワークシートには、従業員名とシフトタイプがそれぞれ入力されている必要があります。
  3. 開始日と日数は、適切な形式で入力する必要があります(例: 2023/4/22、30)。
  4. 完全にランダムで行われるため、実際の業務要件や従業員の希望などは考慮されません。
    ※従業員は追加ができますが、シフト種類は3つ固定となっております。名所変更はOK

★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● Shift_schedule04(サンプルプログラム)

 

【今回の①~④のサンプルプログラムについて】
サンプルプログラムでは、ランダムで行われるため、実際の業務要件や従業員の希望などは考慮されません。このサンプルプログラムを業務で利用する場合は、必要に応じてシフト割り当てのルールや条件を更に追加して、より適切なシフトスケジュールが作成できるように改良することをお勧めします。例えば、以下のような改良が考えられます。

  • 一定の期間内での最大勤務日数や連続勤務日数の制限
  • 従業員の希望シフトを優先して割り当てる機能
  • 特定の曜日や時間帯に必要な最低限のスタッフ数を確保する機能
  • 従業員間でシフトのバランスが取れるように割り当てる機能

これらの改良を加えることで、実際の業務に適したシフトスケジュール作成ツールになりますので、挑戦してみてください。

 

Option Explicit
'
'
Sub CreateShiftSchedule06()

    Dim ws As Worksheet, wsSettings As Worksheet
    Dim i As Integer, j As Integer
    Dim startDate As Date
    Dim totalDays As Integer
    
    ' シフト表ワークシートを作成・選択
    Set ws = ThisWorkbook.Worksheets("シフト表")
    ' 設定ワークシートを選択
    Set wsSettings = ThisWorkbook.Worksheets("設定")
    
    ' シフト表をクリアする。
     ws.Cells.Clear
    
    ' 開始日・日数をInputBoxで登録
    startDate = InputBox("シフト表の開始日を入力してください(例: 2023/4/22):", "開始日")
    totalDays = InputBox("シフト表の日数を入力してください(例: 30):", "日")
        
    
    ' セルに従業員名を入力
    i = 0
    Do While wsSettings.Cells(i + 2, 1).Value <> ""
        ws.Cells(1, i + 3).Value = wsSettings.Cells(i + 2, 1).Value
        i = i + 1
    Loop

    ' 日付と曜日を入力
    For i = 0 To totalDays - 1
        ws.Cells(i + 2, 1).Value = DateAdd("d", i, startDate)
        ws.Cells(i + 2, 2).Value = Format(ws.Cells(i + 2, 1).Value, "ddd")
        
        ' 土日祝日は赤字にする
        If Weekday(ws.Cells(i + 2, 1).Value) = 1 Or Weekday(ws.Cells(i + 2, 1).Value) = 7 Then
            ws.Cells(i + 2, 1).Font.Color = RGB(255, 0, 0)
            ws.Cells(i + 2, 2).Font.Color = RGB(255, 0, 0)
        End If
    Next i
    For i = 0 To totalDays - 1
        Dim totalEmployees As Integer
        totalEmployees = wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row - 1
        
        For j = 0 To totalEmployees - 1
            If i Mod 5 = j Mod 5 Then
                ws.Cells(i + 2, j + 3).Value = "休み"
            ElseIf j Mod 2 = 0 Then
                ws.Cells(i + 2, j + 3).Value = "Aシフト"
            Else
                ws.Cells(i + 2, j + 3).Value = "Bシフト"
            End If
        Next j
    Next i
    
    ' セル書式設定

    For i = 2 To totalDays + 1 Step 2
        ws.Range("A" & i).Resize(1, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + wsSettings.Cells(wsSettings.Rows.Count, 2).End(xlUp).Row).Interior.Color = RGB(235, 235, 235)
    Next i
    
    With ws.Range("A1").Resize(totalDays + 1, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + wsSettings.Cells(wsSettings.Rows.Count, 2).End(xlUp).Row)
        .Cells(1, 1).Value = "日付"
        .Cells(1, 2).Value = "曜日"
        .Rows(1).Interior.Color = RGB(255, 255, 153)
        .Rows("2:2").Interior.Color = RGB(235, 235, 235)
        .Rows("4:4").Interior.Color = RGB(235, 235, 235)
        .Borders.LineStyle = xlContinuous
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .Columns(1).ColumnWidth = 15
        .Rows(1).RowHeight = 20
        .Rows(1).Font.Bold = True
        .Columns(2).ColumnWidth = 5
    End With
    
    ' シフト種類の日別計をカウント
    For i = 0 To totalDays - 1
        For j = 0 To wsSettings.Cells(wsSettings.Rows.Count, 2).End(xlUp).Row - 2
            ws.Cells(i + 2, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + j + 2).Value = Application.WorksheetFunction.CountIf(ws.Range(ws.Cells(i + 2, 3), ws.Cells(i + 2, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + 1)), wsSettings.Cells(j + 2, 2).Value)
            ws.Cells(1, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + j + 2).Value = wsSettings.Cells(j + 2, 2).Value
        Next j
    Next i
    
    ' 印刷範囲の設定
    ws.PageSetup.PrintArea = ws.Range("A1").Resize(totalDays + 1, wsSettings.Cells(wsSettings.Rows.Count, 1).End(xlUp).Row + wsSettings.Cells(wsSettings.Rows.Count, 2).End(xlUp).Row).Address

End Sub
'
'

 

 

●実行前~実行後 ※プログラムを実行すると、指定された期間にわたるシフトスケジュールが作成されます。各従業員に条件に合ったにシフトが割り当てられ、土日は赤字で表示されます。また、シフトの日別集計も行われます。

 

 

最後まで、ご覧いただきまして誠に有難うございました。
また、VBAに関するテクニックや便利な手法などをこのサイトに掲載していきますので、定期的に参照していただけると幸いです。

 

AKIRA