〖ExcelVBA〗担当者を自動割り振りする勤務表マクロ|公平にローテーションする仕組みを作る

ExcelVBA

「窓口担当」「電話当番」「雑務担当」など、
毎日担当を決めるのって、地味に大変ですよね。

人が増えると、偏りなくローテーションさせることも難しくなります。
そこで今回は、ExcelVBAで担当者を自動割り振りする勤務表マクロを紹介します。

今回のマクロはこんなイメージです。

  • 「担当者一覧」シートにメンバーを登録
  • 「勤務表」シートに日付と担当区分(窓口・電話・雑務など)を用意
  • ボタン1つで、担当者が順番にローテーションして自動で割り振られる
担当者を自動割り振りする勤務表イメージ
図:勤務表マクロで担当者を自動割り振りしたイメージ

スポンサーリンク
スポンサーリンク

この記事で作るもの

今回は、次のようなシンプルな勤務表を例にします。

① 担当者一覧シート(シート名:担当者一覧)

② 勤務表シート(シート名:勤務表)

この状態でマクロを実行すると、
メンバーがぐるぐると順番にローテーションして担当が自動で埋まるようにします。


マクロの全体像(コピペOK)

以下のコードを標準モジュールに貼り付けるだけで動きます。

Option Explicit

' 勤務表に担当者を自動割り振りするマクロ
Sub AssignDuty()

    Dim wsMember As Worksheet   ' 担当者一覧シート
    Dim wsDuty As Worksheet     ' 勤務表シート
    Dim lastMemberRow As Long
    Dim lastDutyRow As Long

    Dim members() As String     ' 担当者名を入れる配列
    Dim memberCount As Long
    Dim i As Long, r As Long, c As Long
    Dim idx As Long             ' ローテーション用インデックス

    ' シートをセット
    Set wsMember = Worksheets("担当者一覧")
    Set wsDuty = Worksheets("勤務表")

    ' 担当者一覧の最終行を取得(A列)
    lastMemberRow = wsMember.Cells(wsMember.Rows.Count, "A").End(xlUp).Row
    memberCount = lastMemberRow - 1   ' 1行目は見出し想定なら -1、見出しなしならそのまま

    If memberCount <= 0 Then
        MsgBox "担当者一覧シートに担当者が登録されていません。", vbExclamation
        Exit Sub
    End If

    ' 担当者配列を作成(2行目から下を読み込む想定)
    ReDim members(1 To memberCount)

    For i = 1 To memberCount
        members(i) = wsMember.Cells(i + 1, "A").Value
    Next i

    ' 勤務表の日付行数を取得(A列)
    lastDutyRow = wsDuty.Cells(wsDuty.Rows.Count, "A").End(xlUp).Row

    If lastDutyRow <= 1 Then
        MsgBox "勤務表シートのA列に日付が入力されていません。", vbExclamation
        Exit Sub
    End If

    ' 既存の担当者列(B列以降)をクリア
    wsDuty.Range(wsDuty.Cells(2, 2), wsDuty.Cells(lastDutyRow, wsDuty.Cells(1, wsDuty.Columns.Count).End(xlToLeft).Column)).ClearContents

    ' ローテーション開始位置
    idx = 1

    ' 行(=日付)ごとに、列(=担当区分)を埋めていく
    For r = 2 To lastDutyRow          ' 2行目から最終行まで

        ' 1行目の最終列(=担当区分の右端)を取得
        Dim lastCol As Long
        lastCol = wsDuty.Cells(1, wsDuty.Columns.Count).End(xlToLeft).Column

        For c = 2 To lastCol          ' B列(2) から 最終列 まで

            wsDuty.Cells(r, c).Value = members(idx)

            ' 次の担当者にインデックスを進める(末尾まで行ったら先頭に戻る)
            idx = idx + 1
            If idx > memberCount Then
                idx = 1
            End If

        Next c

    Next r

    MsgBox "勤務表の担当者割り振りが完了しました。", vbInformation

End Sub

コードのポイント解説(初心者向け)

① 担当者を配列に入れておく

ReDim members(1 To memberCount)

For i = 1 To memberCount
    members(i) = wsMember.Cells(i + 1, "A").Value
Next i

「担当者一覧」シートの A 列から、担当者名を配列に読み込みます。
配列にしておくことで、ぐるぐる順番に割り当てる処理が簡単になります。

② 勤務表の日数と列数を自動で判定

lastDutyRow = wsDuty.Cells(wsDuty.Rows.Count, "A").End(xlUp).Row
lastCol = wsDuty.Cells(1, wsDuty.Columns.Count).End(xlToLeft).Column

– A列 … 日付が入っている行の最後までを勤務対象 – 1行目 … B列以降に「窓口」「電話」「雑務」などの担当区分が入っている想定

そのため、列数を増やしても減らしても、マクロ側は自動で対応できます。

③ ローテーション(ぐるぐる回す)処理

wsDuty.Cells(r, c).Value = members(idx)

idx = idx + 1
If idx > memberCount Then
    idx = 1
End If

ここが一番大事な部分です。
担当者配列 members() のインデックス idx を1つずつ進め、最後まで行ったら1に戻すことで、
担当者を公平にローテーションしていく仕組みを実現しています。

④ 既存の担当割り振りは一旦クリア

wsDuty.Range(wsDuty.Cells(2, 2), wsDuty.Cells(lastDutyRow, lastCol)).ClearContents

何度もマクロを実行しても問題ないように、 まずは担当者欄(B列〜最終列、2行目〜最終行)を一度クリアしてから割り当て直しています。


応用テクニック:もう一歩実務寄りにするなら

① 土日を飛ばしたい(平日だけ担当者を割り当てたい)

A列に日付が入っている前提で、
For r = 2 To lastDutyRow のループ内に「曜日判定」を入れると、土日をスキップできます。

Dim d As Date
d = wsDuty.Cells(r, 1).Value

If Weekday(d, vbMonday) > 5 Then
    ' 土日なら飛ばす(6=土, 7=日)
    GoTo NextRow
End If

' …ここに担当割り振り処理…

NextRow:
Next r

② 特定の担当は「この人だけ」にしたい

例えば、「電話」は必ず新人以外にしたい…などの制約がある場合は、
列ごとに担当候補リストを変える方法もあります。

  • C列(電話)用の配列 phoneMembers()
  • B列(窓口)用の配列 windowMembers()

といった形で、列ごとにローテーション対象を変えることもできます。

③ 担当回数をカウントして「より少ない人」を優先

今回のマクロは「ぐるぐる順番に回す」方式でしたが、
「担当回数が少ない人を優先する」という方式に変えることもできます。

その場合は、勤務表の下部などに「担当回数」を集計しておき、 VBAでそれを参照しながら担当を決めるようにします。


マクロの設置と実行手順

  1. 「担当者一覧」シートと「勤務表」シートを作成する
  2. 担当者一覧シートのA列にメンバー名を入力する(2行目から下)
  3. 勤務表シートのA列に日付、1行目のB列以降に「窓口」「電話」などの見出しを入力する
  4. Alt + F11 でVBEを開き、「挿入」→「標準モジュール」を選択
  5. 今回の AssignDuty マクロを貼り付ける
  6. Excelに戻り、「開発」タブ →「マクロ」→ AssignDuty を実行

これで、勤務表に担当者が自動で割り振られます。


まとめ:担当者の公平なローテーションはVBAで一発

今回は、担当者を自動割り振りする勤務表マクロをご紹介しました。

  • 担当者一覧シートからメンバーを配列に読み込む
  • 勤務表の行(=日付)×列(=担当区分)を一気に埋める
  • 配列のインデックスをぐるぐる回すことで公平にローテーション
  • 土日スキップ・担当ごとの候補制限など、実務に合わせて応用可能

毎月・毎週の担当決めは、意外と時間と気を遣う作業です。
一度マクロを作ってしまえば、ボタン一つで何度でもやり直しができるので、
ぜひご自身の勤務表に合わせてカスタマイズしてみてください。

「この条件も加えたい」「三交代制に対応したい」などのご要望があれば、
応用編として別記事で取り上げることもできますので、ぜひコメントなどで教えてください。

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

コメント

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