「毎月のシフト作成が大変…」
「人数が多いと並べ替えが面倒…」
「公平にシフトを割り当てたい」
そんな悩みを解決するのが、ExcelVBAでシフト表を自動生成するマクロです。
今回紹介するマクロは、以下のような実務向けのポイントを押さえています:
- メンバーをランダムで割り当て(偏りを防ぐ)
- 希望休(休みたい日)を反映
- 1日1人以上の配置を保証
- 月の日数を自動判定
目次
シフト表の準備
まずはExcelに2つのシートを用意します。
①「メンバー」シート(スタッフ一覧)

希望休(休みたい日)は「5,12」のように数字で入力します。
空欄の場合は希望休なしとして扱います。
②「シフト表」シート(結果を自動生成)

日付は1〜31まで入力しておけば、月の日数に合わせて自動処理します。
シフト自動生成マクロ(コピペOK)
以下のコードを標準モジュールに貼り付けます。
Option Explicit
Sub CreateShift()
Dim wsM As Worksheet ' メンバーシート
Dim wsS As Worksheet ' シフト表
Dim lastRow As Long
Dim i As Long, d As Long
Dim memberList() As String
Dim holidays As Object
Dim pick As String
Dim dayCount As Long
Set wsM = Worksheets("メンバー")
Set wsS = Worksheets("シフト表")
' メンバーリストを配列に格納
lastRow = wsM.Cells(wsM.Rows.Count, 1).End(xlUp).Row
ReDim memberList(1 To lastRow - 1)
For i = 2 To lastRow
memberList(i - 1) = wsM.Cells(i, 1).Value
Next i
' 月の日数(シフト表のA列で判定)
dayCount = wsS.Cells(wsS.Rows.Count, 1).End(xlUp).Row - 1
' 希望休管理用 Dictionary
Set holidays = CreateObject("Scripting.Dictionary")
For i = 2 To lastRow
Dim arr
arr = Split(wsM.Cells(i, 2).Value, ",")
holidays(wsM.Cells(i, 1).Value) = arr
Next i
' シフト自動生成ループ
For d = 1 To dayCount
Dim candidates As Collection
Set candidates = New Collection
' 希望休ではない人を候補にする
For i = 1 To UBound(memberList)
Dim name As String
name = memberList(i)
Dim hArr
hArr = holidays(name)
Dim isHoliday As Boolean: isHoliday = False
' 希望休チェック
Dim n As Variant
For Each n In hArr
If Trim(n) = CStr(d) Then
isHoliday = True
Exit For
End If
Next n
If Not isHoliday Then
candidates.Add name
End If
Next i
' 候補がいない場合 → 全員からランダム
If candidates.Count = 0 Then
pick = memberList(Int((UBound(memberList)) * Rnd) + 1)
Else
pick = candidates(Int(candidates.Count * Rnd) + 1)
End If
wsS.Cells(d + 1, 2).Value = pick
Next d
MsgBox "シフト表を自動作成しました!", vbInformation
End Sub
コード解説(初心者向け)
① メンバーを配列に取り込む
memberList(i - 1) = wsM.Cells(i, 1).Value
スタッフ名を配列に格納して、ランダム抽選に使います。
② 希望休を Dictionary で管理
holidays(name) = arr
「田中 → {5,12}」のように、
スタッフごとに休みたい日を記録します。
③ 希望休を除外してランダム抽選
If Not isHoliday Then candidates.Add name
候補リストを作り、その中からランダムに選ぶ方式。
④ 希望休が全員の時は fallback(全員からランダム)
If candidates.Count = 0 Then
「全員休みたい日」でも問題なくシフトを作成します。
応用:機能を追加したい場合
① 1日に複数人配置したい
この部分を複数回ループすればOKです。
For p = 1 To 2 ' 2名配置例
'抽選処理をここに入れる
Next p
② シフトの偏りを均等にしたい
回数をカウントして最も少ない人を優先する方式も可能です。
wsS.Columns(2).Find(name)
③「早番/遅番」2つの枠に分けたい
B列とC列を別々に自動生成する形で対応できます。
実行手順
- 「メンバー」「シフト表」の2つのシートを作成する
- メンバー名と希望休を記入する
- 標準モジュールに今回のコードを貼り付ける
- Excelメニュー →「開発」→「マクロ」→
CreateShiftを実行 - シフト表に自動で担当者が入力される
これだけで、毎月のシフト作成が一瞬で終わります。
人数が多くても処理が軽く、現場でも十分使える実用的なマクロです。
まとめ:VBAならシフト作成も自動化できる
今回のマクロのポイントは以下のとおりです。
- スタッフ一覧と希望休を元に自動割り当て
- 全員休みの日でも処理が止まらない
- 希望休を優先したランダム抽選で公平なシフトが完成
- 勤務表・シフト・当番表など幅広く応用可能
シフト作成は毎月同じ作業なので、ぜひVBAで自動化してみてください。
応用版(早番/遅番、偏り調整など)も作成しますので、コメントいただければ拡張記事も書きます!


コメント