このプロジェクトでは、制約開始日前6日を見ることで7日間中の月曜日を検出しています。
正しく制約表示開始日が設定されていないと、その後の計算が全て狂ってしまいます。
なので、制約開始日が正しく設定されてない場合は、エラーを出して終了としています。
そのためのコードが次です。(下記以外にimport ctypesが必要です。)
今回プロジェクトでの全体ソースです。
import sc3
import ctypes
def 予定以外の今月区間の来振休を禁止():
for person in 全スタッフ:
for day in 今月区間:
if shift_schedules[person][day][0] =="来月振休" or shift_schedules[person][day][0]!="":#ハード来振休はスキップ
continue
v=sc3.GetShiftVar(person,day,"来月振休")#それ以外は禁止
s=staffdef[person]+daydef[day]+"来振休禁止"
sc3.AddHard(~v,s)
def 振休今月区間の日夜勤数は第1週から第8週までの振休数に等しい(person,weeks):
夜日リスト=[]
振休リスト=[]
来月残振休リスト=[]
include_next_month_day=False
for day in weeks:
if day < 制約開始日:
continue
if day in 今月区間休日前:
if person in 夜勤可能者:
vt=sc3.GetTaskVar(person,day,0,"夜勤")
夜日リスト.append(vt)
if day in 今月区間休日:
vs=sc3.GetShiftVar(person,day,"日勤")
夜日リスト.append(vs)
if day in 今月区間平日:
v=sc3.GetShiftVar(person,day,"振休")
振休リスト.append(v)
if day in 来月区間平日:
v=sc3.GetShiftVar(person,day,"来月振休")
振休リスト.append(v)
include_next_month_day=True
if day in 来月区間平日:
if day not in weeks:
v=sc3.GetShiftVar(person,day,"来月振休")
来月残振休リスト.append(v)
s= staffdef[person]+ "来月残り期間は振休なし";
sc3.AddHard(~sc3.Or(来月残振休リスト),s)
offset=0
allowable_errors=3
st="SeqSoftComp " +staffdef[person]
print(st,len(夜日リスト),len(振休リスト))
if include_next_month_day:#来月を含むなら最強ソフト
sc3.AddSoft(sc3.SoftSeqComp(offset,allowable_errors,振休リスト,夜日リスト),st,7)
else:#今月なら弱め
sc3.AddSoft(sc3.SoftSeqComp(offset,allowable_errors,振休リスト,夜日リスト),st,2)
def 週シフト継続(person, day):
if 平日週初日の予定があったらその週シフト継続==0:#マクロが0だったら何もしない
return
#print(staffdef[person],daydef[day])
if shift_schedules[person][day][0] !='':
シフト=shift_schedules[person][day][0]
tupple=shiftdef[シフト]
if tupple[3]=='':#業務開始時刻があるシフトをシフト継続マークとする
return
#print(tupple[3])
for i in range(5):#月曜から5日間見る
D=day+i
if D in 休日:#休日は見ない
continue
if shift_schedules[person][D][0] =='':#予定ブランクのときのみ制約する
v=sc3.GetShiftVar(person,D,シフト)
v |=sc3.GetShiftVar(person,D,'振休')
v |=sc3.GetShiftVar(person,D,'年休')
v |=sc3.GetShiftVar(person,D,'宅直')
v |=sc3.GetShiftVar(person,D,'夜勤明け')
s=staffdef[person]+daydef[D]+"シフト継続"
sc3.AddSoft(v,s,2)
def シフト週継続():
for person in 全スタッフ:
for week in [第一週,第二週,第三週,第四週,第五週]:
for day in week:
if day in 月 and day in 平日:
週シフト継続(person,day)
break
elif day in 火 and day in 平日:
週シフト継続(person,day)
break
elif day in 水 and day in 平日:
週シフト継続(person,day)
break
else:
print("programming error")
def shift_aggregate_analysis():
print("hi")
def post_main():
shift_aggregate_analysis()
if 制約開始日 !=6:
MessageBox = ctypes.windll.user32.MessageBoxW
res=MessageBox(HWND, '制約表示日は、制約開始日の6日前に設定してください。', '制約表示部エラー', 0x00000010)#error icon
exit(0)
予定以外の今月区間の来振休を禁止()
シフト週継続()
for person in 振休可能者:
for week in [第一週から第八週]:#
振休今月区間の日夜勤数は第1週から第8週までの振休数に等しい(person,week)