在Excel中CountIfs非常慢

场景:

我有一个情况,每个帐户可以有很多客户,每个客户可以有多个帐户(多对多)。

我正在创build一个报告来计算每个客户有多less个帐户。

在这里输入图像说明

要做到这一点,我使用这个公式:

=COUNTIF(CustAccount[Customer ID], [@[Customer ID]]) 

这工作正常。 问题是CustAccount表包含65K行。 报表包含45K个客户ID。 在相对较慢的PC上执行这个计算需要20多分钟的时间。

我正在使用明显的优化,如:

  Application.ScreenUpdating = False Application.Calculation = xlCalculationManual 

是否每次循环所有的65K行,以获得45K表中每一行的计数? 任何想法可以做什么来显着提高性能?

如何在Excel中对数据运行SQL查询:

 Sub SQLTester() 'Add a reference to "Microsoft ActiveX data objects" 'Workbook must have been saved to run this Dim oConn As New ADODB.Connection Dim oRS As New ADODB.Recordset Dim wb As Workbook Set wb = ThisWorkbook wb.Save oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & wb.FullName & _ ";Extended Properties='Excel 8.0;HDR=Yes'" oRS.Open " select Customer, count(Account) " & _ " from [Data test$A1:B2201] group by Customer", oConn wb.Sheets("Data test").Range("E2").CopyFromRecordset oRS oRS.Close End Sub 

另一种方法是通过CustomerID在Dictionary对象中累积帐户数,然后写出字典并按CustomerID对其进行sorting。 看下面的例子:

 Sub CountAccountsByCustomerID() ' Need to add reference in Menu > Tools > References ' turn checkbox on for "Microsoft Scripting Runtime" to use dictionary Dim customers As Dictionary Set customers = New Dictionary Dim AccountTable As Range Set AccountTable = Sheets("Sheet1").Range("A2") Dim offset As Long offset = 0 Dim OutputTable As Range Set OutputTable = Sheets("Sheet1").Range("D2") Dim customer As String Dim item As Variant ' Build dictionary of counts of accounts for all CustomerIDs Do While AccountTable.offset(offset, 0) <> "" customer = AccountTable.offset(offset, 1).Value If customers.Exists(customer) Then customers(customer) = customers(customer) + 1 Else customers(customer) = 1 End If offset = offset + 1 Loop 'Write table of customerIDs and counts of accounts offset = 0 For Each item In customers.Keys OutputTable.offset(offset, 0).Value = Str(item) OutputTable.offset(offset, 1).Value = customers.item(item) offset = offset + 1 Next 'Sort OutputTable by CustomerID (assumes column headings in row above range OutputTable OutputTable.CurrentRegion.Sort OutputTable, xlAscending, , , , , , xlYes End Sub