燃調費の登録 TODO

投稿者: | 2023-03-16

import collections
import pandas as pd
import pathlib
import pyautogui as pag
import pyperclip
import PySimpleGUI as sg
import sys
import time
import cv2

pag.PAUSE = 2.5
pag.FAILSAFE = True

# 燃調ファイル(低圧)をサマリー版より、辞書を作成
def make_LV_nencho_dic(LV_xlsx):
    p = pathlib.Path(LV_xlsx)
    df = pd.read_excel(p, dtype={"燃料費調整コード":"str", "適用開始年月": "str", "階層":"str"})
    df["code_add_level"] = df["燃料費調整コード"] + "_" + df["階層"]
    df = df.set_index("code_add_level")
    # 燃調費抽出用の辞書を作成
    code_dic = df.to_dict(orient='index')
    return code_dic

# 続けるか?(OK or Cancel)
def is_continue():
    is_ok = sg.popup_ok_cancel("続けますか?", keep_on_top=True)
    if is_ok == 'Cancel':
        sys.exit()
    

# 最低料金制か?(Boolean)
def is_saitei_ryokinsei(code):
    # 各コードの数をカウントする 例:Counter({'0101': 1, '0201': 1, '0301': 2, '0401': 1, '0501': 2, '0601': 2})
    counter_dic = collections.Counter(code_list)
    normal_list = [k for k, v in counter_dic.items() if v == 1]
    saitei_list = [k for k, v in counter_dic.items() if v > 1]
    if code in normal_list:
        return False
    if code in saitei_list:
        return True
    else:
        sg.popup("処理中断:見知らぬcode")
        sys.exit()
        

# 何もせずにEnterで次へ
def nothing_and_next(s):
    # 本番用↓
    time.sleep(1)
    sg.popup(f"{s}:Enter > Next")
    # pag.hotkey('enter')
    time.sleep(1)
    

def input_via_clip(chrs):
    time.sleep(1)
    sg.popup(f'Paste:{chrs} -> Enter > Next')
    # pyperclip.copy(chrs)
    # pag.hotkey('ctrl', 'v')
    # pag.hotkey('enter')
    time.sleep(1)
    
# ずれ防止のため「登録」用ボタンを画像認証で確認
def search_btn_and_click(btn_path):
    while True:
        btn = pag.locateCenterOnScreen(btn_path)
        if btn is not None:
            print('ボタン検索中')
            time.sleep(1)
            pag.click(btn)
            break
        elif sg.popup_yes_no(f'ボタンが見つかりません\n続けますか?') == 'Yes':
            continue
        else:
            print('処理を中断します')
            sys.exit()
    
      
def regi_case_normal(code):
        # 1段目のみ
        sg.popup(f"今から {code} を登録する")
        code_index = code + "_1"
        unit_price = code_dic[code_index]['単価']
        
        nothing_and_next("登録画面へ入る") # 登録画面へ入る
        
        nothing_and_next("1.下限値(不要)") # 1.下限値(不要)、Enter
        nothing_and_next("2.上限値(不要)") # 2.上限値(不要)、Enter
        input_via_clip(unit_price) # 3.単価(値あり)、Enter
        nothing_and_next("4.定額(不要)") # 4.定額(不要)、Enter
        
        # 5.実行、Enter → 下段画面に戻る?
        # search_btn_and_click(btn1_path?) 
        # search_btn_and_click(btn2_path?)
        nothing_and_next("登録 > 下段画面へ")
        
# 画像認証したボタンをクリック
    
def regi_case_saitei(code):
    
        sg.popup(f"今から {code} の1段目を登録する")
    
        # 1段目
        code_index = code + "_1"
        upper_value = code_dic[code_index]['上限値']
        fix_value = code_dic[code_index]['定額']
        
        nothing_and_next("登録画面へ入る") # 登録画面へ入る
        
        nothing_and_next("1.下限値(不要)") # 1.下限値(不要)、Enter
        input_via_clip(upper_value) # 2.上限値(値あり)、Enter
        nothing_and_next("3.単価(不要)") # 3.単価(不要)、Enter
        input_via_clip(fix_value) # 4.定額(不要)、Enter
        
        # 5.実行、Enter → 下段画面に戻る?
        # search_btn_and_click(btn1_path?) 
        # search_btn_and_click(btn2_path?)
        nothing_and_next("登録 > 下段画面に戻る")
        
        # 確認(ここは消すな)
        is_continue()
        
        sg.popup(f"今から {code} の2段目を登録する")
    
        # 2段目
        code_index = code + "_2"
        unit_price = code_dic[code_index]['単価']
        
        nothing_and_next("登録画面へ入る") # 登録画面へ入る
        
        nothing_and_next("1.下限値(不要)") # 1.下限値(不要)、Enter
        nothing_and_next("2.上限値(不要)") # 2.上限値(不要)、Enter
        input_via_clip(unit_price) # 3.単価(値あり)、Enter
        nothing_and_next("4.定額(不要)") # 4.定額(不要)、Enter
        
        # 5.実行、Enter → 下段画面に戻る?
        # search_btn_and_click(btn1_path?) 
        # search_btn_and_click(btn2_path?)
        nothing_and_next("登録 > 下段画面に戻る")
        

# 下段の入力
def register_lower_area(code):
    if code in saitei_ryokinsei_code:
        sg.popup(f"{code}:最低料金制で登録")
        regi_case_saitei(code)
    else:
        sg.popup(f"{code}:Normalで登録")
        regi_case_normal(code)
        
        
# 上段の入力
def register_upper_area(code):
    code_index = code + "_1"
    # 燃調費コード/YYMM/摘要
    code = code
    yymm = (code_dic[code_index]['適用開始年月'])[2:]
    abstract = code_dic[code_index]['摘要']
    
    # 燃調費コード
    input_via_clip(code)
    # YYMM
    input_via_clip(yymm)
    # 摘要
    input_via_clip(abstract)
    time.sleep(1)

# メインプログラム
if __name__ == '__main__':
    
    # p = r"C:\Users\yoshi\Desktop\nencho_tonyu\LV_nencho.xlsx"
    p = sg.popup_get_file("低圧・燃調ファイル(まとめ版)を選択してくだささい(xlsx形式)", title="ファイルの選択", initial_folder="")
    
    # 入力コードを指定
    code_list = ["0101", "0201", "0301", "0301", "0401", "0501", "0501", "0601", "0601"]
    
    code_dic = make_LV_nencho_dic(p)
    
    saitei_ryokinsei_code = [k for k, v in collections.Counter(code_list).items() if v > 1]
    
    for code in sorted(set(code_list)):
        sg.popup(f'燃調費コード:{code} の入力を開始') 
        register_upper_area(code)
        register_lower_area(code)
    sg.popup("終了しました")

以下は、リストから選択したい場合 TODO

  • 以下は上のやり方が問題なければ、次のステップとしてやること
  • 上のdef make_LV_nencho_dic(LV_xlsx) を変える必要がある←引数がXLSXファイルになっているため。
チェックボックスで選択する
戻り値は、チェックONのコードの「リスト」
import collections
import pandas as pd
import pathlib
import pyautogui as pag
import PySimpleGUI as sg
import sys

# 登録したいコードをExcelから取得
def get_code_list(path):
    df = pd.read_excel(p, dtype={"燃料費調整コード":"str", "適用開始年月": "str", "階層":"str"})
    code_list = df['燃料費調整コード'].unique().tolist()
    return code_list


# Excelからのコードからさらに選択する(途中から登録する場合など)
def select_code_list(code_list):
    layout = []
    cb_list = []
    for code in code_list:
        cb_list.append([sg.Checkbox(f'{code}', k=f'{code}', enable_events=True, default=True)]) # キーにハイフンなしにする

    layout.append([sg.T("登録する燃調コードを選択してください。")])
    layout.append(cb_list)
    layout.append([sg.B('Ok'), sg.B('Cancel')])

    window = sg.Window("チェックボックス",layout)

    # チェック後のcodeを格納(チェックイベントがない場合=全登録、ここにないと??
    updated_code_list = []

    while True:
        event, values = window.read()
        print(event, values)
        if event in (sg.WIN_CLOSED, 'Cancel'):
            break
        # チェックイベントがあるとcode_list全体のON-OFFを調べる
        if event in code_list:
            # チェックの度にリストは初期化
            updated_code_list = []
            for code in code_list:
                is_checked = window[code].get()
                if is_checked:
                    updated_code_list.append(code)
        if event == 'Ok':
            if updated_code_list:
                window.close()
                return updated_code_list
            else:
                window.close()
                return code_list

p = r"C:\Users\~\Desktop\nencho_tonyu\LV_nencho.xlsx"
code_list = get_code_list(p)
code_list = select_code_list(code_list)