尝试...捕获一个Items.GetByNameSeekedName与昂贵的Each Items.Item直到CurrentItem.Name = SeekedName

问题描述

在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)。

添加了c#标记,因为您使用哪种.Net语言确实无关紧要。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)