我已经说过 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 作用于用户想要的不同数据集。要做的“正确”事情是“优雅地失败”。