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]开发者_C百科 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?
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.
精彩评论