Excelに書き込めるようにはなりましたが、フォーマットもPythonで書き込みたいということで試行錯誤しながらトライ中です。
下図は、Pywin32でフォーマットしたExcelですが、書くのに2分位かかっていました。フォーマット自体は、そのインスタンスについて1回しか使用しないので、遅くてもよいのですが、データ書き込みも1分以上、かかってしまっており、改善の必要があります。
Pywin32を用いたExcel操作は、あまり例が見当たらないと思いますので、使ったソースはそのまま公開します。ScheduleNurse3に依存する処理はないので、操作例として利用可能と思います。以下は、現状でのフォーマットルーチンです。
難しいのは、土日に色を付けるところで、FormatConditionで記述しています。(恐らくは、仕様追加.追加..の産物なのでしょうが、VBAの言語仕様にたまげてしまいました。)
大抵は、VBAをそのままコンバート出来ますが、オブジェクト変数に落とす部分は、Pythonでは記述不能です。Unionで動的にオブジェクトを追加していくことは出来ないのは残念です。なので、VBAの究極の記述と比較すると、速度低下は避けられないと思います。
def make_initial_format(ws):
print(locale.getdefaultlocale()) dt = datetime.datetime(2018, 1, 1) print(dt) # 2018-01-01 00:00:00 print(dt.strftime('%A, %a, %B, %b')) # Monday, Mon, January, Jan set_font(ws,"D2","Work Schedule") set_font(ws,"AW2","") ws.Range("AW2").Formula='=Year(E7)' ws.Range("AW2","AX2").Merge() ws.Range("AW2").Font.Underline = xlUnderlineStyleSingle ws.Range("AW1","AX1").Merge() set_font(ws,"AW1",'Year') set_font(ws,"AZ2","2022")#dummy ws.Range("AZ2").Formula='=Month(E7)' ws.Range("AZ2").Font.Underline = xlUnderlineStyleSingle ws.Range("AZ2","BB2").Merge() set_font(ws,"AZ1",'Month') ws.Range("AZ1","BB1").Merge() row_start=8 row=row_start col_start=2 col=col_start day_col_offset=3 persons=len(staffdef) days=len(ThisMonth) phases=len(dayphase_list) cols=phases*days #Clear All ws.Range(ws.Cells(row_start,col_start+day_col_offset), ws.Cells(row_start+4*persons-1,col_start+day_col_offset+cols-1)).Value="" ws.Range(ws.Cells(row_start,col_start+day_col_offset), ws.Cells(row_start+4*persons-1,col_start+day_col_offset+cols-1)).Interior.Color=0xffffff ws.Columns(2).EntireColumn.ColumnWidth = 30 ws.Columns(3).EntireColumn.ColumnWidth = 10 ws.Columns(4).EntireColumn.ColumnWidth = 8 for name in staffdef: ws.Cells(row,col_start).Value=name merge_and_align(ws,row,col,row+3,col) ws.Cells(row,col+1).Value='Preferred' merge_and_align(ws,row,col+1,row+1,col+1) ws.Cells(row+2,col+1).Value='Sc3 Solution' merge_and_align(ws,row+2,col+1,row+3,col+1) ws.Cells(row,col+2).Value='Shift' merge_and_align(ws,row,col+2,row,col+2) ws.Cells(row+2,col+2).Value='Shift' merge_and_align(ws,row+2,col+2,row+2,col+2) ws.Cells(row+1,col+2).Value='Task' merge_and_align(ws,row+1,col+2,row+1,col+2) ws.Cells(row+3,col+2).Value='Task' merge_and_align(ws,row+3,col+2,row+3,col+2) row +=4 day_processed=0 row=row_start-2 #import pdb #pdb.set_trace() #print("set trace") pdb.set_trace() for day in ThisMonth: day_str=daydef[day] print(day_str,int(day_str[8:])) col=col_start+day_col_offset+day_processed for ph in range(phases): ws.Columns(col+ph).EntireColumn.ColumnWidth = 2 #ws.Cells(row,col).Value=int(day_str[8:]) ws.Cells(row,col).Formula='=Day(Date('+day_str[0:4]+','+day_str[5:7]+','+day_str[8:]+'))' day_color_format(ws,row,col,day_str) merge_and_align(ws,row ,col,row,col+phases-1) ws.Cells(row+1,col).Formula='=Date('+day_str[0:4]+','+day_str[5:7]+','+day_str[8:]+')' ws.Cells(row+1,col).NumberFormatLocal='aaa' day_color_format(ws,row+1,col,day_str) merge_and_align(ws,row+1,col,row+1,col+phases-1) day_processed +=phases row=row_start for person in All_Staff: day_processed=0 row =row_start+person*4 for day in ThisMonth: #print("row=",row,"row_start=",row_start) col=col_start+day_col_offset+day_processed merge_and_align(ws,row,col,row,col+phases-1) merge_and_align(ws,row+2,col,row+2,col+phases-1) day_processed +=phases ws.Range(ws.Cells(row,col_start), ws.Cells(row+3,col_start+day_col_offset+len(ThisMonth)*phases-1)).Borders.LineStyle = xlContinuous ws.Range(ws.Cells(row,col_start), ws.Cells(row+3,col_start+day_col_offset+len(ThisMonth)*phases-1)).Borders.weight=xlThin #Sub rountines def get_weekday(day_str): date=datetime.day(int(day_str[0:4]),int(day_str[5:7]),int(day_str[8:])) return date.weekday()#return integer Monday=0 def day_color_format(ws,row,col,day_str): ws.Cells(row,col).FormatConditions.Delete()#Add(xlCellValue, xlGreaterEqual, '=85') ws.Cells(row,col).FormatConditions.Add(xlExpression, xlEqual, '=Weekday(Date('+day_str[0:4]+','+day_str[5:7]+','+day_str[8:]+'))=7') #SAT:7 Sun:1 ws.Cells(row,col).FormatConditions.Add(xlExpression, xlEqual, '=Weekday(Date('+day_str[0:4]+','+day_str[5:7]+','+day_str[8:]+'))=1') #SAT:7 Sun:1 ws.Cells(row,col).FormatConditions(1).Interior.ColorIndex=20 #LightBlue ws.Cells(row,col).FormatConditions(2).Interior.ColorIndex=22 # def merge_and_align(ws,row_start1,col_start1,row_end1,col_end1,weight=xlThin): # if row_start<=0: print(row_start1,col_start1,row_end1,col_end1) # pdb.set_trace() ws.Range(ws.Cells(row_start1,col_start1), ws.Cells(row_end1,col_end1)).Merge() ws.Range(ws.Cells(row_start1,col_start1), ws.Cells(row_end1,col_end1)).VerticalAlignment = xlCenter ws.Range(ws.Cells(row_start1,col_start1), ws.Cells(row_end1,col_end1)).HorizontalAlignment = xlCenter ws.Range(ws.Cells(row_start1,col_start1), ws.Cells(row_end1,col_end1)).Borders.LineStyle = xlContinuous ws.Range(ws.Cells(row_start1,col_start1), ws.Cells(row_end1,col_end1)).Borders.Weight = weight
0 件のコメント:
コメントを投稿