问题描述
在VSTO / COM上下文中,对API(此处为Excel)的每次调用都很昂贵(每个调用大约1-10毫秒),这主要是由于从托管代码切换到非托管代码时需要进行编组。
我有一个包含大量形状的电子表格,并且需要获得许多给定形状的引用,并以它们的名字命名。一些名称将被调用,并且它们将没有任何对应的形状。这完全是可以预期的,并且是业务逻辑的一部分。
策略1
Excel API公开ThisSheet.Shapes(ShapeName As String) as Excel.Shape
以获取此形状,如果没有与给定名称相关的形状,则返回Exception:在COM端这是有效的,因为它只需要调用一次。另一方面,如果不存在该形状,则需要“尝试...捕获”(Try ... Catch)和生成堆栈跟踪的负担,这可能在寻找并找不到许多形状时加起来。
Function TryGetFrom(ShapeName As String,Sheet As Excel.Worksheet,ByRef FoundShape as Excel.Shape) As Boolean
Try
FoundShape = Sheet.Shapes.Item(ShapeName)
Return True
Catch ex As Exception
Return False
End Try
End Function
策略2
另一种方法是遍历工作表中的所有形状,然后CurrentShape.Name = MyWantedShapeName
退出循环;如果所有形状均已迭代,但尚未编译任何形状,则我们知道所寻找的形状不存在。很好,因为它不需要任何异常处理。在大多数情况下,这就是我追求的方式,并且很可能是大多数程序员建议这样做的方式。但是,要遍历每个形状并为每个形状调用CurrentShape.Name
,则需要通过COM进行多次调用,这效率很低。
Function TryGetFrom(ShapeName As String,ByRef FoundShape as Excel.Shape) As Boolean
For Each MyShape As Excel.Shape In Sheet.Shapes
If MyShape.Name = ShapeName Then
FoundShape = MyShape
Return True
End If
Next
Return False
End Function
另一个选择?
我知道必须有一个最佳平衡,这取决于工作表上形状的数量和ShapeName
不匹配的数量,应优先采用一种策略。我还知道,我可以通过映射工作表的所有形状来加快此过程,以便更快地进行后续搜索(示例代码已简化)。我想知道,例如,在上述两种策略之间是否存在中间选择,是否可以在不生成堆栈跟踪的情况下捕获异常?这样,我就可以尝试... ...捕获(因此将昂贵的COM调用减至最少),并且避免在ShapeName
不匹配时避免生成昂贵的堆栈跟踪(我可能甚至不需要知道Exception是什么,知道只要有一个足以返回False
)。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)