〖ExcelVBA〗シフト表を自動生成するマクロ|ランダム割り当て+希望休対応の簡単システム

ExcelVBA

「毎月のシフト作成が大変…」
「人数が多いと並べ替えが面倒…」
「公平にシフトを割り当てたい」

そんな悩みを解決するのが、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列を別々に自動生成する形で対応できます。

実行手順

  1. 「メンバー」「シフト表」の2つのシートを作成する
  2. メンバー名と希望休を記入する
  3. 標準モジュールに今回のコードを貼り付ける
  4. Excelメニュー →「開発」→「マクロ」→ CreateShift を実行
  5. シフト表に自動で担当者が入力される

これだけで、毎月のシフト作成が一瞬で終わります。
人数が多くても処理が軽く、現場でも十分使える実用的なマクロです。

まとめ:VBAならシフト作成も自動化できる

今回のマクロのポイントは以下のとおりです。

  • スタッフ一覧と希望休を元に自動割り当て
  • 全員休みの日でも処理が止まらない
  • 希望休を優先したランダム抽選で公平なシフトが完成
  • 勤務表・シフト・当番表など幅広く応用可能

シフト作成は毎月同じ作業なので、ぜひVBAで自動化してみてください。
応用版(早番/遅番、偏り調整など)も作成しますので、コメントいただければ拡張記事も書きます!

スポンサーリンク
スポンサーリンク
ExcelVBA
いがぴをフォローする

コメント

タイトルとURLをコピーしました