vba sleep,read and write text file utf8

本文介绍了如何使用VBA中的SLEEPfunction和SubSleepLib,以及创建两个函数replace_str_file和replace_str_file_sjis来处理UTF-8编码的文本文件,包括删除BOM、替换字符串和处理LF/CRLF换行符。还讨论了在Linux中所需的文件格式和SakuraEditor设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SLEEP function

 Option Explicit
 Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub sleepp(Optional time_tmp As Long = 1000)
    Sleep time_tmp ' Pause for 1 second (1000 milliseconds)
End Sub

[Open path1 For Input As #1] can only write save file in sjis

CreateObject(“ADODB.Stream”) can save file in sjis/utf8/utf8bom

logic of function replace_str_file:

  1. open file in utf8
  2. set position 0,read content to buffer
  3. reopen the file, otherwise u cannot write
  4. edit content,then write the file,contents of the file will all delete before writing
  5. if the file has bom, remove the comment from ここから to ここまで ,it will remove bom
'sjis or utf8
Function replace_str_file(ByVal path1, ByVal find As String, ByVal replace_str As String)
    Dim buffer As String, stream_tmp
    Set stream_tmp = CreateObject("ADODB.Stream")
    With stream_tmp
     
         ' ストリームの文字コードをUTF8に設定する
         .Charset = "UTF-8"
         ' ファイルのタイプ(1:バイナリ 2:テキスト)
         .Type = 2
         ' ストリームを開く
         .Open
         ' ストリームにファイルを読み込む
         .LoadFromFile (path1)
         
         .Position = 0
         ' ファイルの中身をbufferへ代入
         buffer = .ReadText
         ' ストリームを閉じる
         .Close
        .Open
        buffer = replace(buffer, find, replace_str)
        ' ストリームの保存形式をテキスト形式にする
        .WriteText buffer
        
                ' ---------- ここから ----------
    
            ' タイプをバイナリにして、先頭の3バイトをスキップ
            .Position = 0
            .Type = 1 ' タイプ変更するにはPosition = 0である必要がある
            .Position = 3
            ' 一時格納用
            Dim p_byteData() As Byte
            p_byteData = .Read
            .Close ' 一旦閉じて
            .Open ' 再度開いて
            .Write p_byteData ' ストリームに書き込む
    
            ' ---------- ここまで を追加 ----------
            
        ' ストリームに名前を付けて保存する(1は新規作成 2は上書き保存)
        .SaveToFile (path1), 2
         
         .Close
     End With
     Set stream_tmp = Nothing
End Function
'sjis
Function replace_str_file_sjis(ByVal path1, ByVal find As String, ByVal replace_str As String)
    Dim text, text_line As String
    Open path1 For Input As #1
    Do While Not EOF(1)
        Line Input #1, text_line
        If text = "" Then
            text = text_line
        Else
            text = text & vbLf & text_line
        End If
    Loop
    Close #1
    text = replace(text, find, replace_str)
    text = replace(text, ChrW(&HFEFF), "")
    Open path1 For Output As #1
    Print #1, text
    Close #1
End Function

how to save text file in utf8 and by LF

if using sakura editor,ctrl+shifl+s,set as below
在这里插入图片描述

what file format is needed in linux

  • LF+UTF8 is ok
  • if CRLF ,it will raise error if u executethe file(ep. . TT.sh)
  • if sjis,it will output 文字化け,but can be executed
在UI界面顶部生成菜单栏选项:一级目录<Excel文件处理>,点击该目录生成二级目录<宏模块加载分析>、二级目录<文件合并统计分析>。点击二级目录<宏模块加载分析>时加载出如下UI界面:import tkinter as tk from tkinter import ttk, filedialog, messagebox import os import win32com.client as win32 import time from datetime import datetime import threading import re class VBAExecutorApp: def __init__(self, root): self.root = root self.root.title("WPS Excel宏执行器") self.root.geometry("600x280") self.root.resizable(True, True) self.style = ttk.Style() # 配置按钮样式 self.style.configure("Run.TButton", foreground="white", background="#4CAF50", font=("Arial", 10, "bold"), padding=6) self.style.map("Run.TButton", foreground=[('disabled', 'gray')], background=[('disabled', '#CCCCCC')]) # 创建网格布局 self.root.columnconfigure((0, 1, 2), weight=1) self.root.rowconfigure((0, 1, 2), weight=1) # 第一行标题 self.create_label("日志文件选择:", 0, 0, "黑体", 12) self.create_label("分析模块选择:", 0, 1, "黑体", 12) self.create_label("宏主程序读取:", 0, 2, "黑体", 12) # 第二行文件选择 self.excel_path = tk.StringVar() self.bas_path = tk.StringVar() self.create_file_entry(1, 0, self.excel_path, [("Excel文件", "*.xls *.xlsx")]) self.create_file_entry(1, 1, self.bas_path, [("BAS文件", "*.bas")]) # 宏函数下拉框 self.macro_var = tk.StringVar() self.macro_combobox = ttk.Combobox( self.root, textvariable=self.macro_var, state="readonly", height=8 ) self.macro_combobox.grid(row=1, column=2, padx=5, pady=2, sticky="ew") # 第三行按钮 self.run_button = ttk.Button( self.root, text="执行宏命令分析", command=self.start_execution, width=23, style="Run.TButton" ) self.run_button.grid(row=2, column=0, padx=5, pady=(7, 8), sticky="ew") # 添加悬停效果绑定 self.run_button.bind("<Enter>", self.on_enter) self.run_button.bind("<Leave>", self.on_leave) self.run_button.bind("<ButtonPress-1>", self.on_press) self.run_button.bind("<ButtonRelease-1>", self.on_release) # 进度条容器 progress_container = ttk.Frame(self.root) progress_container.grid(row=2, column=1, columnspan=2, padx=5, pady=0, sticky="ew") progress_container.columnconfigure(0, weight=1) progress_container.columnconfigure(1, weight=0) # 进度条 self.progress_var = tk.DoubleVar() self.progress_bar = ttk.Progressbar( progress_container, variable=self.progress_var, maximum=100, mode="determinate", length=200 ) self.progress_bar.grid(row=0, column=0,ipadx=30,ipady=7,padx=(0, 0), sticky="ew") # 百分比标签 self.percent_label = ttk.Label( progress_container, text="0%", font=("Arial", 12), width=5 ) self.percent_label.grid(row=0, column=1, ipadx=2,ipady=7,padx=(10, 0),sticky="e") # 绑定事件 self.bas_path.trace_add("write", self.parse_bas_file) self.progress_var.trace_add("write", self.update_percent_label) def update_percent_label(self, *args): """更新百分比标签显示""" progress_value = self.progress_var.get() self.percent_label.config(text=f"{int(progress_value)}%") # 根据进度改变标签颜色 if progress_value < 30: self.percent_label.config(foreground="red") elif progress_value < 70: self.percent_label.config(foreground="orange") else: self.percent_label.config(foreground="green") # 关键修改:当进度达到100%时重新启用按钮 if progress_value == 100: self.run_button.config(state=tk.NORMAL) def create_label(self, text, row, column, font, size): label = tk.Label( self.root, text=text, font=(font, size), anchor="w" ) label.grid(row=row, column=column, padx=0, pady=(25, 0), sticky="w") return label def create_file_entry(self, row, column, text_var, filetypes): frame = ttk.Frame(self.root) frame.grid(row=row, column=column, padx=5, pady=2, sticky="ew") frame.columnconfigure(1, weight=1) entry = ttk.Entry(frame, textvariable=text_var) entry.grid(row=0, column=0, sticky="ew", padx=(0, 2)) browse = ttk.Button(frame, text="浏览", command=lambda: self.browse_file(text_var, filetypes)) browse.grid(row=0, column=1, padx=(0, 0)) def browse_file(self, text_var, filetypes): file_path = filedialog.askopenfilename(filetypes=filetypes) if file_path: text_var.set(file_path) def parse_bas_file(self, *args): bas_path = self.bas_path.get() if not bas_path or not os.path.exists(bas_path): return try: # 尝试使用UTF-8和GBK解码 try: with open(bas_path, "r", encoding="utf-8") as f: content = f.read() except UnicodeDecodeError: with open(bas_path, "r", encoding="gbk") as f: content = f.read() # 查找Main_开头的宏函数 macro_pattern = r"Sub\s+(Main_\w+)\s*\(\)" macros = re.findall(macro_pattern, content) if macros: self.macro_combobox["values"] = macros if self.macro_combobox["values"]: self.macro_combobox.current(0) except Exception as e: messagebox.showerror("错误", f"解析BAS文件失败: {str(e)}") def start_execution(self): """关键修改:点击后立即禁用按钮""" if not self.excel_path.get() or not self.bas_path.get(): messagebox.showerror("错误", "请先选择需要分析的文件或宏模块") return # 禁用按钮防止重复点击 self.run_button.config(state=tk.DISABLED) self.progress_var.set(0) # 重置进度条 # 在后台线程中执行宏 threading.Thread(target=self.execute_macro, daemon=True).start() def on_enter(self, event): self.style.configure("Run.TButton", background="#45a049") def on_leave(self, event): self.style.configure("Run.TButton", background="#4CAF50") def on_press(self, event): self.style.configure("Run.TButton", background="#2E7D32") def on_release(self, event): self.style.configure("Run.TButton", background="#45a049") def execute_macro(self): try: # 初始化WPS Excel excel = win32.gencache.EnsureDispatch("Excel.Application") excel.Visible = False excel.DisplayAlerts = False # 打开Excel文件 wb = excel.Workbooks.Open(os.path.abspath(self.excel_path.get())) self.update_progress(20) # 导入BAS文件 vb_project = wb.VBProject vb_project.VBComponents.Import(os.path.abspath(self.bas_path.get())) self.update_progress(40) # 执行宏 macro_name = self.macro_var.get() excel.Application.Run(macro_name) self.update_progress(70) time.sleep(1) # 模拟执行时间 # 另存为新文件 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") save_path = filedialog.asksaveasfilename( defaultextension=".xlsx", filetypes=[("Excel文件", "*.xlsx"), ("Excel 97-2003", "*.xls")], initialfile=f"{self.macro_combobox["values"]}{timestamp}" ) if save_path: wb.SaveAs(save_path) self.update_progress(90) messagebox.showinfo("成功", f"文件已保存至: {save_path}") wb.Close(False) excel.Quit() self.update_progress(100) # 关键点:设置进度为100% except Exception as e: messagebox.showerror("执行错误", f"宏执行失败: {str(e)}") self.update_progress(100) # 出错时也设置进度为100% finally: # 确保进度达到100%(update_progress(100)会启用按钮) if self.progress_var.get() < 100: self.update_progress(100) def update_progress(self, value): """更新进度条值(线程安全)""" # 使用after确保在主线程更新UI self.root.after(0, lambda: self.progress_var.set(value)) self.root.update_idletasks() if __name__ == "__main__": root = tk.Tk() app = VBAExecutorApp(root) root.mainloop()
最新发布
07-24
编程语言:Python 运行环境:Pycharm 解释器版本:Python 3.13 程序设计:基于Python的Tkinter技术编写一个分辨率"600x300"UI界面程序。 该程序可针对WPS的Excel文件进行VBA宏模块(*.bas)文件进行添加并执行指定宏函数等操作,具体功能设计如下: 第一:程序UI界面布局设计如下: 1.进行网格布局三行三列。 2.第一行第一列网格A为标题:“日志文件选择:”,字体:黑体12; 第一行第二列网格B为标题:“分析模块选择:”,字体:黑体12; 第一行第三列网格C为标题:“宏主程序读取:”,字体:黑体12。 3.第二行第一列网格D为文本选择框,可选择本地(*.xls)和(*.xlsx)后缀的Excel文件; 第二行第二列网格E为文本选择框,可选择本地(*.bas)VBA宏模块文件; 第二行第三列网格F将网格E文本选择框中选择的(*.bas)VBA宏模块文件中解析宏函数并将格式"Main_*()"函数名称赋值到网格F下拉选项框中,同时注意函数名称为中英文混合,使其中文字符正常显示,防止中文字符显示乱码现象。 4.第三行第一列网格G为一个可点击按钮键,标题为"执行宏命令分析"; 第三行第二列与第三列合并居中为网格H,显示为一个"宏命令程序处理进程进度条"。 5.网格布局:每列网格左对齐,每行网格相同行间隔对齐;网格布局自适应不同分辨率; 第二:程序可执行功能设计如下: 1.点击执行网格G"执行宏命令分析"按钮键后:往网格D手动选择的WPS Excel文件添加网格E手动选择的VBA宏模块文件,解析宏函数并执行由网格F选择的该VBA宏模块文件中的宏函数。同时网格H显示<从点击网格G开始到执行完网格F选择的VBA宏模块文件中的宏函数为止>这一完整过程的进度条显示动画并显示百分比进度。 2.若网格D或网格E二者其中有一个未在文本选择框中选择文件,在点击执行网格G"执行宏命令分析"时则弹出错误提示框"请先选择需要分析的文件或宏模块"; 3.等待网格H进度条动画显示完毕100%即网格F选择的宏函数运行完后,另存生成一个Excel新文件同时弹出一个文本浏览框,可手动选择该Excel新文件保存的路径位置和文件名。该文件生成后自动在其文件名后缀加上当前生成时间戳。
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值