2024年5月30日木曜日

Excelユーザ特殊フォーマットで解出力

 適当なテンプレートを探します。

今回は、以下のExcelブックを有難く使わせていただきます。ありがとうございます。


エクセルカレンダーテンプレート | アラクネ (arachne.jp)

ユーザフォーマットとしては、3行に渡るものが必要でした。上記フォーマットは、最大6行まで可能です。


これに、短時間宿直もあるので、出来れば4行以上のものが必要でした。

まずは、単独でExcelファイルを操作するものを作ります。プロジェクト設定は以下です。

<python ポスト処理設定>



<シート名の作成>
「2024年6月」のような名前になっているので、プロジェクト処理月に応じてシート名を作成する必要があります。年月日情報は、ソース全体の最初の方、daydefでリストとして作成されています。制約開始日でインデックスすると、当該年月日がフォーマット文字列として取り出すことが出来ます。


<ポスト処理>
def post_mainがポスト処理のメインになります。

python ソースは以下です。以下を参考にしました。このテンプレートでは、Dayが数値として定義されていません。検索がうまく動かないので、日曜日基準のカレンダを内部で持って、それをExcelシートフォーマットに展開する方法を取りました。このプロジェクトは、クリアするだけの機能しかありませんが、後々これを基に解を出力していきます。




import sc3
import sys
import os
import csv
import re
import win32gui, win32con
import datetime
import calendar


def get_sheet_name():
    s=daydef[制約開始日]

    year_str=s[0:4]
    month=int(s[5:7])
    sheet_name=year_str+'年'+str(month)+'月'
    return sheet_name

def get_year():
    s=daydef[制約開始日]
    year_str=s[0:4]
    return int(year_str)

def get_month():
    s=daydef[制約開始日]
    month=int(s[5:7])
    return month

def get_day():
    s=daydef[制約開始日]
    day=int(s[8:10])
    return day


def find_address(moncal,D):
    row=0
    for r in moncal:
        if D not in r:
            row+=1
            continue
        return (row,r.index(D))
    raise IndexError

def init_row_columns():
    global start_row
    global start_column
    global row_interval
    global column_interval

    start_row=5
    start_column=2
    row_interval=6
    column_interval=2

def findcell(ws,moncal,D):
    tuple=find_address(moncal,D)
    init_row_columns()
    row=start_row+row_interval*tuple[0]
    column=start_column+column_interval*tuple[1]
    return (row,column)

def clear_cells(ws):
    init_row_columns()
    for r in range(6):
        for d in range(7):
            row=start_row+r*row_interval
            column=start_column+d*column_interval
            print(row,column)
            ws.Cells(row  ,column+1).Value=""
            ws.Cells(row+1,column+1).Value=""
            ws.Cells(row+2,column+1).Value=""
            ws.Cells(row+3,column).Value=""
            ws.Cells(row+4,column).Value=""
            ws.Cells(row+5,column).Value=""


def post_main():
    
    print('\n\n*********ポスト処理を実行中です。*************\n')
    import win32com.client#pywin32をインポート

#すでにExcelが起動されている場合はそのタスクが使われる
#エラー終了するとタスクは残ります
    try :
        excel = win32com.client.Dispatch("Excel.Application")
    except:
        print("can not invoke excel")
        exit()
    #動いている様子を見てみる
    excel.Visible = True
    os.chdir(project_file_path)
    filename="2024勤務表.xlsx"
    file=os.path.join(project_file_path,filename)
    file.replace("/","\\") 
    sheet_name=get_sheet_name()
    try:
        wb = excel.Workbooks.Open(file)
        # Excelシートオブジェクト
        ws = wb.Worksheets(sheet_name)
    except:
        print("Can not open the excel file.")
        wb.Close()
        excel.Quit()
    

    
    # 指定したシートを選択
    # Select()の使用前にシートのActivate()が必要
    ws.Activate()
    
    calendar.setfirstweekday(6)#日曜日を最初に
    mon_cal=calendar.monthcalendar(get_year(),get_month())#行列でリスト

    print(findcell(ws,mon_cal,1))

    clear_cells(ws)

    wb.Close(True)# Trueで保存。False=Defaultでブックを保存せずにクローズ
    # Excel終了
    excel.Quit()
    print('\n\n*********ポスト処理を実行終了しました。*************\n')
             

0 件のコメント:

コメントを投稿