1

Excel 2010,Windows 7

我有一个很慢的UDF。它目前正在 4,500 个单元中使用,这可能是一个问题……但是如果 UDF 不能有效地使用几次以上会有什么好处?无论如何,表格计算只需不到 33 秒,结果不会“粘住”,所以如果我离开表格然后返回表格,单元格都是空白的,需要再次重新计算!这是UDF:

    Function SumEmployee(EmployeeName As String, ProgramCode As String, Optional bVolatile As Boolean) As Double
'Written tightly to keep execution as fast as possible. Search every sheet for the first instance of the given employee name and the first instance of
'the given program gl-code.  This will give a row-column (the intersection of the row & column) and the value in that cell location
'will be added up for each sheet in the workbook.  The final summed result is returned.
Dim lRow As Long, lCol As Long, wksSheet As Worksheet

Application.Volatile (bVolatile)  'http://msdn.microsoft.com/en-us/library/office/bb687891.aspx
SumEmployee = 0
For Each wksSheet In Worksheets
    With wksSheet
        If InStr(1, .Name, gTS_Sheet, vbTextCompare) > 0 And bVolatile Then  'Only pull from the TS Summary sheets when HS is visible
            On Error Resume Next  'Errors are part of the routine so this is purposeful
            lRow = .Range("A2:D100").Find(ProgramCode, , xlValues, xlWhole).Row
            lCol = .Range("C2:DA12").Find(EmployeeName, , xlValues, xlWhole).Column
            'If there were no errors then the items were found so sum new value otherwise skip and move to the next sheet
            If Err.Number = 0 Then
                SumEmployee = SumEmployee + .Cells(lRow, lCol).Value2  'No errors so get the value in the cell & add to the running total
            Else
                Err.Clear
            End If
            On Error GoTo 0  'Resume normal error handling
        End If
    End With
Next wksSheet
End Function

这是使用 UDF 的工作表的代码:

Option Explicit

Private Sub Worksheet_Activate()
'Sheet is active so allow the UDF to function.
    ActiveWorkbook.Names("IsVolatile").RefersToR1C1 = "=TRUE"
End Sub

Private Sub Worksheet_Deactivate()
'Leaving sheet so turn off UDF updating so rest of the wkbk won't lag.
    ActiveWorkbook.Names("IsVolatile").RefersToR1C1 = "=FALSE"
End Sub

这是 UDF 在单元格中的外观(请注意,前两个参数随着 UDF 放置在相邻单元格中而变化):

=SumEmployee(D$5,$A6,IsVolatile)

其中第一个参数是要搜索的员工姓名,第二个参数是要搜索的财务 GL 代码。第三个参数 IsVolatile 告诉函数只有在它所在的工作表可见时才运行(在我的应用程序的上下文中)。

UDF 在工作表“Master”中。其他表格是一个月的数据,顶部有员工姓名(每列一个员工姓名),左侧有 GL 代码(每行一个 GL 代码),因此形成了一个网格。行/列的交叉点是员工为该 GL 代码(特定程序)工作的小时数。UDF 会搜索员工和计划,因为它们可能每月都会发生变化,也就是说,新计划可能会在年中开始,因此它不会出现在较早的表格中。与员工一样,他们可以每月来来去去,因此 .Find 方法但我认为这可能是导致速度下降的原因——这就是为什么我使用指定范围的 ROUGHLY where 来搜索行或列而不是 .Find 。整个工作表的单元格。

  1. 有可能加快这个速度吗?
  2. 如何使结果“坚持”到下一次刷新?

谢谢你。

4

0 回答 0