在单个单元格中,我有一个引用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!
?
P.S。我对VBA很陌生,所以我可能会在这里找到一些显而易见的东西。
答案 0 :(得分:0)
您只需使用Application.Caller.Text
而非Application.Caller.Value
即可返回单元格的原始文本。这样做的一个缺点是,无论 type ,单元格的值都将被转换为字符串。根据其他单元格/公式(即,如果您希望&#34; OtherWorkbook&#34;返回数字而不是字符串)引用Application.Caller
单元格,您可能需要更新它们使用=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
答案 1 :(得分:0)
这样的事情怎么样:
' 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
不可用时的后备。
答案 2 :(得分:0)
我找到了一种方法:
假设您将用户定义函数 UDF 放入单元格 A1 中,并且在某些情况下希望它保留先前的值而无需重新计算。然后,在这种情况下,使此函数返回任何错误值:UDF = CVErr(xlErrNull)
并按以下方式修改您的 A1 公式:=IFERROR(UDF(...); A1)
这可能会产生循环引用的警告-您可以通过在文件->选项->公式中启用循环引用并使用此设置保存文件来摆脱它。