【问题标题】:Efficiently check if a COM property is available without try/catch无需 try/catch 即可有效检查 COM 属性是否可用
【发布时间】:2015-07-21 17:04:53
【问题描述】:

我正在使用 VSTO,并想检查某个属性是否在 COM 对象中可用。当它可用时,它会返回一个结果,当它不可用时,它会返回一个异常。

捕获 com 异常非常慢,我想知道是否有更有效的方法来检查该属性是否会引发异常。

注意这个问题类似但没有解决方案:How to check if a COM property or method exists without generating an exception?

请注意,还有另一种方法可以使用 Range.SpecialCells 检查范围是否具有验证,但我正在寻找更通用的解决方案来检测 COM 对象中的属性是否可用,因为这样其他 Excel COM 对象也会出现同样的性能问题。

举个例子。如果范围有数据验证,则 Range.Validation.Type 属性将返回结果,如果它没有数据验证,则会抛出异常。下面的代码在有或没有的单元格上测试数据验证 10 次。在我的计算机上,对具有数据验证的单元进行测试输出的时间为 0 毫秒,而没有数据验证的单元则花费了超过 500 毫秒。

    public static bool HasDataValidation(Excel.Range range)
    {
        try
        {
            var validationType = range.Validation.Type;
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }

    public static void RunTest()
    {
        var excelApp = Globals.ThisAddIn.Application;
        var worksheet = (Excel.Worksheet) excelApp.ActiveSheet;
        var rangeWithoutDataValidation = worksheet.Range["A1"];
        var rangeWithDataValidation = worksheet.Range["A2"];

        rangeWithoutDataValidation.Validation.Delete();

        rangeWithDataValidation.Validation.Delete();
        rangeWithDataValidation.Validation.Add(Excel.XlDVType.xlValidateList, Excel.XlDVAlertStyle.xlValidAlertStop,
            Excel.XlFormatConditionOperator.xlBetween, "A,B,C");

        var watch = Stopwatch.StartNew();
        for (int i = 0; i < 10; i++)
        {
            bool hasValidation = HasDataValidation(rangeWithoutDataValidation);
        }
        watch.Stop();
        long timeNoValidation = watch.ElapsedMilliseconds;

        watch = Stopwatch.StartNew();
        for (int i = 0; i < 10; i++)
        {
            bool hasValidation = HasDataValidation(rangeWithDataValidation);
        }
        watch.Stop();
        long timeWithValidation = watch.ElapsedMilliseconds;
        MessageBox.Show(String.Format("Time without validation was {0} milliseconds.\nTime with validation was {1} milliseconds.", timeNoValidation,timeWithValidation));
    }

【问题讨论】:

标签: c# exception exception-handling com vsto


【解决方案1】:

这样的事情怎么样:

public static bool HasDataValidation(Excel.Range range)
{
    try
    {
        var validation = range.Validation;
        return (validation != null);
    }
    catch (Exception)
    {
        return false;
    }
}

【讨论】:

  • 这将始终返回 true。据我所知,每个 Range 都有一个 Validation 对象。如果范围没有验证,则 Validation.Type 会引发 COM 异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-20
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
相关资源
最近更新 更多