ソルバのPythonソース出力追加を行いました。デバッグ用としてお医者さまプロジェクトを使用しました。このプロジェクトは、シフト解とタスク解、両方とも有意な値を持ち、なおかつ、シフト・タスク予定が詰まっていて検証用として最適です。(Covid-19支援プロジェクト)
最初は、従来のCSV出力例です。シフト・タスク出力を唯一つのファイルに出力したものですが、日付等もないので、もう一段整形が必要であること分かります。
次は、今回の出力です。予定ラベルを追加した他、出力をラベル出力として、色を定義のものに合わせています。なおかつ、見易くするために夜勤に纏わる部分だけの出力に整形しています。
そして、お客さまフォーマットに合わせて、解を出力しています。例えば、スタッフの順序を入れ替れたり、空白行があっても、問題なく出力されます。つまりそのまま最終出力としても良い形に(ご自分で)整形が可能になった、ということです。
以下は、今回のpythonソースです。予定シフト、予定タスク、解シフト、解タスクをラベルで出力しています。
<Scan Objects>
面倒なのは、ラベル色の処理で、該当するラベルは、以下を検索して一致するものを出力する必要があります。
予定タスク
task→task_aggregate
予定シフト
shift→shift_aggregate→phase_variables→phase_variable_aggregate
をScanする必要があります。
<Alias Labelの処理>
また、予定シフトがAliasで記述されていた場合、例えば、今回”業務”は、”業務AM”、"業務PM”をAliasとして持ちます。予定がそういう風に記述されていたら、解ラベルもそれに応じて、同じラベルで出力するのが親切でしょう。
def post_main(): sc3.hook_stdout()#printをリダイレクトする print('\n\n*********ポスト処理を実行中です。*************\n') import win32com.client#pywin32をインポート #すでにExcelが起動されている場合はそのタスクが使われる #エラー終了するとタスクは残ります try : xl = win32com.client.Dispatch("Excel.Application") except: print("can not invoke excel") exit() #動いている様子を見てみる xl.Visible = True os.chdir(project_file_path) file=os.path.join(project_file_path,"excel_post_export.xlsx") file.replace("/","\\") #なぜか逆スラッシュでないと動かない wb = xl.Workbooks.Open(file) # Excelシートオブジェクト ws = wb.Worksheets(1) # 指定したシートを選択 # Select()の使用前にシートのActivate()が必要 ws.Activate() #print(task_label_color_map['日直'][0]) #return for person in 全スタッフ: staff_name=staffdef[person] c=ws.Range("B1:B51").Find(staff_name) #print(c.Row,c.Column) for day in 今月: col=day-制約開始日 #print(day) tph=col*2 shift_label=shift_schedules[person][day][2] ws.Cells(c.Row,c.Column+3+col*2).Value=shift_label#シフト予定 shift=shift_schedules[person][day][0] shift_color=get_shift_label_color(shift_label) ws.Cells(c.Row,c.Column+3+col*2).Interior.Color=shift_color#シフト予定色 t02=task_schedules[person][day*2][2]#label t0_color=get_task_label_color(t02) t00=task_schedules[person][day*2][0] t12=task_schedules[person][day*2+1][2]#label t1_color=get_task_label_color(t12) t10=task_schedules[person][day*2+1][0] ws.Cells(c.Row+1,c.Column+3+tph).Value=t02#タスク予定 ws.Cells(c.Row+1,c.Column+3+tph).Interior.Color=t0_color ws.Cells(c.Row+1,c.COlumn+3+tph+1).Value=t12#タスク予定 ws.Cells(c.Row+1,c.Column+3+tph+1).Interior.Color=t1_color shift=shift_solution[person][day] if shift=='業務なし日勤': ws.Cells(c.Row+2,c.Column+3+col*2).Value='' #empty ws.Cells(c.Row+2,c.Column+3+col*2).Interior.Color=0xffffff else: label_color=get_shift_label(shift,shift_label)#return (label,color_str) ws.Cells(c.Row+2,c.Column+3+col*2).Value=label_color[0] ws.Cells(c.Row+2,c.Column+3+col*2).Interior.Color=rgb_str_to_hex(label_color[1]) task0=task_solution[person][day*2] task1=task_solution[person][day*2+1] t0_color=get_task_color(task0) t1_color=get_task_color(task1) ws.Cells(c.Row+3,c.Column+3+tph).Interior.Color=t0_color ws.Cells(c.Row+3,c.Column+3+tph+1).Interior.Color=t1_color if task0=='' or task0=='DummyDay': ws.Cells(c.Row+3,c.Column+3+tph).Value='' else: task_label=get_task_label(task0) ws.Cells(c.Row+3,c.Column+3+tph).Value=task_label if task1=='' or task1=='Dummy': ws.Cells(c.Row+3,c.Column+3+tph+1).Value='' else: task_label=get_task_label(task1) ws.Cells(c.Row+3,c.Column+3+tph+1).Value=task_label wb.Close(True)# Trueで保存。False=Defaultでブックを保存せずにクローズ # Excel終了 xl.Quit() print('\n\n*********ポスト処理を実行終了しました。*************\n') def get_shift_label(shift,scheduled_shift_label): for key in shift_label_color_map.keys(): if key ==shift: item_array=shift_label_color_map[key] i=0 for item in item_array: if i==0: solution_shift_label=item[0] solution_label_color=item[1] else: if len(scheduled_shift_label)>=1 and item[0]==scheduled_shift_label: return item[0],item[1] i+=1 return solution_shift_label,solution_label_color print("Fatal Error",shift,scheduled_shift_label) exit() def get_task_label(task): if task in task_label_color_map: return task_label_color_map[task][0][0] else: print("Invalid Task", task) exit() def rgb_to_hex(rgb): ''' ws.Cells(1, i).Interior.color uses bgr in hex ''' bgr = (int(rgb[2]),int(rgb[1]),int(rgb[0])) strValue = '%02x%02x%02x' % bgr # print(strValue) iValue = int(strValue, 16) return iValue def get_task_label_color(task_label): if len(task_label)==0 or task_label=='.': return 0xffffff #空白,Dummy DummyDay for item_array in task_label_color_map.values():#task集合から探して for item in item_array:#taskは複数のラベルを持つ task_label_candidate=item[0] if task_label==task_label_candidate:#ラベル名が一致したなら color_str=item[1] rgb = re.findall(r"\d+",color_str) if len(rgb)==3: return rgb_to_hex(rgb) else: return 0xffffff #rgb形式でなければWhiteを返す for item in task_collections_def.values():#無かったらtask aggregatesから探す task_label_candidate=item[0] #if len(task_label)>=1: # print("list",task_label,task_label_candidate) if task_label==task_label_candidate: #print("matched",task_label_candidate) color_str=item[1] rgb = re.findall(r"\d+",color_str) if len(rgb)==3: return rgb_to_hex(rgb) else: return 0xffffff #rgb形式でなければWhiteを返す #print("unmatched",task_label) return 0xffffff #なければWhiteを返す def get_shift_label_color(shift_label): if len(shift_label)==0 or shift_label=='・': return 0xffffff #空白ならWhiteを返す for item_array in shift_label_color_map.values():#task集合から探して for item in item_array:#taskは複数のラベルを持つ shift_label_candidate=item[0] #print(shift_label,shift_label_candidate) if shift_label==shift_label_candidate:#ラベル名が一致したなら color_str=item[1] rgb = re.findall(r"\d+",color_str) if len(rgb)==3: return rgb_to_hex(rgb) else: return 0xffffff #rgb形式でなければWhiteを返す for item in shift_collections_def.values():#無かったらtask aggregatesから探す shift_label_candidate=item[0] #if len(task_label)>=1: # print("list",task_label,task_label_candidate) if shift_label==shift_label_candidate: #print("matched",task_label_candidate) color_str=item[1] rgb = re.findall(r"\d+",color_str) if len(rgb)==3: return rgb_to_hex(rgb) else: return 0xffffff #rgb形式でなければWhiteを返す for item in phase_objects_def.values(): shift_label_candidate=item[0] if shift_label==shift_label_candidate: color_str=item[1] rgb = re.findall(r"\d+",color_str) if len(rgb)==3: return rgb_to_hex(rgb) else: return 0xffffff #rgb形式でなければWhiteを返す for item in phase_aggregate_object_def.values(): shift_label_candidate=item[0] if shift_label==shift_label_candidate: color_str=item[1] rgb = re.findall(r"\d+",color_str) if len(rgb)==3: return rgb_to_hex(rgb) else: return 0xffffff #print("unmatched",task_label) return 0xffffff #なければWhiteを返す def get_task_color(task): if len(task)==0 or task=='Dummy' or task=='DummyDay': return 0xffffff if task in task_label_color_map: color_str=task_label_color_map[task][0][1] rgb = re.findall(r"\d+",color_str) if len(rgb)==3: return rgb_to_hex(rgb) else: return 255 + 255*256 + 255*256*256 else: return 255 + 255*256 + 255*256*256 def rgb_str_to_hex(color_str): rgb = re.findall(r"\d+",color_str) if len(rgb)==3: return rgb_to_hex(rgb) else: return 0xffffff
0 件のコメント:
コメントを投稿