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在表格#34; Master"中。其他工作表是一个月的数据,其顶部有员工姓名(每列一个员工姓名),左侧是GL代码(每行一个GL代码),因此形成一个网格。行/列的交叉点是员工为该GL代码(特定程序)工作的小时数。 UDF会搜索员工和程序,因为它们可能每月都有变化,也就是说,新程序可能会在年中开始,因此它不会出现在早期的工作表中。与员工一样,他们可以每月来来往往,因此.Find方法,但这可能是什么杀死速度 - 这就是为什么我使用指定范围的粗略搜索行或整个工作表的列而不是.Cells。
谢谢。