このプロジェクトでは、制約開始日前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)
0 件のコメント:
コメントを投稿