最后一个问题:ExcelDNA throwing exception accessing Range.Value2
我将Value2引发COMException的原因归咎于ExcelDNA。但是我不确定情况是否会如此。
我禁用了IsMacroType标志,该标志完全阻止了COMException的发生,并注意到有时Range.Value2根本不会引发异常。
因此有时它起作用,有时却不起作用。我的问题是,什么会导致range.Value2引发间歇性的COMException?
这很烦人,因为stacktrace没有提供有用的信息,而IsMacroType完全解决了该问题。
我的怀疑是,如果某个单元格不断变化,则在访问Value2时,该单元格可能会失效,但这只是一个猜测,我不确定excel的工作方式。
但是,这也没有意义,因为代码中没有多个线程。
您遇到了这个问题吗?
这是代码:
var valueCell = (Range)row.Cells[1, 30];
if (valueCell .Value2 != null)
{
//do something
}
严重的是,Value2无法对if语句求值
答案 0 :(得分:1)
我很惊讶,如果没有IsMacroType=true
,它是否可以工作。这可能取决于是否已计算出单元格。
Excel通常会阻止UDF读取工作表的其他部分,除非UDF被注册为“等效的宏工作表”(在注册字符串中带有#)。
注册为“等效宏”的功能具有以下行为(请参见the documentation from xlfRegister的底部):
在pxTypeText中的最后一个参数代码后放置#字符,使该函数具有与宏工作表上的函数相同的调用权限。如下:
该函数可以检索在此重新计算循环中尚未计算的单元格的值。
该函数可以调用任何XLM信息(第2类)函数,例如xlfGetCell。
如果不存在数字符号(#):计算未计算的单元格将导致xlretUncalced错误,并且一旦计算出该单元格,便会再次调用当前函数;否则,将返回当前函数。调用xlfCaller以外的任何XLM信息函数都会导致xlretInvXlfn错误。
在没有IsMacroType=true
的情况下,您的错误可能是其中的最后一个-您正在读取未计算的单元格,因此会出现错误。
为UDF设置IsMacroType=true
的副作用尚不完全清楚。一种效果是,注册为IsMacroType=true
并具有被标记为AllowReference=true
的参数的函数将自动被视为易失性的(即使已向IsVolatile=false
注册)。另一个副作用是重新计算顺序会受到影响-尤其是当您从UDF内部读取未计算的单元格时。
在从UDF读取其他单元格时,您还必须非常小心,因为您对何时应该重新计算的期望值很高,因为这有损于计算依赖性树。在您的示例中,您的UDF正在读取单元格A30
,但是对单元格A30的更改会自动导致您的函数重新计算吗?当然,您不能使用Excel依赖项跟踪工具来了解您的单元格取决于A30
。确实,您宁愿要有一个使用显式参数的函数,并将其称为=DoSomething(A30)
,以使所有内容清晰并避免所有这些问题。
您可能试图读取Value2
的一个原因是要确定单元格的格式,而不是确定Excel存储的基础值,但这确实很危险,因为它不是重新计算和依赖关系树的一部分。 / p>
所以我想说您看到一些意外行为的事实表明您正在朝Excel不喜欢的方向前进。