2025年7月11日金曜日

Q.男性3人、女性3人配置したいため、列制約で制約タイプを最大―最小スタッフ数とし最大3最小3としたが4人以上配置されてしまう。

 Q.

下図のように女性が3人のところ”入り”に4人配置されてしまっているのは何故?


Ans.
プロジェクトおよび意図および現象の説明、ありがとうございます。


当該制約部分に移動します。
当該制約部分で集合をマウスホイールボタンを押して確認すると、”女性”集合にはなっておらず、別な集合名で記述されているようです。

スタッフプロパティシートを確認すると、次のようになっていました。

意図としては、女性集合で3名にしたいと思いますが、その部分集合で制約していることが分かります。

実際、解で確認すると、制約通りに動いていることが分かります。

従って、

■仕様:女性3人と

いう仕様に対して、制約は、 

■制約:生活介護 休日可女性 3人

になっています。他に”女性”で制約している記述が見当たりません。これが原因と思われます。


Note:

部分集合に対して制約して、全体集合で制約していないことによる問題は、よく遭遇します。(私もよくやらかしてしまいます。)

対策としては、

■スケジュールナースは制約通りに動く

■制約していないところはフリー(何が割り当てられるかは誰も分からない)

ということを常に頭に置くこと。

■制約をしている箇所で、マウスホイールボタンにより、集合(Day集合、グループ集合、シフト集合)をよく確認する。

ということに尽きるかと思います。


2025年7月10日木曜日

7月10日リリース機能その1

 1)スタッフ毎のシフトとタスクのスタッフ名チェックを廃止


Syncfusionの仕様なのか不明ですが、formulaを書くとExcel上では動いているのですが、それを再び読むと、formulaがそのまま表示されてしまい、どうにも動きません。例えば、

=スタッフ定義!B3 

というformulaを書くと、Excel上では動作しますが、それをスケジュールナースでインポートすると、Formulaの内容が表示されてしまって上手く行きませんでした。仕方なくスタッフ名チェックを外すことにしました。

スタッフ名は、もはや見ていないので、予定と同様何であっても問題なく読み込めるようになります。



<注意>

順番が暗黙に合っていることを想定しています。スタッフの順番を入れ替える場合は、スタッフ毎のシフトとタスクも同時にメンテナンスが必要となります。スケジュールナース上で入れ替えて、スタッフプロパティをExportする方法で行うようにすれば、気を使う必要はありません。

2025年7月9日水曜日

夜勤禁止・宅直禁止ラベルをシフト予定上で作るには

 タスク型勤務表において、夜勤や、宅直は、通常業務時間帯シフトとは独立に存在しえるので、タスクとなります。タスク予定は、シフト予定とは別画面となります。そうなると、タスクの禁止、例えば、夜勤禁止、宅直禁止といったラベルは、タスク予定上で操作することになり、ちょっと面倒です。

そこで、シフト予定画面上で、夜勤禁止や、宅直禁止といったラベルを作ることにします。このラベルを使うことによってシフト状態は指定できなくなってしまいますが、それでも実用的な場合があります。




2025年7月8日火曜日

経験年数5年以下の組み合わせを禁止

import sc3
import itertools
import math

def 夜勤ペア禁止(list0,list1):
    for day in 全日:
        if  day<制約開始日:
            continue
        or_list0=[]
        or_list1=[]
        #sc3.print(daydef[day]+"夜勤ペア禁止しました。")
        for person in list0:
            v1=sc3.GetShiftVar(person,day,'入り')#
            sc3.print(staffdef[person]+' ')
            or_list0.append(v1)
        sc3.print('\n')
        for person in list1:
            v1=sc3.GetShiftVar(person,day,'入り')#
            sc3.print(staffdef[person]+' ')
            or_list1.append(v1)
        v1=sc3.Or(or_list0)
        v2=sc3.Or(or_list1)
        sc3.AddSoft(~(v1&v2),"夜勤ペア禁止",5)

        or_list0.clear()
        or_list1.clear()
        
        for person in list0:
            v1=sc3.GetShiftVar(person,day,'明け')#
            or_list0.append(v1)
        for person in list1:
            v1=sc3.GetShiftVar(person,day,'明け')#
            or_list1.append(v1)
        v1=sc3.Or(or_list0)
        v2=sc3.Or(or_list1)
        sc3.AddSoft(~(v1&v2),"夜勤ペア禁止",5)

        sc3.print(daydef[day]+"夜勤ペア禁止しました。\n")
def 休日日勤ペア禁止(list0,list1):
    for day in 今月休診日:
        or_list0=[]
        or_list1=[]
        #sc3.print(daydef[day]+"夜勤ペア禁止しました。")
        for person in list0:
            v1=sc3.GetShiftVar(person,day,'日勤')#
            or_list0.append(v1)
        for person in list1:
            v1=sc3.GetShiftVar(person,day,'日勤')#
            or_list1.append(v1)
        v1=sc3.Or(or_list0)
        v2=sc3.Or(or_list1)
        sc3.AddSoft(~(v1&v2),"休日日勤ペア禁止",5)
        sc3.print(daydef[day]+"休日日勤ペア禁止しました。\n")

def 夜勤人数は最大1人(slist):
    for day in 全日:
        if  day<制約開始日:
            continue
        list0=[]
        for person in slist:
            v1=sc3.GetShiftVar(person,day,'入り')#
            list0.append(v1)
        sc3.AddSoft(sc3.SeqError(0,1,1,list0),"夜勤人数は最大1人",5)

def 休日日勤人数は最大1人(slist):
    for day in 今月休診日:
        list0=[]
        for person in slist:
            v1=sc3.GetShiftVar(person,day,'日勤')#
            list0.append(v1)
        sc3.AddSoft(sc3.SeqError(0,1,1,list0),"休日日勤人数は最大1人",5)

def 合計年数未満の組み合わせを禁止する(years):#Mar302020
    print(str(years)+"年数未満の組み合わせを禁止します。")
    s=set() #set
    for person in 経験年数属性.keys():
        経験年数=経験年数属性[person]
        s.add(経験年数)
    for 経験年数 in s:
        if 経験年数 * 2 < years:#Mar302020 Self組み合わせ の総数和<=1に制約する
            slist=[]
            for person in 経験年数属性.keys():
                if 経験年数 == 経験年数属性[person]:
                    slist.append(person)
            夜勤人数は最大1人(slist)
            休日日勤人数は最大1人(slist)
                
    for v in itertools.combinations(s,2):
        if v[0]+v[1]=0:
            連休.append(D)
            D -=1
    #後方を探索する
    D=day+1
    while D<=制約終了日 and D in 休日:
        連休.append(D)
        D +=1
    #print(連休)
    連休.sort()
    print("連休",連休)
    return 連休#ソートした連休を返す


合計年数未満の組み合わせを禁止する(合計年数最小値) #Jul072025 マクロ引数に変更



経験年数をスタッフプロパティで設定し、Pythonでそれらを読み取り、指定合計年数最小値未満の全ての組み合わせを禁止しています。








合算年数の指定は、マクロにして、Pythonコードをいじらなくても良いようにしています。

ログ例です。Debug出力も兼ねています。
コンパイルの準備中
ソルバを呼び出し中です。
	制約をコンパイル中です。
	Python プロパティファイルの生成が終わりました。
5年数未満の組み合わせを禁止します。
経験年数1年2年
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-01夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-02夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-03夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-04夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-05夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-06夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-07夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-08夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-09夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-10夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-11夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-12夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-13夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-14夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-15夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-16夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-17夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-18夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-19夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-20夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-21夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-22夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-23夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-24夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-25夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-26夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-27夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-28夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-29夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ10 スタッフ19 スタッフ29 スタッフ41 スタッフ44 スタッフ52 2025-06-30夜勤ペア禁止しました。
2025-06-01休日日勤ペア禁止しました。
2025-06-07休日日勤ペア禁止しました。
2025-06-08休日日勤ペア禁止しました。
2025-06-14休日日勤ペア禁止しました。
2025-06-15休日日勤ペア禁止しました。
2025-06-21休日日勤ペア禁止しました。
2025-06-22休日日勤ペア禁止しました。
2025-06-28休日日勤ペア禁止しました。
2025-06-29休日日勤ペア禁止しました。
経験年数1年3年
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-01夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-02夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-03夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-04夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-05夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-06夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-07夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-08夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-09夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-10夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-11夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-12夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-13夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-14夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-15夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-16夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-17夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-18夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-19夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-20夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-21夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-22夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-23夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-24夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-25夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-26夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-27夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-28夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-29夜勤ペア禁止しました。
スタッフ11 スタッフ20 スタッフ21 スタッフ30 スタッフ42 スタッフ61 スタッフ62 
スタッフ39 スタッフ40 スタッフ51 スタッフ60 2025-06-30夜勤ペア禁止しました。
2025-06-01休日日勤ペア禁止しました。
2025-06-07休日日勤ペア禁止しました。
2025-06-08休日日勤ペア禁止しました。
2025-06-14休日日勤ペア禁止しました。
2025-06-15休日日勤ペア禁止しました。
2025-06-21休日日勤ペア禁止しました。
2025-06-22休日日勤ペア禁止しました。
2025-06-28休日日勤ペア禁止しました。
2025-06-29休日日勤ペア禁止しました。

2025年7月5日土曜日

通常、休みシフトは土日祝のみだが、今月診療日に予定で休みが入力されることもある

 これをGUIでやろうとすると、

■今月診療日に、休みシフトをソフト制約で禁止にする

ことが一般的ですが、予定として入力された休みシフトがソフトエラーとなってしまうのが気に食わない、方もいらっしゃるかもしれません。

その場合は、Pythonで記述します。予定で何か入力された以外は、今月診療日の休みシフトを禁止にします。10行足らずで済みます。


def 土日祝休みは今月診療日予定がなければ不可():
    for day in 今月診療日:
        for person in 全スタッフ:
            if shift_schedules[person][day][0]=="":
                v=sc3.GetShiftVar(person,day,'土日祝休み')
                s="予定なしなら、平日診療日土日休み不可 "+staffdef[person]
                sc3.AddHard(~v,s)

土日祝休みは今月診療日予定がなければ不可()