我的任务是根据字符串是否存在于特定行中来隐藏/取消隐藏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);
}
答案 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秒。