2025年4月26日土曜日

制約開始日設定が間違っていたらエラーを出して終了

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

コメントを投稿