From e20ea263d814c6a88c686b1b13b9032949f68de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=85=E6=AD=A3=E4=B8=AD?= Date: Mon, 13 Jan 2025 20:50:06 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=95=B4=E7=A8=8B=E5=BC=8F=E7=A2=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...50\351\237\263\346\252\224\346\241\210.py" | 5 - ...42\345\255\227\346\263\250\351\237\263.py" | 110 --------- ...27\350\243\234\346\263\250\351\237\263.py" | 96 -------- ...50\351\237\263\347\266\262\351\240\201.py" | 105 --------- ...51\237\263\347\266\262\351\240\201_bak.py" | 100 -------- ...\237\273\346\223\254\351\237\263_Excel.py" | 103 -------- ...237\273\346\223\254\351\237\263_SQLite.py" | 102 -------- ...42\345\255\227\346\250\231\351\237\263.py" | 145 +++++++++--- ...345\255\227\346\250\231\351\237\263_R1.py" | 176 -------------- ...42\345\255\227\346\250\231\351\237\263.py" | 84 ++++--- ...63\347\224\250\346\226\271\346\240\274.py" | 86 ------- ...50\351\237\263\345\241\253\345\205\245.py" | 91 -------- fun_ha_ji_tsa_un_bu.py | 40 ---- fun_siong_ji_tsa_siann_bu.py | 35 --- mod_excel_access.py | 20 +- ...\221\343\200\212TestCase\343\200\213.xlsx" | Bin 42383 -> 41071 bytes process_log.txt | 221 ++++++++++++++++++ 17 files changed, 403 insertions(+), 1116 deletions(-) delete mode 100644 "a000_\345\273\272\347\253\213\346\263\250\351\237\263\346\252\224\346\241\210.py" delete mode 100644 "a100_\344\272\210\346\210\221\346\274\242\345\255\227\346\263\250\351\237\263.py" delete mode 100644 "a200_\346\274\242\345\255\227\350\243\234\346\263\250\351\237\263.py" delete mode 100644 "a520_\350\243\275\344\275\234\346\263\250\351\237\263\347\266\262\351\240\201.py" delete mode 100644 "a520_\350\243\275\344\275\234\346\263\250\351\237\263\347\266\262\351\240\201_bak.py" delete mode 100644 "a600_\346\274\242\345\255\227\346\237\245\345\273\243\351\237\273\346\223\254\351\237\263_Excel.py" delete mode 100644 "a600_\346\274\242\345\255\227\346\237\245\345\273\243\351\237\273\346\223\254\351\237\263_SQLite.py" delete mode 100644 "a702_\346\237\245\346\211\276\345\217\212\345\241\253\345\205\245\346\274\242\345\255\227\346\250\231\351\237\263_R1.py" delete mode 100644 "bu-a720_\345\276\205\346\263\250\351\237\263\346\274\242\345\255\227\345\241\253\345\205\245\346\250\231\351\237\263\347\224\250\346\226\271\346\240\274.py" delete mode 100644 "bu-a730_\345\260\207\346\274\242\345\255\227\346\263\250\351\237\263\345\241\253\345\205\245.py" delete mode 100644 fun_ha_ji_tsa_un_bu.py delete mode 100644 fun_siong_ji_tsa_siann_bu.py diff --git "a/a000_\345\273\272\347\253\213\346\263\250\351\237\263\346\252\224\346\241\210.py" "b/a000_\345\273\272\347\253\213\346\263\250\351\237\263\346\252\224\346\241\210.py" deleted file mode 100644 index a6f4a56..0000000 --- "a/a000_\345\273\272\347\253\213\346\263\250\351\237\263\346\252\224\346\241\210.py" +++ /dev/null @@ -1,5 +0,0 @@ -# 產生注音檔:Piau-Tsu-Im.xlsx -from p000_san_sing_tsu_im_tong import main as san_sin_tsu_im_tong - -# 「產生注音檔」開始作業 -san_sin_tsu_im_tong() diff --git "a/a100_\344\272\210\346\210\221\346\274\242\345\255\227\346\263\250\351\237\263.py" "b/a100_\344\272\210\346\210\221\346\274\242\345\255\227\346\263\250\351\237\263.py" deleted file mode 100644 index b73dee4..0000000 --- "a/a100_\344\272\210\346\210\221\346\274\242\345\255\227\346\263\250\351\237\263.py" +++ /dev/null @@ -1,110 +0,0 @@ -import getopt -import sys -import os - -import xlwings as xw - -import settings -from p000_import_source_data import main_run as san_sing_han_ji_tsu_im_paiau -# from p100_tsa_ji_tian import main_run as tsa_ji_tian_tshue_tsu_im -# from p200_hoo_gua_tsu_im import main_run as hoo_gua_tsu_im -from p100_tsa_nga_siok_thong_ji_tian import main_run as tsa_ji_tian_tshue_tsu_im -from p200_Iong_Nga_Siok_Thong_Zu_Im import main_run as hoo_gua_tsu_im - - -def myfunc(argv): - arg_input = "" - arg_output = "" - arg_user = "" - arg_help = "{0} -i -u -o ".format(argv[0]) - - try: - opts, args = getopt.getopt( # pyright: ignore - argv[1:], "hi:u:o:", ["help", "input=", "user=", "output="] - ) - except Exception as e: - print(e) - print(arg_help) - sys.exit(2) - - for opt, arg in opts: - if opt in ("-h", "--help"): - print(arg_help) # print the help message - sys.exit(2) - elif opt in ("-i", "--input"): - arg_input = arg - elif opt in ("-u", "--user"): - arg_user = arg - elif opt in ("-o", "--output"): - arg_output = arg - - print("input:", arg_input) - print("user:", arg_user) - print("output:", arg_output) - - return { - "input": arg_input, - "user": arg_user, - "output": arg_output, - } - - -if __name__ == "__main__": - # ========================================================================= - # (1) 取得需要注音的「檔案名稱」及其「目錄路徑」。 - # ========================================================================= - # 取得 Input 檔案名稱 - file_path = settings.get_input_file_path() - if not file_path: - print("未設定 .env 檔案") - # sys.exit(2) - opts = myfunc(sys.argv) - if opts["input"] != "": - CONVERT_FILE_NAME = opts["input"] - else: - CONVERT_FILE_NAME = "Piau-Tsu-Im" - else: - CONVERT_FILE_NAME = file_path - print(f"CONVERT_FILE_NAME = {CONVERT_FILE_NAME}") - - # ========================================================================= - # (2) 將存放在「工作表1」的「漢字」文章,製成「漢字注音表」以便填入注音。 - # ========================================================================= - san_sing_han_ji_tsu_im_paiau(CONVERT_FILE_NAME) - - # ========================================================================= - # (3) 在字典查注音,填入漢字注音表。 - # ========================================================================= - tsa_ji_tian_tshue_tsu_im(CONVERT_FILE_NAME) - - # ========================================================================= - # (4) 將已注音之「漢字注音表」,製作成 HTML 格式之「注音/拼音/標音」網頁。 - # ========================================================================= - hoo_gua_tsu_im(CONVERT_FILE_NAME) - - # ========================================================== - # 檢查「缺字表」狀態 - # ========================================================== - # 指定來源工作表 - source_sheet = xw.Book(CONVERT_FILE_NAME).sheets["缺字表"] - # 取得工作表內總列數 - end_row_no = ( - source_sheet.range("A" + str(source_sheet.cells.last_cell.row)).end("up").row - ) - if end_row_no > 1: - print(f"總計字典查不到注音的漢字共:{end_row_no}個。") - - # ========================================================================= - # (5) 依據《文章標題》另存新檔。 - # ========================================================================= - wb = xw.Book(CONVERT_FILE_NAME) - setting_sheet = wb.sheets["env"] - new_file_name = str( - setting_sheet.range("C4").value - ).strip() - new_file_path = os.path.join( - ".\\output", - f"【河洛話注音】{new_file_name}" + ".xlsx") - - # 儲存新建立的工作簿 - wb.save(new_file_path) diff --git "a/a200_\346\274\242\345\255\227\350\243\234\346\263\250\351\237\263.py" "b/a200_\346\274\242\345\255\227\350\243\234\346\263\250\351\237\263.py" deleted file mode 100644 index ae547c3..0000000 --- "a/a200_\346\274\242\345\255\227\350\243\234\346\263\250\351\237\263.py" +++ /dev/null @@ -1,96 +0,0 @@ -import getopt -import os -import sys -import xlwings as xw - -from dotenv import dotenv_values - -from p110_khuat_ji_poo_tsu_im import main_run as poo_tsu_im -from p200_hoo_gua_tsu_im import main_run as hoo_gua_tsu_im - -def myfunc(argv): - arg_input = "" - arg_output = "" - arg_user = "" - arg_help = "{0} -i -u -o ".format(argv[0]) - - try: - opts, args = getopt.getopt( - argv[1:], "hi:u:o:", ["help", "input=", "user=", "output="] - ) - except getopt.GetoptError: - print(arg_help) - sys.exit(2) - - for opt, arg in opts: - if opt in ("-h", "--help"): - print(arg_help) # print the help message - sys.exit(2) - elif opt in ("-i", "--input"): - arg_input = arg - elif opt in ("-u", "--user"): - arg_user = arg - elif opt in ("-o", "--output"): - arg_output = arg - - print("input:", arg_input) - print("user:", arg_user) - print("output:", arg_output) - - return { - "input": arg_input, - "user": arg_user, - "output": arg_output, - } - - -if __name__ == "__main__": - # 取得 Input 檔案名稱 - config = dotenv_values(".env") - dir_path = str(config["INPUT_FILE_PATH"]) - file_name = str(config["FILE_NAME"]) - file_path = os.path.join(dir_path, file_name) - if not file_path: - print("未設定 config.env 檔案") - # sys.exit(2) - opts = myfunc(sys.argv) - if opts["input"] != "": - CONVERT_FILE_NAME = opts["input"] - else: - CONVERT_FILE_NAME = "Piau-Tsu-Im.xlsx" - else: - CONVERT_FILE_NAME = file_path - print(f"CONVERT_FILE_NAME = {CONVERT_FILE_NAME}") - - # 將「漢字注音表」的「台羅注音」拆解出聲母、韻母及聲調 - poo_tsu_im(CONVERT_FILE_NAME) - - # 將已填入注音之「漢字注音表」,製作成 HTML 格式的各式「注音/拼音/標音」。 - hoo_gua_tsu_im(CONVERT_FILE_NAME) - - # ========================================================== - # 檢查「缺字表」狀態 - # ========================================================== - # 指定來源工作表 - source_sheet = xw.Book(CONVERT_FILE_NAME).sheets["缺字表"] - # 取得工作表內總列數 - end_row_no = ( - source_sheet.range("A" + str(source_sheet.cells.last_cell.row)).end("up").row - ) - if end_row_no > 1: - print(f"此次增補注音的漢字總數共:{end_row_no}個。") - - # =========================================================================== - # 依據《文章標題》另存新檔。 - # =========================================================================== - wb = xw.Book(CONVERT_FILE_NAME) - setting_sheet = wb.sheets["env"] - new_file_name = str( - setting_sheet.range("C4").value - ).strip() - new_file_path = os.path.join( - ".\\output", - f"【河洛話注音】{new_file_name}" + ".xlsx") - - # 儲存新建立的工作簿 - wb.save(new_file_path) \ No newline at end of file diff --git "a/a520_\350\243\275\344\275\234\346\263\250\351\237\263\347\266\262\351\240\201.py" "b/a520_\350\243\275\344\275\234\346\263\250\351\237\263\347\266\262\351\240\201.py" deleted file mode 100644 index d7f5f23..0000000 --- "a/a520_\350\243\275\344\275\234\346\263\250\351\237\263\347\266\262\351\240\201.py" +++ /dev/null @@ -1,105 +0,0 @@ -import os -import sqlite3 -import sys - -import xlwings as xw - -import settings -from mod_file_access import ( - San_Sing_Han_Ji_Zu_Im_Piau, - close_excel_file, - get_cmd_input, - open_excel_file, - save_to_a_working_copy, - write_to_excel_file, -) -from mod_廣韻 import init_sing_bu_dict, init_un_bu_dict -from p501_Kong_Un_Cha_Ji_Tian import Kong_Un_Piau_Im -from p502_TLPA_Cu_Im import Iong_TLPA_Cu_Im - - -def initialize_dicts(db_cursor): - """初始化聲母和韻母對照表字典""" - try: - sing_bu_dict = init_sing_bu_dict(db_cursor) - un_bu_dict = init_un_bu_dict(db_cursor) - print("字典初始化完成。") - except Exception as e: - print(f"字典初始化失敗:{e}") - sys.exit(1) - return sing_bu_dict, un_bu_dict - - -def create_annotation_file(wb, db_cursor): - """建立注音表並進行查詢填寫""" - # 建立漢字注音表 - San_Sing_Han_Ji_Zu_Im_Piau(wb.name) - # # 查詢注音並填寫表格 - # Kong_Un_Piau_Im(wb.name, db_cursor) - - -def export_to_html(wb): - """將已注音的漢字注音表導出為 HTML 格式""" - # 這裡可以使用已經填寫的漢字注音表進行轉換 - print("將注音表轉換為 HTML 格式的功能可以在這裡實現。") - - -def main(): - #------------------------------------------------------------------------- - # 使用已打開且處於作用中的 Excel 工作簿 - #------------------------------------------------------------------------- - # 取得專案根目錄。 - try: - wb = xw.apps.active.books.active - except Exception as e: - print(f"發生錯誤: {e}") - print("無法找到作用中的 Excel 工作簿") - sys.exit(2) - - # 獲取活頁簿的完整檔案路徑 - file_path = wb.fullname - print(f"完整檔案路徑: {file_path}") - - # 獲取活頁簿的檔案名稱(不包括路徑) - file_name = wb.name - print(f"檔案名稱: {file_name}") - - # 資料庫連接 - DATABASE = settings.get_database_path() - with sqlite3.connect(DATABASE) as conn: - db_cursor = conn.cursor() - print(f"DATABASE = {DATABASE}") - - # # 取得命令列參數和檔案路徑 - # opts = get_cmd_input() - # CONVERT_FILE_NAME = opts["input"] - # dir_path = opts["dir_path"] - # print(f"處理檔案: {CONVERT_FILE_NAME}") - - # # 開啟指定的 Excel 檔案 - # wb = open_excel_file(dir_path, CONVERT_FILE_NAME) - # if wb is None: - # print("無法開啟檔案,終止程式執行。") - # sys.exit() - - # 初始化字典 - sing_bu_dict, un_bu_dict = initialize_dicts(db_cursor) - - # 創建漢字注音表並查詢注音 - create_annotation_file(wb, db_cursor) - - # 注音轉換處理 - Iong_TLPA_Zu_Im(wb, sing_bu_dict, un_bu_dict) - - # 檢查缺字表狀態 - source_sheet = wb.sheets["缺字表"] - end_row_no = source_sheet.range("A" + str(source_sheet.cells.last_cell.row)).end("up").row - if end_row_no > 1: - print(f"總計字典查不到注音的漢字共:{end_row_no}個。") - - # 儲存 Excel 檔案並關閉 - write_to_excel_file(wb) - close_excel_file(wb) - -if __name__ == "__main__": - main() diff --git "a/a520_\350\243\275\344\275\234\346\263\250\351\237\263\347\266\262\351\240\201_bak.py" "b/a520_\350\243\275\344\275\234\346\263\250\351\237\263\347\266\262\351\240\201_bak.py" deleted file mode 100644 index 29ef926..0000000 --- "a/a520_\350\243\275\344\275\234\346\263\250\351\237\263\347\266\262\351\240\201_bak.py" +++ /dev/null @@ -1,100 +0,0 @@ -#================================================================ -# 《予我廣韻標音》 -# 使用《廣韻》作為漢字標讀音之依據。 -#================================================================ -import getopt -import os -import sqlite3 -import sys - -import xlwings as xw - -import settings -from mod_file_access import ( - close_excel_file, - get_cmd_input, - open_excel_file, - save_to_a_working_copy, - write_to_excel_file, -) -from mod_廣韻_v3 import init_sing_bu_dict, init_un_bu_dict -from p500_Import_Source_Sheet import San_Sing_Han_Ji_Tsh_Im_Piau -from p501_Kong_Un_Cha_Ji_Tian import Kong_Un_Piau_Im -from p502_TLPA_Cu_Im import Iong_TLPA_Zu_Im - - -def main(): - # ==========================================================" - # 資料庫", - # ==========================================================" - # 自 .env 檔案取得資料庫名稱 - DATABASE = settings.get_database_path() - conn = sqlite3.connect(DATABASE) - db_cursor = conn.cursor() - print(f"DATABASE = {DATABASE}") - - # ========================================================================= - # (1) 取得需要注音的「檔案名稱」及其「目錄路徑」。 - # ========================================================================= - # 自命令列取得 Input 檔案名稱 - opts = get_cmd_input() - CONVERT_FILE_NAME = opts["input"] - print(f"CONVERT_FILE_NAME = {CONVERT_FILE_NAME}") - - # 取得檔案所屬之目錄路徑 - dir_path = opts["dir_path"] - - # 指定提供來源的【檔案】 - wb = open_excel_file(dir_path, CONVERT_FILE_NAME) - if wb is None: - print("無法開啟檔案,終止程式執行。") - sys.exit() - - # ========================================================================= - # (2) 建置「漢字注音表」 - # 將存放在「工作表1」的「漢字」文章,製成「漢字注音表」以便填入注音。 - # ========================================================================= - # San_Sing_Han_Ji_Tsh_Im_Piau(CONVERT_FILE_NAME) - - # ========================================================================= - # (3) 在字典查注音,填入漢字注音表。 - # ========================================================================= - # Kong_Un_Piau_Im(CONVERT_FILE_NAME, db_cursor) - - # ========================================================================= - # (4) 將已注音之「漢字注音表」,製作成 HTML 格式之「注音/拼音/標音」網頁。 - # ========================================================================= - - # 設定聲母及韻母之注音對照表 - try: - sing_bu_dict = init_sing_bu_dict(db_cursor) - un_bu_dict = init_un_bu_dict(db_cursor) - except Exception as e: - print(e) - Iong_TLPA_Cu_Im(wb, sing_bu_dict, un_bu_dict) - - # ========================================================== - # 檢查「缺字表」狀態 - # ========================================================== - # 指定來源工作表 - source_sheet = wb.sheets["缺字表"] - # 取得工作表內總列數 - end_row_no = ( - source_sheet.range("A" + str(source_sheet.cells.last_cell.row)).end("up").row - ) - if end_row_no > 1: - print(f"總計字典查不到注音的漢字共:{end_row_no}個。") - - # ========================================================================= - # (5) 依據《文章標題》另存新檔。 - # ========================================================================= - write_to_excel_file(wb) - close_excel_file(wb) - - # ========================================================== - # 關閉資料庫 - # ========================================================== - conn.close() - -if __name__ == "__main__": - main() \ No newline at end of file diff --git "a/a600_\346\274\242\345\255\227\346\237\245\345\273\243\351\237\273\346\223\254\351\237\263_Excel.py" "b/a600_\346\274\242\345\255\227\346\237\245\345\273\243\351\237\273\346\223\254\351\237\263_Excel.py" deleted file mode 100644 index 562554f..0000000 --- "a/a600_\346\274\242\345\255\227\346\237\245\345\273\243\351\237\273\346\223\254\351\237\263_Excel.py" +++ /dev/null @@ -1,103 +0,0 @@ -#============================================================================== -# 透過 Excel ,使用廣韻的反切方法,查找漢字的羅馬拼音。 -# -# 操作方式: -# - 輸入欲查詢羅馬拼音之漢字; -# - 輸入廣韻的查找索引資料。 -# -# ipython a900_廣韻反切查羅馬拼音.ipynb 攝 "書涉 (《廣韻·入聲·葉·攝》)" -#============================================================================== - -import sys - -import xlwings as xw - -from __mod_huan_tshiat import tshu_tiau -from mod_於字典網站查詢漢字之廣韻切語發音 import fetch_kong_un_info - - -def fetch_arg(): - # 取得命令行參數 - cmd_arg = sys.argv[1:] # 取得所有除腳本名稱之外的命令行參數 - - # 檢查 cmd_arg 是否有內容 - if not cmd_arg: # 如果沒有傳入任何參數 - print("沒有傳入任何參數,使用預設參數。") - # else: - # # 無論是否使用預設參數,都遍歷 cmd_arg 中的每個元素 - # for i, arg in enumerate(cmd_arg, start=1): - # print(f"參數 {i}: {arg}") - # else: - # # 如果沒有傳入任何參數,則顯示提示信息,然後終止程式 - # print("請輸入欲查詢《廣韻》切語之漢字。") - # sys.exit(1) - - # 若使用者未輸入欲查詢之漢字,則賦予預設值 - han_ji = cmd_arg[0] if len(cmd_arg) > 0 else "詼" - print(f"han_ji = {han_ji}") - - return han_ji - - - -# 程式作業流程: -# 1. 欲查詢之漢字,如:詼; -# 2. 反切雙字,如:苦回; -# 3. 廣韻查詢索引:廣韻·上平聲·灰·恢; -# 4. 自反切雙字分離出:反切上字、反切下字,如:反切上字=苦、反切下字=回。 -if __name__ == "__main__": - # 取得使用者輸入的參數 - han_ji = fetch_arg() - - # 取得反切語與四聲調類 - tshiat_gu_list = fetch_kong_un_info(han_ji) - - ## 開啟可執行反切查羅馬拼音之活頁簿檔案 - # 1. 開啟 Excel 活頁簿檔案: .\tools\廣韻反切查音工具.xlsx ; - # 2. 擇用 "反切" 工作表。 - # - # [程式規格]: - # - 使用 xlwings 套件,操作 Excel 檔案; - # - 以上兩步的作業程序,都用 try: exception: 形式執行,遇有意外事件發生時,於畫面顯示問題狀況,然後終止程式的繼續執行。 - - try: - # 指定 Excel 檔案路徑 - file_path = r'.\\tools\\廣韻反切查音工具.xlsx' - - # 使用 xlwings 開啟 Excel 檔案 - wb = xw.Book(file_path) - - # 選擇名為 "反切" 的工作表 - sheet = wb.sheets['反切'] - - # 將變數值填入指定的儲存格 - sheet.range('C2').value = han_ji - for item in tshiat_gu_list: - # 將漢字之切語填入指定的儲存格 - sheet.range('D2').value = item["tshiat_gu"] - # 將切語上字填入指定的儲存格 - sheet.range('C5').value = siong_ji = item["tshiat_gu"][0] - # 將切語下字填入指定的儲存格 - sheet.range('C6').value = ha_ji = item["tshiat_gu"][1] - # 將切語下字所屬之四聲調類填入指定的儲存格 - sheet.range('E6').value = tshu_tiau(item["tiau"]) - - # 從 D8 儲存格取出值,存放於變數 tai_lo_phing_im - tai_lo_phing_im = sheet.range('D8').value - - #======================================================= - # 顯示查詢結果 - #======================================================= - print("\n===================================================") - print(f"查詢漢字:{han_ji}\t廣韻切語為: {item['tshiat_gu']}\t台羅拼音為: {tai_lo_phing_im}") - print(f"反切上字:{siong_ji}\t得聲母台羅拼音為: {sheet.range('D5').value}\t分清濁為:{sheet.range('E5').value}") - print(f"反切下字:{ha_ji}\t得韻母台羅拼音為: {sheet.range('D6').value}\t辨四聲為:{sheet.range('E6').value}聲") - if not sheet.range('D7').value == "找不到": - print(f"依分清濁與辨四聲,得聲調為:{sheet.range('E7').value},即:台羅四聲八調之第 {int(sheet.range('D7').value)} 調") - - except Exception as e: - # 如果遇到任何錯誤,顯示錯誤信息並終止程式 - print(f"發生錯誤:{e}") - - - diff --git "a/a600_\346\274\242\345\255\227\346\237\245\345\273\243\351\237\273\346\223\254\351\237\263_SQLite.py" "b/a600_\346\274\242\345\255\227\346\237\245\345\273\243\351\237\273\346\223\254\351\237\263_SQLite.py" deleted file mode 100644 index d3d2f4b..0000000 --- "a/a600_\346\274\242\345\255\227\346\237\245\345\273\243\351\237\273\346\223\254\351\237\263_SQLite.py" +++ /dev/null @@ -1,102 +0,0 @@ -#============================================================================== -# 透過 Excel ,使用廣韻的反切方法,查找漢字的羅馬拼音。 -# -# 操作方式: -# - 輸入欲查詢羅馬拼音之漢字; -# - 輸入廣韻的查找索引資料。 -# -# ipython a900_廣韻反切查羅馬拼音.ipynb 攝 "書涉 (《廣韻·入聲·葉·攝》)" -#============================================================================== - -import sys - -from __mod_huan_tshiat import query_tiau_ho, tshu_tiau -from __mod_Query_for_Tshiat_Gu import query_tshiat_gu_ha_ji, query_tshiat_gu_siong_ji -from mod_於字典網站查詢漢字之廣韻切語發音 import fetch_kong_un_info - - -def fetch_arg(): - # 取得命令行參數 - cmd_arg = sys.argv[1:] # 取得所有除腳本名稱之外的命令行參數 - - # 檢查 cmd_arg 是否有內容 - if not cmd_arg: # 如果沒有傳入任何參數 - print("沒有傳入任何參數,使用預設參數。") - - # 若使用者未輸入欲查詢之漢字,則賦予預設值 - han_ji = cmd_arg[0] if len(cmd_arg) > 0 else "詼" - print(f"han_ji = {han_ji}") - - return han_ji - -# 程式作業流程: -# 1. 欲查詢之漢字,如:詼; -# 2. 反切雙字,如:苦回; -# 3. 廣韻查詢索引:廣韻·上平聲·灰·恢; -# 4. 自反切雙字分離出:反切上字、反切下字,如:反切上字=苦、反切下字=回。 -if __name__ == "__main__": - # 取得使用者輸入的參數 - han_ji = fetch_arg() - - # 自廣韻線上字典,取得反切語與四聲調類 - # 查詢回傳的結果是一個字典陣列,每個字典包含了反切語、四聲調類、韻系、反切下字等資訊 - # tshiat_gu_item = { - # "tshiat_gu": tshiat_gu, # 切語:苦回 - # "tiau": tiau, # 調:平/上/去/入的四聲調類 - # "un_he": un_he, # 韻系:灰 - # "tshia_gu_ha_ji": tshia_gu_ha_ji, # 切語下字:恢 - # } - tshiat_gu_list = fetch_kong_un_info(han_ji) - - #======================================================= - # 顯示查詢結果 - #======================================================= - print("\n===================================================") - print(f"查詢漢字:{han_ji}") - for item in tshiat_gu_list: - # 取得切語 - tshiat_gu = item["tshiat_gu"] - - # 查詢切語上字 - siong_ji = item["tshiat_gu"][0] - tshiat_gu_siong_ji = query_tshiat_gu_siong_ji(siong_ji) - if not tshiat_gu_siong_ji: - print("---------------------------------------------------") - print(f"廣韻切語: {tshiat_gu}\t找不到切語上字:{siong_ji}") - continue - - tai_lo_siann_bu = tshiat_gu_siong_ji[0]["tai_lo"] - tshing_tok = tshiat_gu_siong_ji[0]["tshing_tok"] - - # 查詢切語下字 - ha_ji = item["tshiat_gu"][1] - tshiat_gu_ha_ji = query_tshiat_gu_ha_ji(ha_ji) - if not tshiat_gu_ha_ji: - print("---------------------------------------------------") - print(f"廣韻切語: {tshiat_gu}\t找不到切語下字:{ha_ji}") - continue - - tai_lo_un_bu = tshiat_gu_ha_ji[0]["tai_lo"] - - # 取得四聲調類 - tiau_lui = item["tiau"] - su_sing = tshu_tiau(tiau_lui) - # 查詢反切語之四聲八調之調號 - tiau_ho = query_tiau_ho(tshing_tok, su_sing) - - # 組合台羅拼音 - tai_lo_phing_im = f"{tai_lo_siann_bu}{tai_lo_un_bu}{tiau_ho}" - - #======================================================= - # 顯示查詢結果 - #======================================================= - print("---------------------------------------------------") - print(f"廣韻切語: {tshiat_gu}\t台羅拼音: {tai_lo_phing_im}") - print(f"反切上字:{siong_ji}\t得聲母台羅拼音為: {siong_ji}\t分清濁為:{tshing_tok}") - print(f"反切下字:{ha_ji}\t得韻母台羅拼音為: {ha_ji}\t辨四聲為:{su_sing}聲") - print(f"依分清濁與辨四聲,得聲調為:{tshing_tok[-1]}{su_sing},即:台羅四聲八調之第 {tiau_ho} 調") - # if not sheet.range('D7').value == "找不到": - # print(f"依分清濁與辨四聲,得聲調為:{sheet.range('E7').value},即:台羅四聲八調之第 {int(sheet.range('D7').value)} 調") - - - diff --git "a/a702_\346\237\245\346\211\276\345\217\212\345\241\253\345\205\245\346\274\242\345\255\227\346\250\231\351\237\263.py" "b/a702_\346\237\245\346\211\276\345\217\212\345\241\253\345\205\245\346\274\242\345\255\227\346\250\231\351\237\263.py" index 3e9a963..33bc8cd 100644 --- "a/a702_\346\237\245\346\211\276\345\217\212\345\241\253\345\205\245\346\274\242\345\255\227\346\250\231\351\237\263.py" +++ "b/a702_\346\237\245\346\211\276\345\217\212\345\241\253\345\205\245\346\274\242\345\255\227\346\250\231\351\237\263.py" @@ -13,6 +13,7 @@ # 載入自訂模組 from mod_excel_access import ( + delete_sheet_by_name, get_han_ji_khoo, get_tai_gi_by_han_ji, get_value_by_name, @@ -63,6 +64,60 @@ def logging_process_step(msg): # ========================================================================= # 作業程序 # ========================================================================= +def reset_han_ji_cells(wb, sheet_name='漢字注音'): + sheet = wb.sheets[sheet_name] + sheet.activate() + + # 設定起始及結束的【列】位址(【第5列】、【第9列】、【第13列】等列) + TOTAL_LINES = int(wb.names['每頁總列數'].refers_to_range.value) + ROWS_PER_LINE = 4 + start_row = 5 + end_row = start_row + (TOTAL_LINES * ROWS_PER_LINE) + + # 設定起始及結束的【欄】位址(【D欄=4】到【R欄=18】) + CHARS_PER_ROW = int(wb.names['每列總字數'].refers_to_range.value) + start_col = 4 + end_col = start_col + CHARS_PER_ROW + + # 重設【漢字】儲存格文字及底色格式 + EOF = False + line = 1 + for row in range(start_row, end_row, ROWS_PER_LINE): + # 若已到【結尾】或【超過總行數】,則跳出迴圈 + if EOF or line > TOTAL_LINES: + break + + # 設定【作用儲存格】為列首 + Two_Empty_Cells = 0 + sheet.range((row, 1)).select() + + # 逐欄取出漢字處理 + for col in range(start_col, end_col): + cell_value = sheet.range((row, col)).value + if cell_value == 'φ': + EOF = True + break + elif cell_value == '\n': + break + elif cell_value == None: + if Two_Empty_Cells == 0: + Two_Empty_Cells += 1 + elif Two_Empty_Cells == 1: + EOF = True + break + else: + sheet.range((row, col)).font.color = (0, 0, 0) # 將文字顏色設為【黑色】 + sheet.range((row, col)).color = (255, 255, 255) # 將底色設為【白色】 + + # 若讀到【換行】或【文字終結】,跳出逐欄取字迴圈 + if cell_value == '\n' or EOF: + break + + # 每當處理一行 15 個漢字後,亦換到下一行 + line += 1 + row += 4 + + def ca_ji_kiat_ko_tng_piau_im(result, han_ji_khoo: str, piau_im: PiauIm, piau_im_huat: str): """查字結果出標音:查詢【漢字庫】取得之【查找結果】,將之切分:聲、韻、調""" if han_ji_khoo == "河洛話": @@ -111,24 +166,36 @@ def ca_han_ji_thak_im(wb, sheet_name='漢字注音', cell='V3', ue_im_lui_piat=" cursor = conn.cursor() # 建置 PiauIm 物件,供作漢字拼音轉換作業 - han_ji_khoo = get_value_by_name(wb=wb, name='漢字庫') - piau_im = PiauIm(han_ji_khoo=han_ji_khoo) - piau_im_huat = get_value_by_name(wb=wb, name='標音方法') + han_ji_khoo_field = '漢字庫' + han_ji_khoo_name = get_value_by_name(wb=wb, name=han_ji_khoo_field) + piau_im = PiauIm(han_ji_khoo=han_ji_khoo_name) # 指定漢字自動查找使用的【漢字庫】 + piau_im_huat = get_value_by_name(wb=wb, name='標音方法') # 指定【台語音標】轉換成【漢字標音】的方法 + + # 建置自動及人工漢字標音字庫工作表:(1)【漢字庫工作表】;(2)【人工標音字庫工作表】;(3)【缺字表】 + piau_im_sheet_name = '標音字庫' + delete_sheet_by_name(wb=wb, sheet_name=piau_im_sheet_name) + han_ji_koo_sheet = get_han_ji_khoo(wb=wb, sheet_name=piau_im_sheet_name) - # 建置自動及人工漢字標音字庫工作表:(1)【漢字庫工作表】;(2)【人工標音字庫工作表】 - han_ji_koo_sheet = get_han_ji_khoo(wb=wb, sheet_name='漢字庫') - jin_kang_piau_im = get_han_ji_khoo(wb=wb, sheet_name='人工標音字庫') + jin_kang_piau_im_sheet_name='人工標音字庫' + delete_sheet_by_name(wb=wb, sheet_name=jin_kang_piau_im_sheet_name) + jin_kang_piau_im_sheet = get_han_ji_khoo(wb=wb, sheet_name=jin_kang_piau_im_sheet_name) + + khuat_ji_piau_name = '缺字表' + delete_sheet_by_name(wb=wb, sheet_name=khuat_ji_piau_name) + khuat_ji_piau_sheet = get_han_ji_khoo(wb=wb, sheet_name=khuat_ji_piau_name) # 指定【漢字注音】工作表為【作用工作表】 sheet = wb.sheets[sheet_name] sheet.activate() + # 重設【漢字】儲存格文字及底色格式 + reset_han_ji_cells(wb=wb) + # 設定起始及結束的【列】位址(【第5列】、【第9列】、【第13列】等列) TOTAL_LINES = int(wb.names['每頁總列數'].refers_to_range.value) ROWS_PER_LINE = 4 start_row = 5 end_row = start_row + (TOTAL_LINES * ROWS_PER_LINE) - line = 1 # 設定起始及結束的【欄】位址(【D欄=4】到【R欄=18】) CHARS_PER_ROW = int(wb.names['每列總字數'].refers_to_range.value) @@ -137,6 +204,7 @@ def ca_han_ji_thak_im(wb, sheet_name='漢字注音', cell='V3', ue_im_lui_piat=" # 逐列處理作業 EOF = False + line = 1 for row in range(start_row, end_row, ROWS_PER_LINE): # 若已到【結尾】或【超過總行數】,則跳出迴圈 if EOF or line > TOTAL_LINES: @@ -211,13 +279,13 @@ def ca_han_ji_thak_im(wb, sheet_name='漢字注音', cell='V3', ue_im_lui_piat=" han_ji_u_piau_im = True # 將人工輸入的【台語音標】置入【破音字庫】Dict - maintain_han_ji_koo(sheet=jin_kang_piau_im, + maintain_han_ji_koo(sheet=jin_kang_piau_im_sheet, han_ji=han_ji, tai_gi=tai_gi_im_piau, show_msg=False) else: # 無人工輸入,則自【漢字庫】查找作業 # 查找【人工標音字庫】,確認是否有此漢字 - tai_gi_im_piau = get_tai_gi_by_han_ji(jin_kang_piau_im, han_ji) + tai_gi_im_piau = get_tai_gi_by_han_ji(jin_kang_piau_im_sheet, han_ji) found = True if tai_gi_im_piau else False # 若【破音字庫】有此漢字 if found: @@ -231,15 +299,18 @@ def ca_han_ji_thak_im(wb, sheet_name='漢字注音', cell='V3', ue_im_lui_piat=" tiau_ho ) han_ji_u_piau_im = True - sheet.range((row, col)).font.color = (255, 0, 0) # 將文字顏色設為【紅色】 - sheet.range((row, col)).color = (255, 255, 0) # 將底色設為【黄色】 print(f"漢字:【{han_ji}】之注音【{tai_gi_im_piau}】取自【人工注音字典】。") # 若【人工標音字庫】無此漢字,則在資料庫中查找 else: result = han_ji_ca_piau_im(cursor=cursor, han_ji=han_ji, ue_im_lui_piat=ue_im_lui_piat) + # 若【漢字庫】查無此字,登錄至【缺字表】 if not result: + maintain_han_ji_koo(sheet=khuat_ji_piau_sheet, + han_ji=han_ji, + tai_gi='', + show_msg=False) msg = f"【{han_ji}】查無此字!" else: # 依【漢字庫】查找結果,輸出【台語音標】和【漢字標音】 @@ -258,6 +329,9 @@ def ca_han_ji_thak_im(wb, sheet_name='漢字注音', cell='V3', ue_im_lui_piat=" show_msg=False) sheet.range((row - 1, col)).value = tai_gi_im_piau sheet.range((row + 1, col)).value = han_ji_piau_im + if manual_input: + sheet.range((row, col)).font.color = (255, 0, 0) # 將文字顏色設為【紅色】 + sheet.range((row, col)).color = (255, 255, 0) # 將底色設為【黄色】 msg = f"{han_ji}: [{tai_gi_im_piau}] /【{han_ji_piau_im}】" # 顯示處理進度 @@ -274,52 +348,53 @@ def ca_han_ji_thak_im(wb, sheet_name='漢字注音', cell='V3', ue_im_lui_piat=" row += 4 #---------------------------------------------------------------------- - # 作業處理用的 row 迴圈與 col 迴圈己終結 + # 作業結束前處理 #---------------------------------------------------------------------- # 關閉資料庫連線 conn.close() - - # 作業結束前處理 - wb.save() print("已完成【台語音標】和【漢字標音】標注工作。") return EXIT_CODE_SUCCESS def process(wb): - # ------------------------------------------------------------------------------ - # 指定【作業工作表】為【漢字注音】工作表 - # ------------------------------------------------------------------------------ - sheet = wb.sheets["漢字注音"] # 選擇工作表 - sheet.activate() # 將「漢字注音」工作表設為作用中工作表 + # 動態載入查找函數 + module_name='mod_河洛話' + function_name='han_ji_ca_piau_im' + + # --------------------------------------------------------------------- + # 連上資料庫 + # --------------------------------------------------------------------- + han_ji_khoo_field = '漢字庫' + han_ji_khoo_name = get_value_by_name(wb=wb, name=han_ji_khoo_field) # 取得【漢字庫】名稱:河洛話、廣韻 + ue_im_lui_piat = get_value_by_name(wb, '語音類型') # 取得【語音類型】,判別使用【白話音】或【文讀音】何者。 + db_name = 'Ho_Lok_Ue.db' if han_ji_khoo_name == '河洛話' else 'Kong_Un.db' # ------------------------------------------------------------------------------ # 為漢字查找讀音,漢字上方填:【台語音標】;漢字下方填使用者指定之【漢字標音】 # ------------------------------------------------------------------------------ - type = get_value_by_name(wb, '語音類型') # 取得【語音類型】,判別使用【白話音】或【文讀音】何者。 - han_ji_khoo = get_value_by_name(wb, '漢字庫') - if han_ji_khoo == "河洛話" and type == "白話音": + if han_ji_khoo_name == "河洛話" and ue_im_lui_piat == "白話音": ca_han_ji_thak_im( wb=wb, sheet_name="漢字注音", cell="V3", - ue_im_lui_piat=type, - han_ji_khoo="河洛話", - db_name="Ho_Lok_Ue.db", - module_name="mod_河洛話", - function_name="han_ji_ca_piau_im", + ue_im_lui_piat=ue_im_lui_piat, # "白話音" + han_ji_khoo=han_ji_khoo_name, # "河洛話", + db_name=db_name, # "Ho_Lok_Ue.db", + module_name=module_name, # "mod_河洛話", + function_name=function_name # "han_ji_ca_piau_im", ) - elif han_ji_khoo == "河洛話" and type == "文讀音": + elif han_ji_khoo_name == "河洛話" and ue_im_lui_piat == "文讀音": ca_han_ji_thak_im( wb=wb, sheet_name="漢字注音", cell="V3", - ue_im_lui_piat=type, - han_ji_khoo="河洛話", - db_name="Ho_Lok_Ue.db", - module_name="mod_河洛話", - function_name="han_ji_ca_piau_im", + ue_im_lui_piat=ue_im_lui_piat, # "文讀音" + han_ji_khoo=han_ji_khoo_name, # "河洛話", + db_name=db_name, # "Ho_Lok_Ue.db", + module_name=module_name, # "mod_河洛話", + function_name=function_name # "han_ji_ca_piau_im", ) - elif han_ji_khoo == "廣韻": + elif han_ji_khoo_name == "廣韻": ca_han_ji_thak_im( wb=wb, sheet_name="漢字注音", diff --git "a/a702_\346\237\245\346\211\276\345\217\212\345\241\253\345\205\245\346\274\242\345\255\227\346\250\231\351\237\263_R1.py" "b/a702_\346\237\245\346\211\276\345\217\212\345\241\253\345\205\245\346\274\242\345\255\227\346\250\231\351\237\263_R1.py" deleted file mode 100644 index f24b945..0000000 --- "a/a702_\346\237\245\346\211\276\345\217\212\345\241\253\345\205\245\346\274\242\345\255\227\346\250\231\351\237\263_R1.py" +++ /dev/null @@ -1,176 +0,0 @@ -# ========================================================================= -# 載入程式所需套件/模組/函式庫 -# ========================================================================= -import logging -import os -import sys -from pathlib import Path - -# 載入第三方套件 -import xlwings as xw -from dotenv import load_dotenv - -# 載入自訂模組 -from mod_file_access import get_han_ji_khoo, get_sound_type, save_as_new_file -from p702_Ca_Han_Ji_Thak_Im import ca_han_ji_thak_im - -# ========================================================================= -# 載入環境變數 -# ========================================================================= -load_dotenv() - -# 預設檔案名稱從環境變數讀取 -DB_HO_LOK_UE = os.getenv('DB_HO_LOK_UE', 'Ho_Lok_Ue.db') -DB_KONG_UN = os.getenv('DB_KONG_UN', 'Kong_Un.db') - -# ========================================================================= -# 設定日誌 -# ========================================================================= -logging.basicConfig( - filename='process_log.txt', - level=logging.INFO, - format='%(asctime)s - %(levelname)s - %(message)s' -) - -def logging_process_step(msg): - print(msg) - logging.info(msg) - -# ========================================================================= -# 常數定義 -# ========================================================================= -# 定義 Exit Code -EXIT_CODE_SUCCESS = 0 # 成功 -EXIT_CODE_NO_FILE = 1 # 無法找到檔案 -EXIT_CODE_INVALID_INPUT = 2 # 輸入錯誤 -EXIT_CODE_PROCESS_FAILURE = 3 # 過程失敗 -EXIT_CODE_UNKNOWN_ERROR = 99 # 未知錯誤 - -# ========================================================================= -# 作業程序 -# ========================================================================= -def process(wb): - # ------------------------------------------------------------------------------ - # 指定【作業中工作表】 - # ------------------------------------------------------------------------------ - sheet = wb.sheets["漢字注音"] # 選擇工作表 - sheet.activate() # 將「漢字注音」工作表設為作用中工作表 - sheet.range("A1").select() # 將 A1 儲存格設為作用儲存格 - - # ------------------------------------------------------------------------------ - # 為漢字查找讀音,漢字上方填:【台語音標】;漢字下方填使用者指定之【漢字標音】 - # ------------------------------------------------------------------------------ - type = get_sound_type(wb) # 取得【語音類型】,判別使用【白話音】或【文讀音】何者。 - han_ji_khoo = get_han_ji_khoo(wb) - if han_ji_khoo == "河洛話" and type == "白話音": - ca_han_ji_thak_im( - wb=wb, - sheet_name="漢字注音", - cell="V3", - ue_im_lui_piat=type, - han_ji_khoo="河洛話", - db_name="Ho_Lok_Ue.db", - module_name="mod_河洛話", - function_name="han_ji_ca_piau_im", - ) - elif han_ji_khoo == "河洛話" and type == "文讀音": - ca_han_ji_thak_im( - wb=wb, - sheet_name="漢字注音", - cell="V3", - ue_im_lui_piat=type, - han_ji_khoo="河洛話", - db_name="Ho_Lok_Ue.db", - module_name="mod_河洛話", - function_name="han_ji_ca_piau_im", - ) - elif han_ji_khoo == "廣韻": - ca_han_ji_thak_im( - wb=wb, - sheet_name="漢字注音", - cell="V3", - ue_im_lui_piat="文讀音", - han_ji_khoo="廣韻", - db_name="Kong_Un.db", - module_name="mod_廣韻", - function_name="han_ji_ca_piau_im", - ) - else: - msg = "無法執行漢字標音作業,請確認【env】工作表【語音類型】及【漢字庫】欄位的設定是否正確!" - print(msg) - logging.error(msg) - return EXIT_CODE_INVALID_INPUT - - #-------------------------------------------------------------------------- - # 作業結尾處理 - #-------------------------------------------------------------------------- - save_as_new_file(wb=wb) - logging.info("己存檔至路徑:{file_path}") - return EXIT_CODE_SUCCESS - - -# ============================================================================= -# 程式主流程 -# ============================================================================= -def main(): - # ========================================================================= - # 開始作業 - # ========================================================================= - logging.info("作業開始") - - # ========================================================================= - # (1) 取得專案根目錄。 - # ========================================================================= - current_file_path = Path(__file__).resolve() - project_root = current_file_path.parent - logging_process_step(f"專案根目錄為: {project_root}") - - # ========================================================================= - # (2) 設定【作用中活頁簿】:偵測及獲取 Excel 已開啟之活頁簿檔案。 - # ========================================================================= - wb = None - # 取得【作用中活頁簿】 - try: - wb = xw.apps.active.books.active # 取得 Excel 作用中的活頁簿檔案 - except Exception as e: - print(f"發生錯誤: {e}") - logging.error(f"無法找到作用中的 Excel 工作簿: {e}", exc_info=True) - return EXIT_CODE_NO_FILE - - # 若無法取得【作用中活頁簿】,則因無法繼續作業,故返回【作業異常終止代碼】結束。 - if not wb: - return EXIT_CODE_NO_FILE - - # ========================================================================= - # (3) 執行【處理作業】 - # ========================================================================= - try: - result_code = process(wb) - if result_code != EXIT_CODE_SUCCESS: - logging_process_step("作業異常終止!") - return result_code - - except Exception as e: - print(f"作業過程發生未知的異常錯誤: {e}") - logging.error(f"作業過程發生未知的異常錯誤: {e}", exc_info=True) - return EXIT_CODE_UNKNOWN_ERROR - - finally: - if wb: - # xw.apps.active.quit() # 確保 Excel 被釋放資源,避免開啟殘留 - logging.info("a702_查找及填入漢字標音.py 程式已執行完畢!") - - # ========================================================================= - # 結束作業 - # ========================================================================= - logging.info("作業完成!") - return EXIT_CODE_SUCCESS - - -if __name__ == "__main__": - exit_code = main() - if exit_code == EXIT_CODE_SUCCESS: - print("程式正常完成!") - else: - print(f"程式異常終止,錯誤代碼為: {exit_code}") - sys.exit(exit_code) diff --git "a/a706_\346\211\213\345\213\225\346\233\264\346\255\243\346\274\242\345\255\227\346\250\231\351\237\263.py" "b/a706_\346\211\213\345\213\225\346\233\264\346\255\243\346\274\242\345\255\227\346\250\231\351\237\263.py" index abdd62b..1e8d297 100644 --- "a/a706_\346\211\213\345\213\225\346\233\264\346\255\243\346\274\242\345\255\227\346\250\231\351\237\263.py" +++ "b/a706_\346\211\213\345\213\225\346\233\264\346\255\243\346\274\242\345\255\227\346\250\231\351\237\263.py" @@ -3,8 +3,10 @@ # ========================================================================= import logging import os +import sqlite3 import sys from pathlib import Path +from typing import Callable # 載入第三方套件 import xlwings as xw @@ -14,14 +16,15 @@ from a701_作業中活頁檔填入漢字 import process as fill_hanji_in_cells # 載入自訂模組/函式 -from mod_excel_access import ( - get_han_ji_khoo, - get_total_rows_in_sheet, - maintain_han_ji_koo, -) -from mod_file_access import save_as_new_file +# from p709_reset_han_ji_cells import reset_han_ji_cells +from a702_查找及填入漢字標音 import reset_han_ji_cells + +# 載入自訂模組/函式 +from mod_excel_access import get_han_ji_khoo, get_value_by_name, maintain_han_ji_koo +from mod_file_access import load_module_function, save_as_new_file +from mod_標音 import PiauIm # 漢字標音物件 from mod_標音 import is_punctuation # 是否為標點符號 -from p709_reset_han_ji_cells import reset_han_ji_cells +from mod_標音 import tlpa_tng_han_ji_piau_im # 台語音標轉台語音標 # ========================================================================= # 載入環境變數 @@ -59,43 +62,47 @@ def logging_process_step(msg): # ========================================================================= # 本程式主要處理作業程序 # ========================================================================= -def update_han_ji_piau_im(wb, han_ji_khoo_sheet_name='漢字庫', jin_kang_piau_im_sheet_name='人工標音字庫'): +def update_han_ji_piau_im(wb): """ - 更新【漢字注音】表中【台語音標】儲存格的內容,依據【漢字庫】中的【校正】欄位進行更新。 - wb: Excel 活頁簿物件 - han_ji_koo_sheet_name: 【漢字庫】工作表名稱 - han_ji_zhu_yin_sheet_name: 【漢字注音】工作表名稱 + 更新【漢字注音】表中【台語音標】儲存格的內容,依據【標音字庫】中的【校正音標】欄位進行更新,並將【校正音標】覆蓋至原【台語音標】。 """ + # 建置 PiauIm 物件,供作漢字拼音轉換作業 + han_ji_khoo_field = '漢字庫' + han_ji_khoo_name = get_value_by_name(wb=wb, name=han_ji_khoo_field) # 取得【漢字庫】名稱:河洛話、廣韻 + piau_im = PiauIm(han_ji_khoo=han_ji_khoo_name) # 指定漢字自動查找使用的【漢字庫】 + ue_im_lui_piat = get_value_by_name(wb=wb, name='語音類型') + piau_im_huat = get_value_by_name(wb=wb, name='標音方法') # 指定【台語音標】轉換成【漢字標音】的方法 + # 取得工作表 han_ji_piau_im_sheet = wb.sheets['漢字注音'] - han_ji_khoo_sheet = wb.sheets[han_ji_khoo_sheet_name] - jin_kang_piau_im_sheet = wb.sheets[jin_kang_piau_im_sheet_name] + piau_im_sheet_name = '標音字庫' + piau_im_ji_khoo_sheet = get_han_ji_khoo(wb=wb, sheet_name=piau_im_sheet_name) - # 取得【漢字庫】表格範圍的所有資料 - data = han_ji_khoo_sheet.range("A2").expand("table").value + # 取得【標音字庫】表格範圍的所有資料 + data = piau_im_ji_khoo_sheet.range("A2").expand("table").value if data is None: - print("【漢字庫】工作表無資料") + print("【標音字庫】工作表無資料") return EXIT_CODE_INVALID_INPUT # 確保資料為 2D 列表 if not isinstance(data[0], list): data = [data] - # 將資料轉為字典格式,key: 漢字, value: (台語音標, 校正, 次數) + # 將資料轉為字典格式,key: 漢字, value: (台語音標, 校正音標, 次數) han_ji_dict = {} - for row in data: + for i, row in enumerate(data, start=2): han_ji = row[0] or "" tai_gi_im_piau = row[1] or "" total_count = int(row[2]) if len(row) > 2 and isinstance(row[2], (int, float)) else 0 corrected_tai_gi = row[3] if len(row) > 3 else "" # 若無 D 欄資料則設為空字串 - if corrected_tai_gi and (corrected_tai_gi != tai_gi_im_piau): - han_ji_dict[han_ji] = (tai_gi_im_piau, corrected_tai_gi, total_count) + if corrected_tai_gi and corrected_tai_gi != tai_gi_im_piau: + han_ji_dict[han_ji] = (tai_gi_im_piau, corrected_tai_gi, total_count, i) # i 為資料列索引 # 若無需更新的資料,結束函數 if not han_ji_dict: - print("【漢字庫】工作表中,【校正音標】欄,均未填入需更新之台語音標!") + print("【標音字庫】工作表中,【校正音標】欄,均未填入需更新之台語音標!") return EXIT_CODE_SUCCESS # 逐列處理【漢字注音】表 @@ -114,40 +121,55 @@ def update_han_ji_piau_im(wb, han_ji_khoo_sheet_name='漢字庫', jin_kang_piau_ han_ji = han_ji_cell.value or "" if han_ji in han_ji_dict: - _, corrected_tai_gi, total_count = han_ji_dict[han_ji] + original_tai_gi, corrected_tai_gi, total_count, row_index_in_ji_khoo = han_ji_dict[han_ji] tai_gi_cell = han_ji_piau_im_sheet.range((row - 1, col)) - original_tai_gi = tai_gi_cell.value or "" + original_tai_gi_in_sheet = tai_gi_cell.value or "" jin_kang_piau_im_cell = han_ji_piau_im_sheet.range((row + 2, col)) jin_kang_piau_im = jin_kang_piau_im_cell.value or "" + han_ji_piau_im_cell = han_ji_piau_im_sheet.range((row + 1, col)) # 更新多次,直到總數用完 - if corrected_tai_gi != original_tai_gi and total_count > 0: + if corrected_tai_gi != original_tai_gi_in_sheet and total_count > 0: if jin_kang_piau_im: # 若【人工標音】已有標音,則不進行更新 msg = f"({row}, {xw.utils.col_name(col)}) = {han_ji},已有人工標音【{jin_kang_piau_im}】,故無更新" else: - tai_gi_cell.value = corrected_tai_gi # 更新儲存格 + tai_gi_cell.value = corrected_tai_gi # 更新【台語音標】儲存格 han_ji_cell.color = (255, 255, 0) # 將底色設為【黄色】 han_ji_cell.font.color = (255, 0, 0) # 將文字顏色設為【紅色】 - msg = f"({row}, {xw.utils.col_name(col)}) = {han_ji},台語音標由【{original_tai_gi}】改為【{corrected_tai_gi}】" + + tai_gi_im_piau = corrected_tai_gi + han_ji_piau_im = tlpa_tng_han_ji_piau_im( + piau_im=piau_im, + piau_im_huat=piau_im_huat, + tai_gi_im_piau=tai_gi_im_piau + ) + han_ji_piau_im_cell.value = han_ji_piau_im # 更新【漢字標音】儲存格 + + # 更新【標音字庫】中原【台語音標】欄位內容 + piau_im_ji_khoo_sheet.range(f"B{row_index_in_ji_khoo}").value = corrected_tai_gi + msg = f"({row}, {xw.utils.col_name(col)}) = {han_ji},台語音標由【{original_tai_gi_in_sheet}】改為【{corrected_tai_gi}】/【{han_ji_piau_im}】" print(msg) total_count -= 1 # 減少剩餘更新次數 - # 更新完畢後,減少【漢字庫】的總數 - han_ji_khoo_sheet.range(f"C{row + 1}").value = total_count + # 更新完畢後,減少【標音字庫】的總數 + piau_im_ji_khoo_sheet.range(f"C{row_index_in_ji_khoo}").value = total_count if total_count == 0: print(f"漢字【{han_ji}】的更新次數已用完") print("【漢字注音】表的台語音標更新作業已完成") # 作業結束前處理 - logging_process_step(f"完成【作業程序】:更新漢字標音...") + logging_process_step(f"完成【作業程序】:更新漢字標音並同步【標音字庫】內容...") return EXIT_CODE_SUCCESS def process(wb): - return_code = update_han_ji_piau_im(wb) + # --------------------------------------------------------------------- + # 依【標音字庫】的【校正音標】,更新【漢字注音】表中的【台語音標】 + # --------------------------------------------------------------------- + return_code = update_han_ji_piau_im(wb=wb) if return_code != EXIT_CODE_SUCCESS: logging_process_step("處理作業失敗,過程中出錯!") return return_code diff --git "a/bu-a720_\345\276\205\346\263\250\351\237\263\346\274\242\345\255\227\345\241\253\345\205\245\346\250\231\351\237\263\347\224\250\346\226\271\346\240\274.py" "b/bu-a720_\345\276\205\346\263\250\351\237\263\346\274\242\345\255\227\345\241\253\345\205\245\346\250\231\351\237\263\347\224\250\346\226\271\346\240\274.py" deleted file mode 100644 index 3ae29d3..0000000 --- "a/bu-a720_\345\276\205\346\263\250\351\237\263\346\274\242\345\255\227\345\241\253\345\205\245\346\250\231\351\237\263\347\224\250\346\226\271\346\240\274.py" +++ /dev/null @@ -1,86 +0,0 @@ -# 填漢字等標音:將整段的文字拆解,個別填入儲存格,以便後續人工手動填入台語音標、注音符號。 -import getopt -import sys - -import xlwings as xw - -import settings -from p701_Clear_Cells import clear_hanji_in_cells -from p710_thiam_han_ji import fill_hanji_in_cells - - -def get_input_and_output_options(argv): - arg_input = "" - arg_output = "" - arg_user = "" - arg_help = "{0} -i -u -o ".format(argv[0]) - - try: - opts, args = getopt.getopt( # pyright: ignore - argv[1:], "hi:u:o:", ["help", "input=", "user=", "output="] - ) - except Exception as e: - print(e) - print(arg_help) - sys.exit(2) - - for opt, arg in opts: - if opt in ("-h", "--help"): - print(arg_help) # print the help message - sys.exit(2) - elif opt in ("-i", "--input"): - arg_input = arg - elif opt in ("-u", "--user"): - arg_user = arg - elif opt in ("-o", "--output"): - arg_output = arg - - print("input:", arg_input) - print("user:", arg_user) - print("output:", arg_output) - - return { - "input": arg_input, - "user": arg_user, - "output": arg_output, - } - - -if __name__ == "__main__": - # ========================================================================= - # (1) 取得需要注音的「檔案名稱」及其「目錄路徑」。 - # ========================================================================= - # 取得 Input 檔案名稱 - file_path = settings.get_tai_gi_zu_im_bun_path() - if not file_path: - print("未設定 .env 檔案") - # sys.exit(2) - opts = get_input_and_output_options(sys.argv) - if opts["input"] != "": - CONVERT_FILE_NAME = opts["input"] - else: - CONVERT_FILE_NAME = "Tai_Gi_Zu_Im_Bun.xlsx" - else: - CONVERT_FILE_NAME = file_path - print(f"CONVERT_FILE_NAME = {CONVERT_FILE_NAME}") - - # 打開 Excel 檔案 - wb = xw.Book(CONVERT_FILE_NAME) - - # 顯示「已輸入之拼音字母及注音符號」 - named_range = wb.names['顯示注音輸入'] # 選擇名為 "顯示注音輸入" 的命名範圍# 選擇名為 "顯示注音輸入" 的命名範圍 - named_range.refers_to_range.value = True - - # ========================================================================= - # (2) 將漢字填入 - # - 上方:台語音標 - # - 下方:台語注音符號 - # ========================================================================= - # 選擇工作表 - sheet = wb.sheets['漢字注音'] - - # 清除 C3:R166 範圍的內容 - sheet.range('D3:R166').clear_contents() - - # 將漢字逐個填入各儲存格 - fill_hanji_in_cells(wb) diff --git "a/bu-a730_\345\260\207\346\274\242\345\255\227\346\263\250\351\237\263\345\241\253\345\205\245.py" "b/bu-a730_\345\260\207\346\274\242\345\255\227\346\263\250\351\237\263\345\241\253\345\205\245.py" deleted file mode 100644 index 52a90e8..0000000 --- "a/bu-a730_\345\260\207\346\274\242\345\255\227\346\263\250\351\237\263\345\241\253\345\205\245.py" +++ /dev/null @@ -1,91 +0,0 @@ -import getopt -import sys - -import xlwings as xw - -import settings -from p720_Thiam_Zu_Im import thiam_zu_im - - -def get_input_and_output_options(argv): - arg_input = "" - arg_output = "" - arg_user = "" - arg_help = "{0} -i -u -o ".format(argv[0]) - - try: - opts, args = getopt.getopt( # pyright: ignore - argv[1:], "hi:u:o:", ["help", "input=", "user=", "output="] - ) - except Exception as e: - print(e) - print(arg_help) - sys.exit(2) - - for opt, arg in opts: - if opt in ("-h", "--help"): - print(arg_help) # print the help message - sys.exit(2) - elif opt in ("-i", "--input"): - arg_input = arg - elif opt in ("-u", "--user"): - arg_user = arg - elif opt in ("-o", "--output"): - arg_output = arg - - print("input:", arg_input) - print("user:", arg_user) - print("output:", arg_output) - - return { - "input": arg_input, - "user": arg_user, - "output": arg_output, - } - - -if __name__ == "__main__": - # ========================================================================= - # (1) 取得需要注音的「檔案名稱」及其「目錄路徑」。 - # ========================================================================= - # 取得 Input 檔案名稱 - file_path = settings.get_tai_gi_zu_im_bun_path() - if not file_path: - print("未設定 .env 檔案") - # sys.exit(2) - opts = get_input_and_output_options(sys.argv) - if opts["input"] != "": - CONVERT_FILE_NAME = opts["input"] - else: - CONVERT_FILE_NAME = "Tai_Gi_Zu_Im_Bun.xlsx" - else: - CONVERT_FILE_NAME = file_path - print(f"CONVERT_FILE_NAME = {CONVERT_FILE_NAME}") - - # 打開 Excel 檔案 - wb = xw.Book(CONVERT_FILE_NAME) - - # ========================================================================= - # (2) 分析已輸入的【台語音標】及【台語注音符號】,將之各別填入漢字之上、下方。 - # - 上方:台語音標 - # - 下方:台語注音符號 - # ========================================================================= - thiam_zu_im(wb, '漢字注音', 'V3') - - # ========================================================================= - # (3) 依據《文章標題》另存新檔。 - # ========================================================================= - # wb = xw.Book(CONVERT_FILE_NAME) - # setting_sheet = wb.sheets["env"] - # new_file_name = str( - # setting_sheet.range("C4").value - # ).strip() - # new_file_path = os.path.join( - # ".\\output", - # f"【河洛話注音】{new_file_name}" + ".xlsx") - - # # 儲存新建立的工作簿 - # wb.save(new_file_path) - - # 保存 Excel 檔案 - # wb.close() diff --git a/fun_ha_ji_tsa_un_bu.py b/fun_ha_ji_tsa_un_bu.py deleted file mode 100644 index 3dc3523..0000000 --- a/fun_ha_ji_tsa_un_bu.py +++ /dev/null @@ -1,40 +0,0 @@ -import xlwings as xw - -def ha_ji_tsa_un_bu(ha_ji): - try: - # 使用 xlwings 打開 Excel 檔案 - file_path = r'.\\tools\\反切下字與韻母對映表.xlsx' - wb = xw.Book(file_path) - sheet = wb.sheets['反切下字表'] - - # 查找 ha_ji 在指定範圍 (J2:J187) 的位置 - for row in range(2, 188): # 資料從第2列開始,到第187列 - cell_value = sheet.range(f'J{row}').value - if cell_value: - words = cell_value.split() # 按空格拆分儲存格的值 - if ha_ji in words: - # 如果找到了 ha_ji,則記錄下其相對映之 "列號",並從相關欄位獲取資料 - data = { - "id": row - 1, # 第一行為標題行,故實際列號需要減1 - "liap": sheet.range(f'B{row}').value, # 攝 - "un_he": sheet.range(f'C{row}').value, # 韻系 - "si_siann": sheet.range(f'D{row}').value, # 四聲 (平上去入) - "ting_de": sheet.range(f'E{row}').value, # 等第 - "khai_hap": sheet.range(f'F{row}').value, # 開合 - "un_bu": sheet.range(f'G{row}').value, # 韻母 - "tai_lo": sheet.range(f'H{row}').value, # 臺羅拼音 - "IPA": sheet.range(f'I{row}').value, # 國際音標 - } - wb.close() # 處理完成後關閉工作簿 - return data - wb.close() # 如果沒找到,也關閉工作簿 - return None # 如果在範圍內沒有找到 ha_ji,返回 None - except Exception as e: - print(f"發生錯誤:{e}") - return None - - -# 測試函數 -ha_ji = "荅" # 假設的反切上字 -result = ha_ji_tsa_un_bu(ha_ji) -print(result) \ No newline at end of file diff --git a/fun_siong_ji_tsa_siann_bu.py b/fun_siong_ji_tsa_siann_bu.py deleted file mode 100644 index 2ada062..0000000 --- a/fun_siong_ji_tsa_siann_bu.py +++ /dev/null @@ -1,35 +0,0 @@ -import xlwings as xw - -def siong_ji_tsa_siann_bu(siong_ji): - try: - # 使用 xlwings 打開 Excel 檔案 - file_path = r'.\\tools\\反切上字與聲母對映表.xlsx' - wb = xw.Book(file_path) - sheet = wb.sheets['反切上字表'] # 假設工作表的名稱為 "反切上字" - - # 查找 siong_ji 在 "反切上字" 欄 (G2:G39) 的位置 - for row in range(2, 40): # 假設資料從第2行開始,到第39行 - cell_value = sheet.range(f'G{row}').value - if cell_value: - words = cell_value.split() # 按空格拆分儲存格的值 - if siong_ji in words: - # 如果找到了 siong_ji,則記錄下其相對映之 "列號",並從相關欄位獲取資料 - data = { - "id": row - 1, # 第一行為標題行,故實際列號需要減1 - "lui": sheet.range(f'B{row}').value, - "siann_bu": sheet.range(f'C{row}').value, - "tai_lo": sheet.range(f'D{row}').value, - "IPA": sheet.range(f'E{row}').value, - } - wb.close() # 處理完成後關閉工作簿 - return data - wb.close() # 如果沒找到,也關閉工作簿 - return None # 如果在範圍內沒有找到 siong_ji,返回 None - except Exception as e: - print(f"發生錯誤:{e}") - return None - -# 測試函數 -siong_ji = "普" # 假設的反切上字 -result = siong_ji_tsa_siann_bu(siong_ji) -print(result) diff --git a/mod_excel_access.py b/mod_excel_access.py index a10c2ae..77c30fa 100644 --- a/mod_excel_access.py +++ b/mod_excel_access.py @@ -56,6 +56,24 @@ def logging_process_step(msg): # ========================================================================= # 程式用函式 # ========================================================================= +def delete_sheet_by_name(wb, sheet_name: str, show_msg: bool=False): + """ + 刪除指定名稱的工作表 + wb: Excel 活頁簿物件 + sheet_name: 要刪除的工作表名稱 + """ + try: + # 檢查工作表是否存在 + if sheet_name in [sheet.name for sheet in wb.sheets]: + sheet = wb.sheets[sheet_name] + sheet.delete() # 刪除工作表 + if show_msg: print(f"已成功刪除工作表:{sheet_name}") + else: + if show_msg: print(f"無法刪除,工作表 {sheet_name} 不存在") + except Exception as e: + if show_msg: print(f"刪除工作表時發生錯誤:{e}") + + def get_value_by_name(wb, name): try: if name in wb.names: @@ -66,7 +84,7 @@ def get_value_by_name(wb, name): value = None return value -def get_han_ji_khoo(wb, sheet_name="漢字庫"): +def get_han_ji_khoo(wb, sheet_name="標音字庫"): """ 從 Excel 工作表中取得漢字庫 wb: Excel 活頁簿物件 diff --git "a/output7/\343\200\220\346\262\263\346\264\233\347\231\275\350\251\261\346\263\250\351\237\263-\351\233\205\344\277\227\351\200\232\343\200\221\343\200\212TestCase\343\200\213.xlsx" "b/output7/\343\200\220\346\262\263\346\264\233\347\231\275\350\251\261\346\263\250\351\237\263-\351\233\205\344\277\227\351\200\232\343\200\221\343\200\212TestCase\343\200\213.xlsx" index 7ff760e1e531adc850a22090194fd558336007ac..715fb85668b97ff737ce6181071beb705c42be99 100644 GIT binary patch delta 27215 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 delta 28210 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... + function_name="han_ji_ca_piau_im", + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ) + ^ + File "a702_查找及填入漢字標音.py", line 255, in ca_han_ji_thak_im + maintain_han_ji_koo(sheet=han_ji_koo_sheet, + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^ + han_ji=han_ji, + ^^^^^^^^^^^^^^ + tai_gi=tai_gi_im_piau, + ^^^^^^^^^^^^^^^^^^^^^^ + show_msg=False) + ^^^^^^^^^^^^^^^ + File "c:\work\Piau-Im\mod_excel_access.py", line 125, in maintain_han_ji_koo + sheet.range("A2").value = records # 寫入更新後的資料 + ^^^^^^^^^^^^^^^^^^^^^^^ + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\main.py", line 2482, in value + conversion.write(data, self, self._options) + ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\conversion\__init__.py", line 94, in write + raise Exception( + "All elements of a 2d list or tuple must be of the same length" + ) +Exception: All elements of a 2d list or tuple must be of the same length +2025-01-13 14:21:29,900 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 14:22:50,766 - INFO - 作業開始 +2025-01-13 14:22:50,768 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 14:23:39,826 - INFO - 己存檔至路徑:{file_path} +2025-01-13 14:23:39,826 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 14:23:39,826 - INFO - 作業完成! +2025-01-13 15:24:33,801 - INFO - 作業開始 +2025-01-13 15:24:33,803 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 15:25:23,643 - INFO - 己存檔至路徑:{file_path} +2025-01-13 15:25:23,643 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 15:25:23,643 - INFO - 作業完成! +2025-01-13 15:27:24,595 - INFO - 作業開始 +2025-01-13 15:27:24,596 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 15:28:14,103 - INFO - 己存檔至路徑:{file_path} +2025-01-13 15:28:14,104 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 15:28:14,104 - INFO - 作業完成! +2025-01-13 15:48:29,297 - INFO - 作業開始 +2025-01-13 15:48:29,298 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 15:49:19,690 - INFO - 己存檔至路徑:{file_path} +2025-01-13 15:49:19,690 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 15:49:19,690 - INFO - 作業完成! +2025-01-13 16:01:45,921 - INFO - 作業開始 +2025-01-13 16:01:45,922 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:02:36,713 - INFO - 己存檔至路徑:{file_path} +2025-01-13 16:02:36,714 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:02:36,714 - INFO - 作業完成! +2025-01-13 16:05:06,068 - INFO - 作業開始 +2025-01-13 16:05:06,069 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:06:14,362 - ERROR - 作業過程發生未知的異常錯誤: (-2147352567, '發生例外狀況。', (0, 'Microsoft Excel', 'Class Range 的 Select 方法失敗', 'xlmain11.chm', 0, -2146827284), None) +Traceback (most recent call last): + File "a702_查找及填入漢字標音.py", line 391, in main + result_code = process(wb) + File "a702_查找及填入漢字標音.py", line 309, in process + ca_han_ji_thak_im( + ~~~~~~~~~~~~~~~~~^ + wb=wb, + ^^^^^^ + ...<6 lines>... + function_name="han_ji_ca_piau_im", + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ) + ^ + File "a702_查找及填入漢字標音.py", line 154, in ca_han_ji_thak_im + sheet.range((row, 1)).select() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^ + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\main.py", line 2815, in select + self.impl.select() + ~~~~~~~~~~~~~~~~^^ + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\_xlwindows.py", line 1500, in select + return self.xl.Select() + ~~~~~~~~~~~~~~^^ + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\_xlwindows.py", line 122, in __call__ + v = self.__method(*args, **kwargs) + File ">", line 2, in Select + File "c:\work\Piau-Im\.venv\Lib\site-packages\win32com\client\dynamic.py", line 355, in _ApplyTypes_ + result = self._oleobj_.InvokeTypes( + *(dispid, LCID, wFlags, retType, argTypes) + args + ) +pywintypes.com_error: (-2147352567, '發生例外狀況。', (0, 'Microsoft Excel', 'Class Range 的 Select 方法失敗', 'xlmain11.chm', 0, -2146827284), None) +2025-01-13 16:06:14,369 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:08:36,117 - INFO - 作業開始 +2025-01-13 16:08:36,118 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:09:26,548 - INFO - 己存檔至路徑:{file_path} +2025-01-13 16:09:26,548 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:09:26,548 - INFO - 作業完成! +2025-01-13 16:22:44,428 - INFO - 作業開始 +2025-01-13 16:22:44,430 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:23:38,486 - INFO - 己存檔至路徑:{file_path} +2025-01-13 16:23:38,486 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:23:38,486 - INFO - 作業完成! +2025-01-13 16:25:17,744 - INFO - 作業開始 +2025-01-13 16:25:17,745 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:26:12,009 - INFO - 己存檔至路徑:{file_path} +2025-01-13 16:26:12,009 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:26:12,009 - INFO - 作業完成! +2025-01-13 16:27:07,971 - INFO - 作業開始 +2025-01-13 16:27:07,972 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:28:00,615 - INFO - 己存檔至路徑:{file_path} +2025-01-13 16:28:00,615 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:28:00,615 - INFO - 作業完成! +2025-01-13 16:37:01,720 - INFO - 作業開始 +2025-01-13 16:37:01,721 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:37:10,961 - INFO - 己存檔至路徑:{file_path} +2025-01-13 16:37:10,961 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:37:10,961 - INFO - 作業完成! +2025-01-13 16:38:34,701 - INFO - 作業開始 +2025-01-13 16:38:34,702 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:38:43,640 - INFO - 己存檔至路徑:{file_path} +2025-01-13 16:38:43,640 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:38:43,640 - INFO - 作業完成! +2025-01-13 16:39:32,976 - INFO - 作業開始 +2025-01-13 16:39:32,977 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:40:25,447 - INFO - 己存檔至路徑:{file_path} +2025-01-13 16:40:25,447 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 16:40:25,447 - INFO - 作業完成! +2025-01-13 16:55:04,247 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 16:55:04,267 - ERROR - 執行過程中發生未知錯誤: (-2147352567, '發生例外狀況。', (0, None, None, None, 0, -2147352565), None) +Traceback (most recent call last): + File "a706_手動更正漢字標音.py", line 198, in main + result_code = process(wb) + File "a706_手動更正漢字標音.py", line 157, in process + return_code = update_han_ji_piau_im(wb) + File "a706_手動更正漢字標音.py", line 74, in update_han_ji_piau_im + han_ji_khoo_sheet = wb.sheets[han_ji_khoo_sheet_name] + ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^ + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\main.py", line 89, in __getitem__ + return self(key) + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\main.py", line 5218, in __call__ + return Sheet(impl=self.impl(name_or_index)) + ~~~~~~~~~^^^^^^^^^^^^^^^ + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\_xlwindows.py", line 943, in __call__ + return Sheet(xl=self.xl(name_or_index)) + ~~~~~~~^^^^^^^^^^^^^^^ + File "c:\work\Piau-Im\.venv\Lib\site-packages\xlwings\_xlwindows.py", line 236, in __call__ + v = self._inner(*args, **kwargs) + File "c:\work\Piau-Im\.venv\Lib\site-packages\win32com\client\dynamic.py", line 213, in __call__ + self._oleobj_.Invoke(*allArgs), self._olerepr_.defaultDispatchName, None + ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^ +pywintypes.com_error: (-2147352567, '發生例外狀況。', (0, None, None, None, 0, -2147352565), None) +2025-01-13 16:55:04,337 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 17:03:41,448 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 17:04:14,021 - INFO - 完成【作業程序】:更新漢字標音... +2025-01-13 17:04:14,021 - INFO - 完成【處理作業】... +2025-01-13 17:04:14,093 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 17:04:14,093 - INFO - 作業成功完成! +2025-01-13 17:38:12,132 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 17:38:24,208 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 17:38:32,786 - INFO - 完成【處理作業】... +2025-01-13 17:38:32,873 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 17:38:32,873 - INFO - 作業成功完成! +2025-01-13 17:39:53,580 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 17:40:06,203 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 17:40:06,203 - INFO - 完成【處理作業】... +2025-01-13 17:40:06,267 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 17:40:06,267 - INFO - 作業成功完成! +2025-01-13 17:40:37,701 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 17:40:49,702 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 17:40:49,702 - INFO - 完成【處理作業】... +2025-01-13 17:40:49,771 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 17:40:49,771 - INFO - 作業成功完成! +2025-01-13 17:41:47,291 - INFO - 作業開始 +2025-01-13 17:41:47,292 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 17:42:40,304 - INFO - 己存檔至路徑:{file_path} +2025-01-13 17:42:40,304 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 17:42:40,304 - INFO - 作業完成! +2025-01-13 17:43:16,699 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 17:49:10,630 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 17:49:10,630 - INFO - 完成【處理作業】... +2025-01-13 17:49:10,702 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 17:49:10,702 - INFO - 作業成功完成! +2025-01-13 17:49:47,360 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 17:49:59,850 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 17:49:59,850 - INFO - 完成【處理作業】... +2025-01-13 17:49:59,919 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 17:49:59,919 - INFO - 作業成功完成! +2025-01-13 19:15:50,215 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 19:17:03,238 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 19:17:03,238 - INFO - 完成【處理作業】... +2025-01-13 19:17:03,304 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 19:17:03,304 - INFO - 作業成功完成! +2025-01-13 19:20:46,362 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 19:20:58,877 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 19:20:58,878 - INFO - 完成【處理作業】... +2025-01-13 19:20:58,949 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 19:20:58,949 - INFO - 作業成功完成! +2025-01-13 20:12:17,982 - INFO - 作業開始 +2025-01-13 20:12:17,983 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 20:13:15,446 - INFO - 己存檔至路徑:{file_path} +2025-01-13 20:13:15,446 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 20:13:15,446 - INFO - 作業完成! +2025-01-13 20:13:24,315 - INFO - 作業開始 +2025-01-13 20:13:24,316 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 20:14:26,209 - INFO - 己存檔至路徑:{file_path} +2025-01-13 20:14:26,209 - INFO - a702_查找及填入漢字標音.py 程式已執行完畢! +2025-01-13 20:14:26,210 - INFO - 作業完成! +2025-01-13 20:15:54,117 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 20:16:06,915 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 20:16:06,915 - INFO - 完成【處理作業】... +2025-01-13 20:16:06,976 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 20:16:06,976 - INFO - 作業成功完成! +2025-01-13 20:17:54,816 - INFO - 專案根目錄為: C:\work\Piau-Im +2025-01-13 20:18:13,020 - INFO - 完成【作業程序】:更新漢字標音並同步【標音字庫】內容... +2025-01-13 20:18:13,020 - INFO - 完成【處理作業】... +2025-01-13 20:18:13,082 - INFO - 釋放 Excel 資源,處理完成。 +2025-01-13 20:18:13,083 - INFO - 作業成功完成!