2017-11-16 11 views
-1

いくつかのsumifを計算し、別のワークシート上の条件を検索するマクロを構築しようとしています。これはこれまでのコードです:VBA - forループのsumif - より効率的な方法はありますか?

Sub SumPerYear() 

Dim NoClients As Long 
NoClients = Worksheets("Temp").Range("A2").End(xlDown).Row - 1 

Sheets("Temp").Activate 

For i = 2 To NoClients + 1 

    'Fill 2015 € in column E 
    Cells(i, 5).Value2 = Application.SumIfs(Worksheets("Q ALL").Range("I:I"), _ 
     Worksheets("Q ALL").Range("A:A"), 2015, _ 
     Worksheets("Q ALL").Range("D:D"), Worksheets("Temp").Range("A" & i).Value2, _ 
     Worksheets("Q ALL").Range("C:C"), True) 

    'Fill 2015 # in column F 
    Cells(i, 6).Value2 = Application.CountIfs(_ 
     Worksheets("Q ALL").Range("A:A"), 2015, _ 
     Worksheets("Q ALL").Range("D:D"), Worksheets("Temp").Range("A" & i).Value2, _ 
     Worksheets("Q ALL").Range("C:C"), True) 

    'Fill 2016 € in column G 
    Cells(i, 7).Value2 = Application.SumIfs(Worksheets("Q ALL").Range("I:I"), _ 
     Worksheets("Q ALL").Range("A:A"), 2016, _ 
     Worksheets("Q ALL").Range("D:D"), Worksheets("Temp").Range("A" & i).Value2, _ 
     Worksheets("Q ALL").Range("C:C"), True) 

    'Fill 2016 # in column H 
    Cells(i, 8).Value2 = Application.CountIfs(_ 
     Worksheets("Q ALL").Range("A:A"), 2016, _ 
     Worksheets("Q ALL").Range("D:D"), Worksheets("Temp").Range("A" & i).Value2, _ 
     Worksheets("Q ALL").Range("C:C"), True) 

    'Fill 2017 € in column I 
    Cells(i, 9).Value2 = Application.SumIfs(Worksheets("Q ALL").Range("I:I"), _ 
     Worksheets("Q ALL").Range("A:A"), 2017, _ 
     Worksheets("Q ALL").Range("D:D"), Worksheets("Temp").Range("A" & i).Value2, _ 
     Worksheets("Q ALL").Range("C:C"), True) 

    'Fill 2017 # in column J 
    Cells(i, 10).Value2 = Application.CountIfs(_ 
     Worksheets("Q ALL").Range("A:A"), 2017, _ 
     Worksheets("Q ALL").Range("D:D"), Worksheets("Temp").Range("A" & i).Value2, _ 
     Worksheets("Q ALL").Range("C:C"), True) 

    'Fill Tot € in column K 
    Cells(i, 11).Value2 = Cells(i, 5) + Cells(i, 7) + Cells(i, 9) 

    'Fill Tot # in column L 
    Cells(i, 12).Value2 = Cells(i, 6) + Cells(i, 8) + Cells(i, 10) 

Next i 

End Sub 

このコードは機能しますが、何千ものレコードがあるため、完了するまでに時間がかかります。これをより効率的に/より速くする方法はありますか?

ありがとうございました!

+0

は、関数-itsは異なり、その後だから私はこれをどのように行うことができます – Ashok

+0

が完了するまでの時間のあまりを取るループを使用していけませんか?何をお勧めしますか? – Geert

+0

SUMIFをrow2に直接入力せずにコピーしているのはなぜですか? –

答えて

0

残念なことに、アプリケーションメソッドは大量のセルでは処理が遅すぎますので、コードを書く必要があります。これはあなたのものほど素敵で簡単ではありません。 主なアイデアは、ここでcatchedさ:

Dim arrA as Variant 'change Variant to your type 
Dim arrCD as Variant 
Dim arr as Variant 
Dim i as long 
Dim k as integer 
Dim NoClients As Long 
NoClients = Worksheets("Temp").Range("A2").End(xlDown).Row - 1 

'assign Ranges to arrays 
'we can't assign non-contiguous range, so we create two arrays 
arrA = Range("A:A") 
arrCD = Range("C:D") 
ReDim arr(UBound(arrA), 3) 
ReDim outArr(NoClients, 5 to 10) 
'loop and fill third merged array 
For i = 1 To UBound(arrA) 
    arr(i, 0) = arrA(i, 1) 
    arr(i, 1) = arrCD(i, 1) 
    arr(i, 2) = arrCD(i, 2) 
Next i 

'the rest of code You just loop through 
For k = 2 To NoClients + 1 'get client 
    For i = 1 To UBound(arr) 'count summuries for him 
     if (arr(i,0) = 2016) and (arr(i,1) = true) and (arr(i,2) = _ 
      Worksheets("Temp").Range("A" & k).Value2) then 
      'sumifs replacement 
      outArr(k, 5) = outArr(k, 5) + Worksheets("Q ALL").Cells(1+i, "I").Value2 
      'countifs replacement 
      outArr(k, 6) = outArr(k, 6) + 1 
     end if 
    Next i 
Next k 

Worksheets("Temp").Range("A2").Value2 = outArr 'prints array on sheet with top left corner at A2 
+0

ご協力ありがとうございます。ソリューション(arr)で新しい配列を作成すると分かりますが、これによってsumifsがより高速に計算されますか? sumifがforループでどのように見えるべきかの小さな例を挙げることができますか? – Geert

+0

@Geert私はいくつかの細部であなたの仕事を誤解していたので、コードの考え方は少し変わった。 – Vmesser

+0

クライアントリストをループし、データ配列に基づいてサマリを計算し、これらのサマリーをoutArr 2次元配列に入れます。ここで、最初の次元はクライアント番号、2番目はデータストレージです。インデックスの意味を理解するために2番目の次元(5〜10) - 対応する列番号と同じです。最後の文字列は、配列を印刷するための良いトリックです。どんな計算でも、ずっと多くのものが、シートよりもはるかに速いため、よりうまくいくと思います。 – Vmesser

関連する問題