优化Excel CountIfs – 我可以使它更快?

我有一些更大的文件,我需要validation数据英寸我大部分是自动input我需要的公式自动。 这有助于消除在大文件上复制和粘贴的错误。 问题是这个最新的validation。

最新的validation之一涉及计算匹配3列的行数。 3列在表2中,要计数的行在表1中。然后将此计数与基于表2的预期数进行比较。使用CountIFs很容易,但是存在大文件,它可以占用一些小时。 我正在努力寻找更快的东西。

我正在使用一个较小的文件,它仍然需要大约1分钟。 只有大约1800行。

我有这样的东西:

在这里输入图像说明

在这里输入图像说明

在Check1中,我使用:= COUNTIFS(Sheet1!A:A,A2,Sheet1!B:B,B2,Sheet1!C:C,C2)

我的代码将该公式放入活动单元格中。 有一个更好的方法吗?

无论如何 – 使用VB或任何东西 – 来提高性能。 当行开始成千上万的时候,是时候开始这个,吃午饭了。 然后,当我回到我的办公桌时,希望能够完成!

谢谢。

你基本上必须遍历每列的所有行,这是昂贵的。 您可以将其分成两个任务:

  1. 合并您的列AC到一个值=CONCAT(A2,B2,C2)
  2. 然后在这个列上只做一个单元=COUNTIF(D:D,D2)

这样,你就可以摆脱两个(时间)昂贵的countifs,代价是新的concat。

您应该将范围CountIf从整列到实际使用的范围缩小

而你的代码可以写公式的结果,而不是公式本身

如下所示:

 With Sheet1 Set sheet1Rng = Intersect(.UsedRange, .Range("A:C")) End With With Sheet2 For Each cell in Intersect(.UsedRange, .Range("A:A")) cell.Offset(,3) = WorksheetFunction.CountIfs(sheet1Rng.Columns(1), cell.Value, sheet1Rng.Columns(2), cell.Offset(,1).Value, sheet1Rng.Columns(3),cell.Offset(2).Value) Next cell End With 

我使用与显示内容类似的布局设置了一个模拟工作表,其中包含10,000行,并手动使用显示的COUNTIFS公式填充它。 更改数据中的单个项目会触发重新计算,这需要大约十秒钟左右的时间才能执行。

然后我尝试了下面的macros,在一秒钟内完成。 所有的计数都在VBAmacros中完成。 所以这个字典方法可能是你的速度问题的答案。

在运行这个之前,如果工作表上有COUNTIFS,可能需要将Calculation状态设置为Manual(或者在代码中执行)。


 Option Explicit 'set reference to Microsoft Scripting Runtime Sub CountCol123() Dim DCT As Dictionary Dim V As Variant Dim WS As Worksheet, R As Range Dim I As Long Dim sKey As String Set WS = Worksheets("sheet2") 'read the info into an array With WS Set R = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)).Resize(columnsize:=4) V = R End With 'Get count of the matches Set DCT = New Dictionary For I = 2 To UBound(V, 1) sKey = V(I, 1) & "|" & V(I, 2) & "|" & V(I, 3) If DCT.Exists(sKey) Then DCT(sKey) = DCT(sKey) + 1 Else DCT.Add Key:=sKey, Item:=1 End If Next I 'Get the results and write them out For I = 2 To UBound(V, 1) sKey = V(I, 1) & "|" & V(I, 2) & "|" & V(I, 3) V(I, 4) = DCT(sKey) Next I 'If you have COUNTIFS on the worksheet when testing this, ' or any other formulas that will be triggered, ' then uncomment the next line 'Application.Calculation = xlCalculationManual With R .EntireColumn.Clear .Value = V End With End Sub