2013-07-26 58 views
1

我嘗試第一次使用VBA代碼,在編寫這些草稿代碼之前,我做了很多搜索,但是一件它不太好用。 我使用Application.WorkSheetFunction.CountIfs但代碼它非常緩慢,我需要讀取一個有140.000行和31列的表,具有countif條件的表有6000行和13列。Excel excel VBA代碼中的CountIFs非常慢

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 

問候 安德烈

+3

你應該使用'與'塊,以便更容易閱讀...我必須滾動像10英里的權利,看到整個陳述,它只是使它很難閱讀... – chancea

+1

André,爲您如何找到一個很好的例子d用'with with'塊寫這個,看看這個答案:http://stackoverflow.com/a/17868147/138938 –

+3

這會很慢我很害怕。 Excel不是數據庫。查找是O(N^2)操作的最壞情況,因爲它必須通過查找每個值的每個查找值(最大值)(大約140000 * 6000 =大數字)運行(最大值)。您上面發佈的所有COUNTIFS都可以在不使用VBA的情況下以公式(= COUNTIFS等)完成 - 它可能會更快。或者您可以考慮使用DAO Recordset並運行SQL查詢,但這可能過於複雜。祝你好運 - VBA開局艱難。 –

回答

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 
+0

@Cor_Bilmey我不能申請這個,你只聲明標準,並且我收到了combinedColumn的錯誤,我們需要以與用於標準相同的方式聲明CombinedColum。另一個疑問是,我需要在'WITH'之後或'With'之內。 Thansk很多 – user1902796

+0

@ user1902796這僅僅是一個例子 - 你需要真正把一個公式或東西做成'combined__'的東西。在沒有真正看到工作簿的情況下,我不能僅僅嘗試和描述方法,而是從本質上減少CountIfs必須完成的工作。 –