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)