ソルバーによるシフト表自動作成
エクセルのアドイン機能に、シミュレーションツールの一つ「ソルバー」があります。
従来、ソルバーは整数の扱いが不得手のようでしたが、エクセル2010からエボリューショナリー機能が追加されました。
これにより、魔方陣や数独(そして本例のシフト表作成)のような非線形の整数問題を解くことが可能になりました。
ここでは、ソルバー機能をフルに活用し(のちにはVBA機能も)、シフト表の自動作成を試みてみます。
注: 本ツールはEXCEL2010以上で動作します。(2007以下は不可)
- 最終的に作成したいシフト表
サンプルファイル(ダウンロード shift-solver30.zip)の使用方法
ソルバーとは 「ソルバーアドイン」の組み込み ソルバーの使い方
目次
1. - 日々の必要人数を個人単位で割り振る
2. - 日勤や夜勤のように複数の勤務種別を均等割振
3. - 連続してはいけない勤務の組み合わせを指定
4.
- 各人が出来ない勤務を日単位で指定する
5.
- ソルバーを使用して勤務日数を均等化
6.
- 別のアドインを使用して勤務日数を均等化
7.
- 早出および遅出が不可のように複数の不可勤務を指定
8. - 数値ではなく、リストから勤務名として指定できるようにする
以下、マクロ(VBA)使用
9. - 入力から実行までをマクロ等を利用してなるべく自動化
10. - リストから複数の組み合わせで入力可
11. - 要員氏名を任意に追加削除可能
12. - 前もって、指定日に希望勤務を予約しておく
14. - 休みが指定日数以上続くのを抑制
15. - 勤務が指定日数以上続くのを抑制
16. - 前旬末1週間のデータを作成に反映
17. - 重複チェック、勤務色自動反映
18. - 作成完了までの時間を短縮する工夫
19. - 過去の勤務日数を均等化に反映
途中
20. - 期間を2週間、人員を7人にしたシフト表
21. - 勤務日数を指定し、不足分は自動調整
22. - 出来たシフト表を調整、または変更するための仕掛け
- ソースコード
変更履歴
作成するシフト表の仕様
最終的には、ソルバー、
および、VBAを使用して、
データを入力しボタンをクリックするだけで、シフト表が全自動で作成されるようにな仕掛けを作成します。
下の例のように、日々の必要人数を勤務ごとに指定し、
不可条件を課して、要員を割り振ります。
本例では、
2週間、3種類の勤務、7人体制
―――――――――――――――――――――――――
要員設定
日々勤務ごとに必要な人数を指定、また、超過できる勤務とその数を指定
超過可能数は、予定勤務数に満たない場合の
勤務日数自動調整に使用
不可条件
個人単位にできない勤務を日ごとに設定 (フォームから複数勤務の組み合わせで指定可)

岸伸介 3,4日は全部の勤務が不可としているので「
休み」を意味する
連続不可条件
連続してはいけない勤務を指定
「早出」の翌日の「遅出」
「遅出」の翌日の「早出」
「早出」の3連続 |
|
 |
予約勤務
あらかじめ日にちと勤務を決めて置きたい場合(入力規則リストから選択)
期間内における勤務日数の偏りを最小化
出力と集計表

勤務日数、連続休み数、連続勤務数は、理想的な値で均等化されています。
個別に均等化を重視したい場合は、各重みで調整。
(上図の
黒枠内の数値)
条件設定
操作方法
「
全自動実行」ボタンをクリックすると、
薄い黄色のセル内に、全ての条件を満たす要員配置ができました。
(3.30Ghz、5Gbメモリ、64ビットPCで約2分)
ダウンロード後実行して、コンパイルエラーメッセージが出る場合
要員の
人数、作成するシフト表の
期間
下図の例は2週間、ステップ別説明は1週間分
期間/人数は、行列を追加することで(ある程度)
拡張可。(我慢できる時間内に解が求まるかの問題・・・)
入力部:黒枠内は入力データ。
出力部:勤務シフト表 が自動作成される。(黄色セル)
計算部:入
力データを計算できるように
数値に変換
初期情報:
下図の
黒枠内に入力
・複数の勤務種別
日:日勤 早:早出 遅:遅出 の3種類
(勤務の種類数に制限は無し - PC/ソルバーの性能次第)
・必要人数の指定
曜日(日)単位に必要な人数を指定
(人数の制限は無し - ソルバーの性能次第)
目標値
・目的セル(過不足計=必要人数と割当人数の差)
が0になること。
・分散計(勤務日数のばらつき)が最少となること。
・連続休み個数を最少化-3連休、4連休などの発生を抑制
・連続勤務個数を最小化-6連勤、7連勤などの発生を抑制
・その他-順次条件を追加
入力チェック
予約勤務と不可勤務の重複
予約勤務と連続不可勤務との整合
自動作成
出力部の青枠内に出力
入力情報と禁止条件を元に、勤務数のバラツキが最小となるように要員を配置
バラツキは、個人単位の日数合計、勤務種別ごとの日数合計の分散計を最小化
手動作成
個別のボタンクリックで、段階を経て作成可能
配色
勤務の背景色と文字の色は勤務テーブルで指定する。
指定された背景色と文字色がVBAでシフト表に自動反映される。
「勤務色更新」ボタンで手動でも更新可
使用しているエクセルの技
1. - 日々の必要人数を個人単位で割り振る
SUM:合計算出
COUNTIF:条件を満たすセルの個数、
ABS:絶対値に変換
ソルバー:線形問題解法(
シンプレックスLP)
2. - 日勤や夜勤のように複数の勤務種別を均等割振
ソルバー:進化論的解法(
エボリューショナリ)
3. - 連続してはいけない勤務の組み合わせを指定
文字列の連結:「
&」
演算子
COUNTIF:ワイルドカードを使った条件付き集計
(文字列中に指定文字列が含まれるかを判定:連続不可勤務)
4.
- 各人が出来ない勤務を日単位で指定する
配列数式:勤務ごとの個数集計(クロス集計)
(右側のセルが空白でなく、かつ、左側のセルと値が一致しているセルの個数)
5.
- ソルバーを使用して勤務日数を均等化
均等化:標準アドインの組み込み方法
ソルバーアドインを使用して均等化を図る(失敗)
6. - 別のアドインを使用して勤務日数を均等化
均等化:「
均等再配置」アドインを使用して勤務日数のバラツキを少なくする
ユーザーアドインの組み込み方
VARPA(分散値):個人単位での勤務個数のバラツキを求める
7.
- 早出および遅出が不可のように複数の不可勤務を指定
入力チェック:カンマ区切りデータから
重複チェック
配列数式を使用して不可勤務指定
8. - 数値ではなく、リストから勤務名として指定できるようにする
文字列処理:文字列から計算用の数値に変換、文字列に復元して出力
ユーザー定義関数
MyConnectAll:範囲内のセル文字列を全て連結(区切り文字指定可)
MyReplaceAll:テーブルに従い範囲内の文字列を全て置換
入力規則:リストから選択して入力
9.
-
入力から実行までをマクロ等を利用してなるべく自動化
VBA:コマンドボタン、
ソルバー関連関数(SolverOk)、
均等再配置(ReAllocate)
10.
- リストから複数の組み合わせで入力できるようにする
フォーム:VBAを使用して
ユーザーフォーム&
リストボックス(複数項目選択可)を使用
11.
- 要員氏名を任意に追加削除可能とする
入力範囲を可変:
Offset関数、
名前の動的定義
キー処理:入力されたキーを取得(
GetAsyncKeyState)
ソルバーダイアログ表示関数:
SolverOkDialog関数
条件付きコンパイル:32/64ビット版Officeへの対応(
#If
Win64 Then ~ #Else ~ #End If)
12.
- 前もって、指定日に希望勤務を予約しておく
配列数式による集計:文字列の中に
含まれる指定文字列の個数を算出
転記:
VBAによる範囲内文字列の全転記
14.
連続休み日数の制限 - 休みが指定日数以上続くのを抑制
連続文字列のブロックす個数:
SUBSTITUTE関数を使用して指定文字列(連続休み)の
ブロック個数を求める
SUMPRODUCT関数による配列間積の総和 - 連続休み数に重みを付ける
15.
連続勤務日数の制限 - 勤務が指定日数以上続くのを 抑制
正規表現:指定文字列のブロック個数を求めるVBAユーザー定義関数(
MyRegCount)作成
16.
前旬データを考慮 - 前旬末1週間のデータを作成に反映
フォーム:チェックボックス
列の非表示:VBAを使用して、指定範囲列の表示/非表示を切り替える(Range.
EntireColum.Hidden=TRUE/FALSE)
17. - 予約/不可/連続不可勤務間の重複チェック、勤務色自動反映
条件付き書式:指定条件を満たす(または満たさない)セルの色を変える
セルの文字色/背景色変更:VBAを使用して、指定範囲のセル書式(
Interior.Color/Color)を個別変更する
18.
実行速度改良&汎用化 - 解に達するまでの時間を短縮する工夫
ソルバーパラメータの動的変更:SolverOptions関数を使用して、パラメータを変更
19.過去勤務状況を反映 - 過去の勤務日数を均等化に反映
20.
- 期間を2週間、人員を7人にしたシフト表
21.
予定勤務日数 - 勤務日数を指定し、不足分は自動調整
あらかじめ予定勤務日数を表として指定する。要員数と予定日数の差は、自動で勤務を割り当てる
自動で割り当てる勤務と超過可能数は表で指定。
例:日数に満たない場合は「日勤」を割り振って予定勤務日数になるように調整
22.
手動調整 - 出来上がったシフト表を調整、または変更するための仕掛け
フォームから略称名の候補リストから選択して変更できるようにする。
候補は変更可能な条件により、色分けする。
また、誤って数式が破壊されないように、シートの保護機能を設定する。
次項以降で実際に順を追って(簡素な条件から初めて、徐々に条件を追加)処理していきます。
関連