2011-04-07 124 views
0

我目前使用的是Excel 2003 Interop机制来操纵一些范围保持一个Excel COM对象活着

有时候我存放一些范围在我插件,作为一个类的属性,但是当我试图在稍后的时间COM对象有时是随机的,无效的访问它们,以及每个属性当我尝试访问它们时,COM对象将抛出“COMException”。

我一直在说,有对象的Excel分配和对象的插件是使用之间没有密切的联系:这样的“真实” Range对象可以通过Excel中在任何时候被释放,甚至如果从.Net/C#的角度来看,我仍然有一个参考。

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

备注:我可以用一种变通方法等存储字符串将代表范围,例如“A1”,而不是自己的范围,但这会使代码不那么干净。

在此先感谢您的帮助。

回答

1

我一直在说,有对象的Excel分配和对象之间没有密切联系的插件使用

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

...“真正”的范围对象,可以用Excel随时

我不会说“随时”中解脱出来。一旦得到一个Range对象或任何其他COM对象,COM对象将保持可用状态,直到被释放为止(在COM意义上 - 每个AddRef()调用IUnknown::Release())。

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

比方说你坚持Range并且用户删除范围所在的工作表。你认为应该发生什么?这不像是Excel会抛出一个消息框说“对不起,你不能删除工作表,因为一些代码想要坚持它”。如果用户删除数据,则Excel将符合并且Range对象将不得不应对。你需要为这种可能性做好准备。如果您的加载项提供了公式,让他们返回#REF等。

我不认为有反正主动检测到这一点。我检查是否有某种IsValid(myRange)方法在某处,但我没有看到任何。

无论如何,它不太可能是非常有用的;许多命令可能会导致[窗口]消息被处理,并且任何时候在代码外发生的情况都会在不知情的情况下运行,并使您的范围无效。你必须在发生错误时抓住错误,并适当地“踢”。

也许你是对的。它可能是“在任何时间”。但它不是随机的。有人不得不去掉这个范围。

顺便说一句,我不会试图智取情况。保存范围参考文本只会导致AddIn作用于用户预期的一组不同的数据。 “正确”的做法是“优雅地失败”。

+0

感谢您的完整答案。我的问题是,有问题的范围永远不会被用户删除或移动。每个范围对应一列,只修改列中的单元格值。 – Pragmateek 2011-04-07 17:29:32

+0

这听起来很奇怪。细胞如何修改?只需手工编辑?你知道你得到了什么确切的例外/ HRESULT吗? – 2011-04-08 03:47:20

+0

是的单元格只能由用户手工修改。我不记得确切的错误代码,但只存储一些字符串引用而不是“范围”本身已经解决了这个问题,并不会影响代码,也不会对性能产生副作用。 – Pragmateek 2011-04-09 15:16:22