今回説明するのは、Excel VBAを使用したシフト管理マクロをご紹介します。このコードを使うことで、従業員のシフトスケジュールを簡単かつ効率的に作成する事ができます。会社の従業員の人数や日数に応じて柔軟に対応できるため、さまざまな業種で活用できます。また、土日の赤字表示やシフトの自動割り当てなど、効率化と利便性が向上します。手作業でシフト表を作成する手間を大幅に削減し、業務効率化に貢献できると思います。あくまでも簡易的なプログラムなために参考にしていただけると嬉しいです。それでは、順番に説明をいたします。
●【EXCEL VBA 氏名からメールアドレスを自動生成・名前情報からメールを作成・業務効率化パスワードについては、下記を参照して下さい】
●【EXCEL VBA パスワードの自動作成・ランダムパスワードの生成については、下記を参照して下さい】
下記のプログラムは、従業員のシフト表を自動生成します。月曜日~日曜日までのシフト表を自動生成します。具体的なこのプログラムは、従業員名、シフトの種類(午前、午後、休み)、曜日をもとにして、ランダムにシフトを割り当て、書式設定を行い、シフト表ワークシートに出力することができます。
【プログラムの流れ】
【プログラム実行条件・注意事項】
★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● 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ワークシートに表示するためのものです。シフトの開始日と日数を指定し、従業員の名前とシフトの種類をもとに、ランダムにシフトを割り当てます。また、土日の日付と曜日を赤字で表示し、シフト種類の日別計をカウントして表示します。シフトの開始日と作成日数を指定することで、柔軟に従業員のシフトスケジュール表を作成する事ができます。
【プログラムの流れ】
【プログラム実行条件・注意事項】
★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● 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ワークシートに表示するためのものです。サンプル②と同様にシフトの開始日と日数を指定し、従業員の名前とシフトの種類をもとに、ランダムにシフトを割り当てます。また、土日の日付と曜日を赤字で表示し、シフト種類の日別計をカウントして表示します。今回のシフト表は、従業員名の追加やシフト種類(追加不可)も名称を変更する事ができます。更に、シフト種類ごとに日別の合計を集計する事ができます。スケジュール表も縦型に変更して長期日数のシフト表も作成する事ができます。
【プログラムの流れ】
【プログラム実行条件・注意事項】
★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● 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ワークシートに表示するためのものです。サンプル③の改良版です。サンプル③では、ランダムでシフト表を生成するため日によっては、Aシフト・Bシフト・休みの偏りが発生します。子の偏りをなくすためにシフト表を生成する際に条件を設定してシフト表の偏りを無く仕組みを追加しました。
【シフト表を生成する条件】
① Aシフト・Bシフト・共に1名以上シフト表に登録される。
② 7日間に1回は休みのシフトを登録する。
※ ①②の条件で作成していますが、詳細にチェックしていませんので、従業員数の増減により条件を満たされない可能性もありますので、ご了承ください。
【プログラムの流れ】
【プログラム実行条件・注意事項】
★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● 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
'
'