【问题标题】:Logging strategies with 'Open myFile For Append' (VBA Excel)使用“打开 myFile 进行追加”(VBA Excel)的日志记录策略
【发布时间】:2017-08-31 16:40:49
【问题描述】:

我需要记录在 Excel 中运行的 VBA 宏的操作(100 个子程序和函数,10 个主子程序)。我已经在使用“工作流”表作为用户可读的非常轻量级的日志(主子)。

但我想记录Debug.Print 当前在即时窗口中打印的内容,因为它是更全面的日志,所以可以生成很多内容。因此,我正在考虑类似:

Open "C:\Temp\Log.txt" For Append As #1
Print #1, "This need to be logged"
Close #1

我应该如何使用OpenClose 命令?

根据需要打开/追加/关闭每一行

类似:

Public Sub Log_to_file(byval message as string)
    log_file_nb = FreeFile 
    Open "C:\Temp\Log.txt" For Append As #log_file_nb
    Print #log_file_nb, message
    Close #log_file_nb
End Sub

Log_to_file ("This need to be logged")

实现起来要简单得多,但我担心打开/关闭文件 1000 次的性能。

在 Main sub 的开头打开/根据需要附加/在 Main sub 的末尾关闭

类似:

Public Const log_file_nb = 1

Public Sub Open_log_file(byval log_file_nb)
    Open "C:\Temp\Log myMacro.txt" For Append As #log_file_nb
End Sub

Public Sub Log_to_file(byval message as string)
    Print #log_file_nb, message
End Sub

Public Sub Close_log_file()
    Close #log_file_nb
End Sub

Log_to_file ("This need to be logged")
  • 在尝试登录之前如何检查文件是否已打开? (有些子可以直接通过按钮启动,也可以通过主子递归启动)

  • 我可以Open For Output 第二个文件(我的宏也需要将数据输出到 csv 文件)而文件 n°1 仍处于打开状态吗?

  • 保持文件打开是否会对内存产生很大影响(假设文件中有 100 000 行)?

【问题讨论】:

  • 对于第一种方法 - 您可以在 Log_to_file 内的静态变量中缓冲行 - 当您累积了一定数量的行时,然后将它们写出并清除缓冲区。对于第二种方法:使用全局布尔值来指示文件是否打开 - 在写入文件之前检查它,如果尚未打开则打开文件。
  • 如果您打开一个文件进行附加,我认为它不会加载整个文件 - 它会寻找到文件末尾并写入新内容。
  • 正如 Rich 所提到的,我正在使用日志进行调试,所以我宁愿不缓冲 Append。我还用 100 000 * Open/Append/Close 进行了测试;需要 18 秒。这比执行 100 000* Append(只有 1 个打开和 1 个关闭)要糟糕得多,这需要 1 秒。但我会说它对我来说足够高效,所以我不必管理关闭文件(如果宏失败,这可能会失败)。

标签: vba excel logging append


【解决方案1】:

一次打开​​多个文件没有问题。只要确保您的文件编号不同,不要混淆它们。

您的第一种方法,打开文件,追加文件,并在每次调用 log_to_file 时关闭可能是一种有用的方法,特别是如果您担心程序崩溃或外部终止时会丢失日志数据。如果您确实按照 Tim Williams 的建议缓冲了输出,那么在崩溃/终止时您将丢失缓冲区中的内容。

会有一些性能成本,但多少取决于许多因素,例如计算机系统的配置、日志文件所在的驱动器类型等。可能值得尝试看看是哪种类型受到的性能影响。 (一个测试胜过一千个专家意见......)

另一种方法,即在开始时打开日志文件并在结束时关闭它也是一个好方法。正如 Tim 建议的那样,只需创建一个全局布尔变量,例如 logfileOpened,然后在 log_to_file 子文件中添加一个检查。

Public Const log_file_nb = 1
private log_file_open as boolean

Public Sub Open_log_file(byval log_file_nb)
    Open "C:\Temp\Log myMacro.txt" For Append As #log_file_nb
    log_file_open = True
End Sub

Public Sub Log_to_file(byval message as string)
    if not log_file_open then Open_log_file log_file_nb
    Print #log_file_nb, message
End Sub

Public Sub Close_log_file()
    Close #log_file_nb
    log_file_open = False
End Sub

这留下悬而未决的细节是需要在某个时候关闭日志文件。通过将 log_file_open 设置为 false 作为 Close_log_file 子的一部分,您可以在运行程序的过程中多次执行此操作。但在所有 Log_to_file 调用之后,您至少需要执行一次。

最后一点:始终以附加模式打开日志文件,每次运行程序时文件都会增长。根据具体情况,这可能是可以接受的,或者您可能必须包含一些代码以防止日志文件变得庞大。一些可能的解决方案:

  1. 根据日期为日志文件命名。这会产生许多较小的日志文件。您还可以删除日期太旧的日志文件,以检查总数。
  2. 一旦文件变得太大,编写代码删除文件中最旧(最上面)的行。这是非常可能的,但并非微不足道。
  3. 在程序的特定运行期间第一次打开日志文件时,请先删除现有的日志文件。您最终会得到一个日志文件,其中仅包含上次程序运行的日志记录。

【讨论】:

  • 我测试了 100 000 * Open/Append/Close ;需要 18 秒。这比执行 100 000* Append(只有 1 个打开和 1 个关闭)要糟糕得多,后者需要 1 秒。但我会说它对我来说足够高效,所以我不必管理关闭文件(如果宏失败,这可能会失败)。
  • 关于日志文件增长的要点。我确实在使用日志中的日期并在必要时删除旧日志。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-10
  • 1970-01-01
相关资源
最近更新 更多