在VSTO应用程序C#

时间:2017-01-05 07:04:34

标签: c# excel vsto

我的任务是根据字符串是否存在于特定行中来隐藏/取消隐藏excel工作簿的行。我面临的问题是,使用以下代码在1000行上执行此任务需要大约20秒。该文件可能有多达2k-3k行,我想减少这个加载时间。

需要注意的是,当我在代码中注释“隐藏/取消隐藏”整行(currentFind.EntireRow.Hidden =!isShown;)时,excel文件只需4-5秒即可加载。这使我得出结论,它是行隐藏部分,这是耗时的而不是搜索字符串部分。

        Worksheet activeWorksheet= Globals.ThisAddIn.Application.ActiveSheet;
        Range usedRange = activeWorksheet.UsedRange;

        Range currentFind = null;
        Range firstFind = null;

        currentFind = activeWorksheet.UsedRange.Find(searchInput);

        while (currentFind != null)
        {
            // Keep track of the first range you find. 
            if (firstFind == null)
            {
                firstFind = currentFind;
            }

            // If you didn't move to a new range, you are done.
            else if (currentFind.get_Address(XlReferenceStyle.xlA1)
                  == firstFind.get_Address(XlReferenceStyle.xlA1))
            {
                break;
            }

            currentFind.EntireRow.Hidden = !isShown;

            currentFind = usedRange.FindNext(currentFind);
        }

2 个答案:

答案 0 :(得分:0)

在开头使用Globals.ThisAddin.Application.ScreeenUpdating = false 并在结束时将其设置为true。 你也可以在开始时抛出Globals.ThisAddin.Application.EnableEvents = false 最后是真实的。

答案 1 :(得分:0)

我发现,在同一时间做任何事情(或范围或单元格)似乎总是花费比在整个范围内一次性做更长的时间。例如,我曾经写过一些东西,它删除了所有完全空白的行,当我把它作为一个语句(Range.Delete)而不是一个循环时,它在眨眼之间运行,这花了很长时间。

本着这种精神,如果您重新访问代码并收集包含相关字符串的所有行,然后立即隐藏它们,该怎么办呢?

Excel.Range hideRange = null;
Excel.Application xl = Globals.ThisAddIn.Application;

foreach (Excel.Range row in activeWorksheet.UsedRange.Rows)
{
    if (oApp.WorksheetFunction.CountIf(row, "*" + searchInput + "*") > 0)
        hideRange = hideRange == null ? row : xl.Union(hideRange, row);
}

hideRange.EntireRow.Hidden = true;

我不能保证这段代码更快,但请尝试一下,让我们知道它的比较方式。我非常有信心最后一行会快速运行;还有待观察的是如何识别出现的循环。

我在一些虚假数据上进行了测试,对于数千行隐藏了数百行,"隐藏"代码行只花了156毫秒,或0.15秒。