Files
BLD_sync/vbareplace.py
Misaka_Company a1c8a572bd Enhance logging and synchronization features across multiple scripts
- Added detailed logging functionality to init_full_sync.py and run_incremental_sync.py for better tracking of synchronization processes.
- Updated configuration mappings in config.py to include additional Access database tables.
- Improved error handling and user feedback in vbareplace.py, including the ability to refresh linked tables in Access.
- Adjusted polling intervals and batch sizes for performance optimization.
2026-01-07 15:01:27 +08:00

128 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import sys
import win32com.client
import tkinter as tk
from tkinter import messagebox
# 隐藏 tkinter 主窗口
root = tk.Tk()
root.withdraw()
def main():
# 检查是否通过拖拽传入文件
if len(sys.argv) != 2:
messagebox.showerror("错误", "请将一个 Access 数据库文件拖拽到此 EXE 上运行!")
return
access_file = sys.argv[1]
# 检查文件是否存在且是 Access 文件
if not os.path.exists(access_file):
messagebox.showerror("错误", f"文件不存在:\n{access_file}")
return
ext = os.path.splitext(access_file)[1].lower()
if ext not in ['.accdb', '.mdb']:
messagebox.showwarning("警告", "这不是一个 Access 数据库文件(.accdb 或 .mdb\n将尝试继续,但可能失败。")
# 获取脚本所在目录EXE 同目录)
if getattr(sys, 'frozen', False):
script_dir = os.path.dirname(sys.executable)
else:
script_dir = os.path.dirname(os.path.abspath(__file__))
vba_txt_file = os.path.join(script_dir, "vba.txt")
if not os.path.exists(vba_txt_file):
messagebox.showerror("错误", f"未找到 vba.txt 文件!\n请确保 vba.txt 与 EXE 在同一目录。\n路径: {vba_txt_file}")
return
# 读取新 VBA 代码
try:
with open(vba_txt_file, "r", encoding="utf-8") as f:
new_code = f.read()
except Exception as e:
messagebox.showerror("错误", f"读取 vba.txt 失败:\n{e}")
return
try:
# 启动 Access使用 DispatchEx 强制创建新实例,避免与已打开的 Access 冲突)
access = win32com.client.DispatchEx("Access.Application")
access.Visible = False # 后台运行,不显示窗口
# 打开数据库
access.OpenCurrentDatabase(access_file)
all_forms = access.CurrentProject.AllForms
form_count = all_forms.Count
if form_count == 0:
messagebox.showinfo("完成", "数据库中没有窗体,无需替换。")
access.CloseCurrentDatabase()
access.Quit()
return
replaced = 0
for i in range(form_count):
form_name = all_forms.Item(i).Name
try:
access.DoCmd.OpenForm(form_name, 1) # acDesign = 1
form = access.Forms(form_name)
module = form.Module
line_count = module.CountOfLines
if line_count > 0:
module.DeleteLines(1, line_count)
if new_code.strip():
module.InsertLines(1, new_code)
access.DoCmd.Close(0, form_name, 1) # acForm=0, acSaveYes=1
replaced += 1
except Exception as e:
access.DoCmd.Close(0, form_name, 0) # 尝试关闭,避免卡住
print(f"处理窗体 {form_name} 时出错: {e}")
# 刷新所有链接表
refreshed_tables = 0
failed_tables = 0
try:
db = access.CurrentDb()
table_count = db.TableDefs.Count
for i in range(table_count):
table_def = db.TableDefs(i)
# 检查是否是链接表Connect属性不为空
if table_def.Connect:
try:
table_def.RefreshLink()
print(f"已刷新链接表: {table_def.Name}")
refreshed_tables += 1
except Exception as e:
print(f"刷新链接表 {table_def.Name} 失败: {e}")
failed_tables += 1
except Exception as e:
print(f"刷新链接表时出错: {e}")
access.CloseCurrentDatabase()
access.Quit()
# 构建结果消息
result_msg = f"操作完成!\n\n"
result_msg += f"已处理 {form_count} 个窗体,成功替换 {replaced} 个。\n"
if refreshed_tables > 0 or failed_tables > 0:
result_msg += f"已刷新 {refreshed_tables} 个链接表"
if failed_tables > 0:
result_msg += f"{failed_tables} 个失败"
result_msg += "\n"
result_msg += f"\n文件已保存: {os.path.basename(access_file)}"
messagebox.showinfo("成功", result_msg)
except Exception as e:
messagebox.showerror("运行错误", f"操作失败:\n{e}\n\n请检查是否已启用 VBA 项目访问信任。")
if __name__ == "__main__":
main()
# pyinstaller --onefile --noconsole --name "VBA代码批量替换" vbareplace.py