CountIfs在Excel中非常慢

时间:2014-04-03 18:36:58

标签: excel vba excel-vba

情境:

我有一个场景,每个帐户可以有很多客户,每个客户可以拥有多个帐户(多对多)。

我正在创建一份报告来计算每个客户拥有的帐户数量。

enter image description here

为此,我使用这个公式:

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

这很好用。问题是CustAccount表包含65K行。报告表包含45K客户ID。在相对较慢的PC上执行此计算需要20多分钟。

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

 Application.ScreenUpdating = False
 Application.Calculation = xlCalculationManual 

每次循环所有65K行以获取45K表中每一行的计数吗? 关于如何才能显着提高绩效的任何想法?

2 个答案:

答案 0 :(得分:4)

如何在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

答案 1 :(得分:1)

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

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