保持Excel COM对象的活动状态

时间:2011-04-07 09:27:03

标签: excel com com-interop excel-interop comexception

我目前正在使用 Excel 2003 Interop 机制来操作一些范围

有时我会将 addin 中的一些范围存储为类的属性,但是当我稍后尝试访问它们时, COM对象有时会,随机,无效, COM对象的每个属性在我尝试访问时都会抛出“ COMException ”。

我曾经说过, Excel 分配的对象与插件正在使用的对象之间没有强大的联系:因此可以释放“true” Range对象通过 Excel 随时,即使从 .Net / C#的角度来看,我仍然可以参考它们。

所以,我想知道是否有办法让我的Range对象保持活着以便以后以安全的方式使用它们?

备注:我可以使用一种解决方法,例如存储代表范围字符串,例如“A1”,而不是范围本身,但这会使代码不那么干净。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

  

我曾经说过Excel分配的对象和addin正在使用的对象之间没有强大的联系

这指的是Excel使用“Flyweights”的事实。 Excel不在内部使用COM;它根据需要为COM客户端(无论是外接程序,VBA还是外部应用程序)提供请求,为其内部结构创建COM包装器(我将它们视为“视图”)。

  

......“真实”的Range对象可以随时由Excel释放

我不会说“随时”。

获得Range对象或任何其他COM对象后,COM对象将一直保持可用状态(在COM意义上 - 为每个IUnknown::Release()调用AddRef())。 / p>

但是,如果您持有COM对象并且底层结构不再存在,则COM对象确实变为无效。它还能做什么?

假设您持有Range并且用户删除了Range所在的工作表。您认为应该怎么做?这不像Excel会抛出一个消息框说“抱歉,你不能删除工作表,因为有些代码想要抓住它”。如果用户删除数据,Excel将遵守,Range对象将不得不应对。你加载项只需要为这种可能性做好准备。如果加载项提供公式,请让它们返回#REF等

我认为无论如何都不能主动发现这一点。我检查了某处是否存在某种IsValid(myRange)方法,但我没有看到任何方法。

无论如何,它不太可能非常有用;许多命令可能会导致[windows]消息被处理,并且在代码外部发生的任何时候都可以在毫无疑问的时间运行并使您的范围无效。你真的必须抓住错误发生,然后“适当”。

也许你是对的。它也可能是“随时”。但这不是随机的。有人必须去扫除范围。

顺便说一句,我不会试图超越情况。保存范围引用文本只会导致AddIn作用于用户想要的不同数据集。 “正确”的事情是“优雅地失败”。