功能中的Excel VBA加载工作表

时间:2014-04-22 17:43:57

标签: excel vba excel-vba

我正在尝试编写一个函数来查找外部工作表的第一行。我可以使用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的回报。我认为这是因为加载工作簿时出错。

请建议并谢谢。

2 个答案:

答案 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 ,则只能向该单元格返回值。它无法打开另一个工作簿