简体   繁体   English

记录宏所做的更改的最快方法

[英]Quickest way to note changes that macro makes

Some background: 一些背景:

I have an Excel Add-In that executes 17 Sub Routines and was wondering what would be the easiest, most efficient, and fastest way to 我有一个执行17个子例程的Excel加载项,想知道什么是最简单,最有效和最快的方法

  1. Record specific changes made by the macro 记录宏所做的特定更改
  2. Display a list of all the changes (in a new spreadsheet) and why it changed (or flagged/highlighted) each cell 显示所有更改的列表(在新的电子表格中)以及更改(或标记/突出显示)每个单元格的原因
  3. Provide the cell address of each error as a clickable link that will take the user to the specific cell in another worksheet (in the same workbook) 提供每个错误的单元格地址作为可单击的链接,它将带用户到另一个工作表(在同一工作簿中)中的特定单元格

What I've gathered thus far: 到目前为止,我已经收集了以下内容:

I've read up on a few methods of how to accomplish this, most notably from here , here , here , and most importantly here . 我已经阅读了一些有关如何完成此操作的方法,尤其是从这里这里这里 ,最重要的是这里 These suggest methods such as 这些建议方法如

  • Dumping the UsedRange into an array prior to running through all the subs, then dumping the UsedRange into a second array after all the subs have completed. UsedRange所有子程序之前,将UsedRange转储到数组中,然后在完成所有子程序后,将UsedRange到另一个数组中。 Compare the two arrays and find the differences that way. 比较两个数组,并以这种方式找到差异。
  • Utilizing the worksheet_change event to log the changes. 利用worksheet_change事件记录更改。
  • The last link for the Marktastic site provides the most convincing method, combining the previous two methods. Marktastic网站的最后一个链接提供了最令人信服的方法,将前两种方法结合在一起。 However, even with his method of checking the array each time the worksheet_change event fires takes .06 seconds, which seems like it will add up to a lot of overhead. 但是,即使使用了每次worksheet_change事件触发时都要检查数组的方法,也要花费0.06秒,这似乎会增加很多开销。

A few particular issues I face include: 我面临的一些特殊问题包括:

  • Dealing with large files (15000+ rows, 150 columns) 处理大文件(超过15000行,150列)
  • Some of my subs make changes that don't need to be noted, such as only rearranging values in certain cells, not changing them otherwise 我的一些潜艇进行了不需要记录的更改,例如仅重新排列某些单元格中的值,否则不进行更改
  • My macro is built to work fast (<1 minute) and complete it's scan of our large files, so I imagine this would eliminate using the Worksheet_Change event and also writing immediately to the separate worksheet after each error is addressed accordingly. 我的宏被构建为可以快速运行(<1分钟)并完成对大文件的扫描,因此我想这将消除使用Worksheet_Change事件,并在相应解决每个错误之后立即将其写入单独的工作表。 Even utilizing both methods in one as Mark suggests seems like it'll cause too much lagtime. 就像Mark所说的那样,即使同时使用这两种方法,似乎也会导致过多的延迟时间。
  • Comparing two arrays appears it would also be quite slow for files as large as I'm working with, as it would mean iterating through 15000 (rows) x 150 (columns) = 2,250,000 cells 比较两个数组似乎对我正在处理的文件来说也很慢,因为这意味着要遍历15000(行)x 150(列)= 2,250,000个单元
  • Since I"m making all the changes via a macro the worksheet_change event won't fire. 由于我是通过宏进行所有更改,因此不会触发worksheet_change事件。

So, that basically eliminates all of the options I've come across. 因此,这基本上消除了我遇到的所有选项。 The only other option I can think of is just have one array, use it to record the cell/location and the error in the location as the code is executing and then dump the entire array into the new sheet after the subs complete. 我唯一想到的另一个选择是只有一个数组,使用它记录代码执行时的单元格/位置和位置中的错误,然后在完成subs之后将整个数组转储到新工作表中。 Would this really be my best option though? 这真的是我最好的选择吗?

So, given all of the facts and research above 因此,鉴于以上所有事实和研究

Now, for my question: 现在,我的问题是:

  • What would be the most efficient way in my situation to record changes and show what (necessary-to-note) changes have been made to the file after my macro has completed? 在我的情况下,最有效的方式是记录更改并显示在宏完成后对文件进行了哪些更改(需要记录)? Whether I've listed it or not, feel free to share a method you feel would best suit this situation. 无论我是否列出了它,请随时分享您认为最适合这种情况的方法。
  • Can you provide a simple sample code of how to implement your suggested method? 您能否提供一个简单的示例代码来说明如何实现建议的方法?

Here's what I've decided to go with. 这就是我决定去的地方。 Using this method I call a sub each time I want to note a change and pass the necessary variables that I need recorded. 使用此方法时,每次要记录更改并传递需要记录的必要变量时,我都会调用一个sub。 In this case, Cell , Reason , Status . 在这种情况下, CellReasonStatus Then the sub that has been called stores it at the end of a public Array , in this case ChangeLog . 然后,被调用的子项将其存储在公共Array (在本例中为ChangeLog的末尾。 After I am finished recording all of the changes I need I call the PrintLog sub to spit out the list of changes onto a new sheet, which I rename Change Log . 记录完所有更改后,我需要调用PrintLogPrintLog ,将更改列表吐出到新工作表上,然后将其重命名为Change Log A neat addition I added was the pre-made HYPERLINK formulas I produce while storing the values inside the array. 我添加的一个巧妙添加是在将值存储在数组中时生成的预制HYPERLINK公式。 Once the array is pasted to the worksheet the cell references are already clickable links that bring the user to the address on the other worksheet. 将数组粘贴到工作表后,单元格引用已经是可单击的链接,可将用户带到另一个工作表上的地址。

Public ChangeLog() As String

Sub Test()
    Log ActiveSheet.Range("A2"), "Test1", "Changed"
    Log ActiveSheet.Range("B2"), "Test2", "Needs Attention"
    Log ActiveSheet.Range("C2"), "Test3", "Changed"
    PrintLog
End Sub

Sub Log(Cell As Range, Reason As String, Optional Status As String)
    On Error Resume Next
    If (Not Not ChangeLog) = 0 Then
        ReDim ChangeLog(0 To 2, 0 To 1)
        ChangeLog(0, 0) = "Cells": ChangeLog(1, 0) = "Changes Made": ChangeLog(2, 0) = "Status"
        ChangeLog(0, 1) = "=Hyperlink(" & """#'" & ActiveSheet.Name & "'!" & Cell.Address(False, False) & """,""" & Cell.Address(False, False) & """)"
        ChangeLog(1, 1) = Reason
        ChangeLog(2, 1) = Status
    Else
        ReDim Preserve ChangeLog(0 To 2, 0 To UBound(ChangeLog, 2) + 1)
        ChangeLog(0, UBound(ChangeLog, 2)) = "=Hyperlink(" & """#'" & ActiveSheet.Name & "'!" & Cell.Address(False, False) & """,""" & Cell.Address(False, False) & """)"
        ChangeLog(1, UBound(ChangeLog, 2)) = Reason
        ChangeLog(2, UBound(ChangeLog, 2)) = Status
    End If
    On Error GoTo 0
End Sub

Sub PrintLog()
    Dim currentSheet As Integer: currentSheet = ActiveSheet.Index
    For s = 1 To ActiveWorkbook.Worksheets.Count
        If Worksheets(s).Name = "Change Log" Then
            Application.DisplayAlerts = False
            Worksheets(s).Delete
            Application.DisplayAlerts = True
            Exit For
        End If
    Next
    Dim WS As Worksheet: Set WS = Sheets.Add(After:=Worksheets(ActiveSheet.Index))
    WS.Name = "Change Log"
    WS.Tab.Color = vbYellow
    WS.Range("A1").Resize(UBound(ChangeLog, 2) + 1, 3) = WorksheetFunction.Transpose(ChangeLog)
    Erase ChangeLog
    Worksheets(currentSheet).Activate
End Sub

Change Log Sheet Preview: 更改日志表预览:
变更记录

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM