我正在尝试编写一个函数来查找外部工作表的第一行。我可以使用sub执行此操作,但它不能用作函数。可以做到吗。
目前我正在使用
Function GetLine(fileName As String) As Boolean
GetLine = 0
Dim loadBook As Workbook
If loadBook = Application.Workbooks.Open(fileName) Then
GetLine = True
Else
GetLine = False
End If
end function
我收到了#value的回报。我认为这是因为加载工作簿时出错。
请建议并谢谢。
答案 0 :(得分:3)
这是正确的,用户定义函数的执行具有一定的局限性。在UDF中执行您想要的操作并且不违反订单的技巧很少。
的 1。通过后期绑定获取另一个Excel.Application实例,打开它的工作簿,通过引用实例执行所有必要的计算。完全引用创建的实例至关重要,以便一些嵌套的With ... End With
语句或其他语法e。 G。在.Cells()
之前,.Sheets()
似乎不寻常。有一个UDF示例如何从已关闭的文件中获取工作表上的第一行:
Function GetFirstRowLbind(FileName, SheetName) ' UDF function that calculates value, works with certain limitations
On Error Resume Next
With CreateObject("Excel.Application") ' late binding
.Workbooks.Open (FileName)
GetFirstRowLbind = .Sheets(SheetName).UsedRange.Row
.Quit
End With
End Function
OERN
仅用于跳过缺少文件和其他错误的错误,以便确保执行.Quit
语句以防止内存泄漏,否则启动excel进程将在每个表单recalc和UDF调用后保留在内存中。
的 2。实现一些UDF扩展,通过调度到另一个过程,在UDF完成后应该执行的操作,并根据工作表recalc事件执行。这种方式更复杂,难以调试,但更灵活,它提供了在UDF内部进行更多操作的机会,例如更改相邻单元,甚至整个应用程序中的任何可访问数据。安排示例:
将代码放置到VBAProject的一个模块中:
Public Tasks, Permit, Transfer
Function GetFirstRowSched(FileName, SheetName) ' UDF function, schedules filling this UDF cell with a value after all UDFs to be completed
If IsEmpty(Tasks) Then TasksInit
If Permit Then Tasks.Add Application.Caller, Array(FileName, SheetName) ' pack arguments to array, the dictionary key is actually this cell object
GetFirstRowSched = Transfer
End Function
Sub TasksInit() ' function for initial setting values
Set Tasks = CreateObject("Scripting.Dictionary")
Transfer = ""
Permit = True
End Sub
Function GetFirstRowConv(FileName, SheetName) ' function that actually calculates the value, runs without UDF limitations like an usual function
With Application.Workbooks.Open(FileName)
GetFirstRowConv = .Sheets(SheetName).UsedRange.Row
.Close
End With
End Function
将代码放在VBAProject中的Microsoft Excel对象的ThisWorkbook部分:
Private Sub Workbook_SheetCalculate(ByVal Sh As Object) ' sheets recalc event that perform all scheduled calls, puts data to each of UDFs cells
Dim Task, TempFormula
If IsEmpty(Tasks) Then TasksInit
Application.EnableEvents = False
Permit = False
For Each Task In Tasks ' cycle trough all stored cell objects
TempFormula = Task.FormulaR1C1
Transfer = GetFirstRowConv(Tasks(Task)(0), Tasks(Task)(1)) ' unpack arguments from array to perform calculations
Task.FormulaR1C1 = TempFormula
Tasks.Remove Task
Next
Application.EnableEvents = True
Transfer = ""
Permit = True
End Sub
答案 1 :(得分:0)
如果从单元格调用 UDF ,则只能向该单元格返回值。它无法打开另一个工作簿