使用VBA代码的Excel中的CountIF非常慢

时间:2013-07-26 18:43:53

标签: excel vba excel-vba countif

我第一次尝试使用VBA代码,在编写这些草稿代码之前我做了很多搜索,但是一件事它运行不好。 我使用了Application.WorkSheetFunction.CountIfs,但代码非常慢,我需要读取一个包含140.000行和31列的表,带有countif标准的表有6000行和13列。

Sheet2.Cells(x,17),Sheet2.Cells(x,14)和Sheet2.Cells(x,17)的代码这是错误的,但我找不到问题

按照我用于countIfs的代码片段

x = 2     y = Application.CountA(范围(“A:A”))

Dim Submit_Date As Range
Dim GU As Range
Dim Legal_Entity_Country As Range
Dim Media_Type As Range
Dim Doc_Status As Range
Dim Approval_Date As Range
Dim Month_Create As Range
Dim FY As Range
Dim Status As Range

Set Submit_Date = Range("Table1[[#All],[Submit_Date]]")
Set GU = Range("Table1[[#All],[GU]]")
Set Legal_Entity_Country = Range("Table1[[#All],[Legal_Entity_Country]]")
Set Media_Type = Range("Table1[[#All],[Media_Type]]")
Set Doc_Status = Range("Table1[[#All],[Doc_Status]]")
Set Approval_Date = Range("Table1[[#All],[Approval_Date]]")
Set Month_Create = Range("Table1[[#All],[Month_Create]]")
Set FY = Range("Table1[[#All],[FY]]")
Set Status = Range("Table1[[#All],[Status]]")

For x = 2 To y
    With Application.WorksheetFunction
        Sheet2.Cells(x, 10) = _
            .Sum(.CountIfs(Month_Create, Sheet2.Cells(x, 3), _
                           FY, Sheet2.Cells(x, 5), _
                           GU, Sheet2.Cells(x, 6), _
                           Legal_Entity_Country, Sheet2.Cells(x, 7), _
                           Media_Type, Sheet2.Cells(x, 8), _
                           Doc_Status, Sheet2.Cells(x, 9), _
                           Status, Sheet2.Cells(1, 10)), _
                 .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), _
                           GU, Sheet2.Cells(x, 6), _
                           Legal_Entity_Country, Sheet2.Cells(x, 7), _
                           Media_Type, Sheet2.Cells(x, 8), _
                           Doc_Status, Sheet2.Cells(x, 9), _
                           Status, Sheet2.Cells(1, 10)), _
                 .CountIfs(Approval_Date, ">" & Sheet2.Cells(x, 2), _
                           Month_Create, Sheet2.Cells(x, 3), _
                           FY, Sheet2.Cells(x, 5), _
                           GU, Sheet2.Cells(x, 6), _
                           Legal_Entity_Country, Sheet2.Cells(x, 7), _
                           Media_Type, Sheet2.Cells(x, 8), _
                           Doc_Status, Sheet2.Cells(x, 9), _
                           Status, Sheet2.Cells(1, 13)), _
                 .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), _
                           Approval_Date, ">=" & Sheet2.Cells(x, 1), _
                           GU, Sheet2.Cells(x, 6), _
                           Legal_Entity_Country, Sheet2.Cells(x, 7), _
                           Media_Type, Sheet2.Cells(x, 8), _
                           Doc_Status, Sheet2.Cells(x, 9), _
                           Status, Sheet2.Cells(1, 13)))
         Sheet2.Cells(x, 11) = .Sum(.CountIfs(Month_Create, Sheet2.Cells(x, 3), FY, Sheet2.Cells(x, 5), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 11)), .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 11)))
         Sheet2.Cells(x, 12) = .Sum(.CountIfs(Month_Create, Sheet2.Cells(x, 3), FY, Sheet2.Cells(x, 5), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 12)), .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 12)))
'         Sheet2.Cells(x, 13) = .Sum(.CountIfs(Month_Create, Sheet2.Cells(x, 3), Approval_Date, "<=" & Sheet2.Cells(x, 2), FY, Sheet2.Cells(x, 5), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 13)), .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), Month_Approved, Sheet2.Cells(x, 3), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 13)))
'         Sheet2.Cells(x, 14) = .Sum(.CountIfs(Month_Create, Sheet2.Cells(x, 3), FY, Sheet2.Cells(x, 5), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 14)), .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), Month_Approved, Sheet2.Cells(x, 3), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 14)))
         Sheet2.Cells(x, 15) = .Sum(Sheet2.Cells(x, 10), Sheet2.Cells(x, 11), Sheet2.Cells(x, 12), Sheet2.Cells(x, 13), Sheet2.Cells(x, 14))
         Sheet2.Cells(x, 16) = .CountIfs(Month_Create, Sheet2.Cells(x, 3), FY, Sheet2.Cells(x, 5), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9))
'         Sheet2.Cells(x, 17) = .Sum(.CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), Month_Approved, Sheet2.Cells(x, 3), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 14)), .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 11)), .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 12)))
         Sheet2.Cells(x, 18) = .Sum(.CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 10)), .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), Approval_Date, ">=" & Sheet2.Cells(x, 1), GU, Sheet2.Cells(x, 6), Legal_Entity_Country, Sheet2.Cells(x, 7), Media_Type, Sheet2.Cells(x, 8), Doc_Status, Sheet2.Cells(x, 9), Status, Sheet2.Cells(1, 13)))
         Sheet2.Cells(x, 19) = .Sum(Sheet2.Cells(x, 16), Sheet2.Cells(x, 17), Sheet2.Cells(x, 18)) = Sheet2.Cells(x, 15)
    End With
Next x

此致 安德烈

1 个答案:

答案 0 :(得分:1)

看看标准是什么,我可以告诉你,通过改变它们会看到性能的巨大提升。除了第一个或第二个标准外,他们都在检查相同的几个标准之间的平等。

在一个新列中添加一个值,该列用于连接(用分隔符)要检查的单元格。然后根据类似连接的标准检查它们。一个例子是它们都检查每一行的GU,Legal_Entity_Country,Media_Type,Doc_Status和Status是否等于某些值。因此,加入这些,然后根据加入的条件检查联接。

所以,如果你想使用公式,添加一个列,如“= CONCATENATE(A1,”|,B1,“|”,C1,“|”,D1)“,其中A1,B1等是行的相关值。然后,您的标准将是类似连接的相关标准。然后,将您的身份改为例如= COUNTIFS(的 _ 下,combinedColumn,combinedCritera)。

这样做会显着减少查找次数,从而提高速度。

要在宏中更改它,请执行以下操作(仅提供问题中代码的示例摘录)

旧:

.CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), _
                           GU, Sheet2.Cells(x, 6), _
                           Legal_Entity_Country, Sheet2.Cells(x, 7), _
                           Media_Type, Sheet2.Cells(x, 8), _
                           Doc_Status, Sheet2.Cells(x, 9), _
                           Status, Sheet2.Cells(1, 10)), _

新:

Dim combinedCriterion As String
combinedCriterion = Join(Array(Sheet2.Cells(x, 7),Sheet2.Cells(x, 8),Sheet2.Cells(x, 9),Sheet2.Cells(1, 10)),"|")
     .CountIfs(Submit_Date, "<" & Sheet2.Cells(x, 1), _
                               combinedColumn, combinedCriterion)
...etc