【发布时间】:2014-12-11 19:46:46
【问题描述】:
在单个单元格中,我有一个引用 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!?
附:我对 VBA 很陌生,所以我可能在这里遗漏了一些明显的东西。
【问题讨论】:
-
为什么不直接将
getValueFromWorkbook("OtherWorkbook", 10)的结果复制到当前工作簿的某个单元格中,然后以此为基础进行计算?这样你就知道价值永远存在。每次成功调用此 UDF 时,将值更新到“本地”单元格中。现在当OtherWorkbook.xlsx不可用时,您可以回退到本地单元格。 -
添加到 Jasons 的建议中,您可以将函数包装在 iferror 语句中,并将 otherworkbook 函数作为“值”部分调用,并将复制的数据(如 Jason 所建议)用作“If error “ 部分。因此,如果其他工作簿可用,您将获得最新的值,但如果没有,您将获得从中读取的最后一个值
-
Application.Caller.Value 将始终返回循环引用,因为您将单元格传递给自身。你想向用户展示什么价值?我只需在“If Err.Number 0 Then”语句中添加一条消息,说明
getValueFromWorkbook = "Workbook not open"或其他提示,让用户知道工作簿未打开。 -
没关系,我明白你现在在说什么了。
-
@PJRosenburg - 我会的,但我没有时间(当时)为答案做一个“适当的”写作。我现在就打一个。
标签: vba excel excel-formula