[英]Excel VBA Load worksheet in Function
我正在嘗試編寫一個函數來查找外部工作表的第一行。 我可以使用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的回報。 我認為這是因為加載工作簿時出錯。
請指教,謝謝。
沒錯,用戶定義函數的執行有一定的局限性。 在UDF中執行您想要的操作並且不違反訂單的技巧很少。
1.通過后期綁定獲取另一個Excel.Application實例,使用它打開工作簿,通過引用實例執行所有必要的計算。 完全引用創建的實例是至關重要的,因此有些嵌套的With ... End With
語句或其他語法,例如在.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
如果從單元格調用UDF ,則它只能向該單元格返回值。 它無法打開另一個工作簿
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.