[英]excel vba preserve original value if UDF formula fails
在單個單元格中,我有一個引用 UDF 的指定公式:
=getValueFromWorkbook("OtherWorkbook", 10)
getValueFromWorkbook
UDF 大致執行類似...
Function getValueFromWorkbook(workbookName As String, identifier As Integer) As Variant
' some magic is done to get the `worksheetName` and `cellRange`
' but for simplicity, we'll just stub them here...
Dim worksheetName As String: worksheetName = "SomeWorkSheet"
Dim cellRange As String: cellRange = "A1"
getValueFromWorkbook = Workbooks("" & workbookName & ".xlsx").Worksheets(worksheetName).Range(cellRange).Value
End Function
這很好用,只要OtherWorkbook.xlsx
是一個打開的工作簿,單元格就會獲得正確的值,世界就會快樂。
現在,如果我關閉OtherWorkbook.xlsx
工作簿,事情會繼續工作並且仍然反映單元格值。
但是,如果我刪除一行或執行一些其他操作導致 Excel 重新計算所有單元格值,UDF 將失敗(因為引用的工作簿不再打開),導致可怕的#VALUE!
.
理想情況下,我希望這樣可以保留原始(過時)值而不是返回錯誤,但我還沒有想出一種方法來做到這一點。
我試過的...
Function getValueFromWorkbook(...) As Variant
...
On Error Resume Next
getValueFromWorkbook = ...
If Err.Number <> 0 Then
Err.Clear
getValueFromWorkbook = Application.Caller.Value
End If
End Function
但這會導致循環引用錯誤:
公式中的單元格引用引用公式的結果,從而創建循環引用。
但是,如果我將Application.Caller.Value
更改為Application.Caller.Text
,這有點有效,但它以文本形式返回並且我丟失了原始值格式。
因此,長話短說,有沒有辦法保留原始鏈接值而不是返回垃圾#VALUE!
?
PS 我對 VBA 還很陌生,所以我在這里可能遺漏了一些明顯的東西。
您可以簡單地使用Application.Caller.Text
而不是Application.Caller.Value
來返回單元格的原始文本。 這樣做的一個缺點是單元格的值,無論類型如何,都將被轉換為字符串。 根據引用Application.Caller
單元格的其他單元格/公式(即,如果您希望“OtherWorkbook”返回數字而不是字符串),您可能必須使用=VALUE()
更新它們。
只要您不嘗試使用其中的值更新實際單元格,這就會起作用。 一旦你輸入一個單元格, Application.Caller
就會變成一個循環引用,你只會得到0
; 不過,您應該能夠刪除其他行。
Function getValueFromWorkbook(...) As Variant
Dim Org As String
Org = Application.Caller.Text
...
On Error Resume Next
getValueFromWorkbook = ...
If Err.Number <> 0 Then
Err.Clear
getValueFromWorkbook = Org
End If
End Function
這樣的事情怎么樣:
' Globally available variable to cache the external value.
Public GlobalValue As Variant
Function getValueFromWorkbook(workbookName As String, identifier As Integer) As Variant
' some magic is done to get the `worksheetName` and `cellRange`
' but for simplicity, we'll just stub them here...
Dim worksheetName As String: worksheetName = "SomeWorkSheet"
Dim cellRange As String: cellRange = "A1"
Dim returnValue As Variant
' Attempt to get from the external sheet.
' This will fail if it isn't available.
On Error Resume Next
returnValue = Workbooks(workbookName & ".xlsx").Worksheets(worksheetName).Range(cellRange).Value
If Err = 0 Then
' No error, we retrieved the value from the external file.
' Set it locally for use when this value isn't available.
GlobalValue = returnValue
Else
' Error - the external sheet wasn't available.
' Use the local value.
returnValue = GlobalValue
End If
' Done with error trapping.
On Error GoTo 0
getValueFromWorkbook = returnValue
End Function
這個想法是您在本地緩存該值,並可以在您的workbookName
不可用時將其用作后備。
我找到了一種方法:
假設您將用戶定義的函數UDF放入單元格A1 中,並且在某些條件下希望它保留以前的值而不重新計算。 然后在這種情況下使此函數返回任何錯誤值: UDF = CVErr(xlErrNull)
並按以下方式修改您的A1公式: =IFERROR(UDF(...); A1)
這可能會產生循環引用警告 - 您可以通過在文件 -> 選項 -> 公式中啟用循環引用並使用此設置保存文件來擺脫它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.