0

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

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

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

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

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

在此先感谢您的帮助。

4

1 回答 1

1

我已经说过 Excel 分配的对象和插件使用的对象之间没有强联系

那是指 Excel 使用“享元”这一事实。Excel 内部不使用 COM;它根据需要为其内部结构(我认为它们为“视图”)创建 COM 包装器,以服务 COM 客户端(无论是加载项、VBA 还是外部应用程序)的请求。

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

我不会说“任何时候”。

一旦您获得一个Range对象或任何其他 COM 对象,该 COM 对象将保持可用直到被释放(在 COM 意义上 - 调用IUnknown::Release()每个对象AddRef())。

但是,如果您持有一个 COM 对象并且其基础结构不复存在,则该 COM 对象将变为无效。它还能做什么?

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

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

无论如何,它不太可能很有用。许多命令可能会导致正在处理的 [windows] 消息,并且任何时候发生在代码之外的任何时候都可能在毫无防备的时间运行并使您的范围无效。你真的必须在错误发生时抓住它,并适当地“平底船”。

或许你是对的。还不如“随时”。但这不是随机的。必须有人去弄脏靶场。

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

于 2011-04-07T16:13:23.177 回答