Excel::Shape 对象在 List中计数达到 18 后自动释放;

发布于 2024-09-03 18:37:31 字数 1072 浏览 3 评论 0原文

我有一个用 C# 2.0 编写的 Excel 插件,在其中我遇到了奇怪的行为。请注意,此行为仅出现在 Excel 2003 中,而不出现在 Excel 2007 或 2010 中。

问题:< /em>

当用户单击导入命令按钮时,将读取一个文件并使用 Worksheet::Shapes::AddPicture() 方法创建/添加许多形状到工作表中。对这些 Shape 对象的引用保存在通用列表中:

List<Excel.Shape> list = new List<Excel.Shape>();

一切正常,直到列表中的引用少于 18 个为止。当计数达到18时,添加一个新的Shape引用,第一个即@index[0]被释放。我无法调用该引用上的任何方法或属性,并且调用方法/属性会引发 COMException (0x800A1A8),即需要对象。如果我再加一个,那么引用@[1]就不可访问等等。

奇怪的是......这种情况仅发生在 Shape 对象上,即如果我添加一个 Shape,然后向列表中添加 17 个空值,那么在添加另外 17 个 Shape 对象之前,这种情况不会发生。

有人知道为什么在计数达到 18 后会发生这种情况吗?

我认为这可能与列表的默认容量有关。比如在释放引用时重新定位引用,所以我用 1000 的容量初始化它,但仍然没有成功。

List<Excel.Shape> list = new List<Excel.Shape>(1000);

任何想法?


更新

发现尝试通过字符串索引访问 Shape 对象时生成的异常正在发挥作用。添加新 Shape 时,我通过调用 Worksheet::Shapes::Item(shapename) 检查现有 Shape 对象。如果未找到形状,则会引发异常。如果我删除这行代码...它工作正常。

是否有另一种方法可以检查 Shape 是否存在而不生成此异常或迭代整个集合?

I have a Excel addin written in C# 2.0 in which I am experiencing a strange behavior.Please note that this behavior is only seen in Excel 2003 and NOT in Excel 2007 or 2010.

Issue:

When the user clicks an import command button, a file is read and a number of Shapes are created/added to the worksheet using Worksheet::Shapes::AddPicture() method. A reference to these Shape objects are kept in a generic list:

List<Excel.Shape> list = new List<Excel.Shape>();

Everything works fine till the list has less than 18 references. When the count reaches 18, and a new Shape reference is added, the first one i.e. @ index [0] is released. I am unable to call any method or property on that reference and calling a method/property throws a COMException (0x800A1A8) i.e. Object Required. If I add one more, then the reference @ [1] is not accessible and so on.

Strange enough... this happens with Shape object only i.e. If I add one Shape and then 17 nulls to the list then this wont happen until 17 more Shape objects are added.

Does anyone has an idea why it happens after the count reaches 18?

I thought it might be something with the List's default capacity. Something like relocating the references during which they get released so I initialized it with a capacity of 1000 but still no luck.

List<Excel.Shape> list = new List<Excel.Shape>(1000);

Any Idea??


UPDATED

Found that the exception generated while trying to access a Shape object through a string index is playing some role. When a new Shape is added, I check for an existing Shape object by calling Worksheet::Shapes::Item(shapename). This throws an exception if the Shape is not found. If I remove this line of code... it works fine.

Is there another way of checking if a Shape exists without generating this exception or iterating through the whole collection?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

财迷小姐 2024-09-10 18:37:31

不幸的是,Excel 中有许多邪恶的小错误。 UI 和 VBA 均可。

其中之一是,当Excel中创建的用户窗体拥有超过{一定数量}个控件时,引用Form.ControlName形式的控件会导致Excel无故崩溃,但是以 Form.Controls("ControlName") 的形式访问相同的控件可以正常工作。

也就是说,尝试存储形状的字符串名称,每次需要时通过使用名称查询 Worksheet::Shapes 集合来获取新指针。

There are many evil little bugs in Excel, unfortunately. Both in UI and VBA.

One of them is that when a user form created in Excel has more than {certain amount} of controls, referring to a control in the form of Form.ControlName will cause Excel to crash for no reason, but accessing the same control in the form of Form.Controls("ControlName") will work fine.

That's to say, try storing string names of the shapes instead, acquiring a new pointer each time you need it by querying Worksheet::Shapes collection with the name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文