2012-03-15 11 views
1

一部のファイルを処理するには時間がかかるコードブロックがあります。小さなファイル(データ行数が少ない)はうまく動作しますが、150-300程度になると、処理が遅くなることがあります(実際にはプロセス全体がちょうどハングアップしていると思うこともあります)。 6,000。ExcelでVBAを使用したループスルー範囲

.FormulaR1C1VLookup()機能にいくつかのセルを接続したいとします。私は.Range("J2:J" & MaxRow)を使って全範囲を一度に設定できることを知っています。しかし、私はそれらの細胞の価値をチェックするために細胞のブロックをループしています。 IFが空です。THEN私はこの式を適用したいと思います。それらのセルに既に値がある場合、それらを変更したくないので、私は全体の範囲オプションが私のために働くとは思わない(少なくとも私はそれを得ることができませんでした)。

Private Sub PullMIAFinalizedData(NewMIARep As Worksheet, MaxRow As Long, wkbFinalized As Workbook) 

Dim wksFinalized As Worksheet 
Dim lCount As Long 
Dim sVLookupJBlock As String 
Dim sVLookupKBlock As String 

    Application.Calculation = xlCalculationManual 

    sVLookupJBlock = "=IF(ISERROR(" & _ 
     "VLOOKUP(RC1,'[" & wkbFinalized.Name & "]" & wksFinalized.Name & "'!C1:C13,13,FALSE))," & _ 
     Chr(34) & Chr(34) & _ 
     ",VLOOKUP(RC1,'[" & wkbFinalized.Name & "]" & wksFinalized.Name & "'!C1:C13,13,FALSE))" 
    sVLookupKBlock = "=IF(ISERROR(" & _ 
     "VLOOKUP(RC1,'[" & wkbFinalized.Name & "]" & wksFinalized.Name & "'!C1:C3,3,FALSE))," & _ 
     Chr(34) & Chr(34) & _ 
     ",VLOOKUP(RC1,'[" & wkbFinalized.Name & "]" & wksFinalized.Name & "'!C1:C3,3,FALSE))" 

    For Each wksFinalized In wkbFinalized.Sheets 

     ShowAllRecords wksFinalized 'Custom Function to unhide/unfilter all data 

     With NewMIARep 

      For lCount = 2 To MaxRow 

       If .Range("J" & lCount).value = "" And .Range("K" & lCount).value = "" Then 
        .Range("J" & lCount).FormulaR1C1 = sVLookupJBlock 
        .Range("K" & lCount).FormulaR1C1 = sVLookupKBlock 

        Application.Calculate 

        With .Range("J" & lCount & ":K" & lCount) 
         .value = .value 
        End With 


       End If 
      Next lCount 

      .Range("J2:J" & MaxRow).NumberFormat = "mm/dd/yyyy" 

     End With 

    Next wksFinalized 

    Application.Calculation = xlCalculationAutomatic 

End Sub 

私はちょうどこれにこだわっていますか?

+0

何がsVLookupJBlockですか?あなたは完全なコードを投稿できますか? – assylias

+1

'Application.Calculate'を削除してみてください。 'Vlookup'の代わりに' .Find'を使うことも考えました(あなたはそれらを値に変換しているので?)このリンクの第4章を参照してください。http://siddharthrout.wordpress.com/2011/07/14/find-and -findnext-in-excel-vba/ –

+0

各行で 'Calculate'する必要はありますか?そうでない場合は、計算を手動に変更します。また、画面更新をオフにする必要があります: 'Application.ScreenUpdating = FALSE'とループの後に再度オンにすることを忘れないでください。 – bernie

答えて

3
assylias及びこれを手伝っため Siddharth Routに非常に多くの

感謝。どちらも非常に有用な情報を提供し、この結果につながった:

Private Sub PullMIAFinalizedData(NewMIARep As Worksheet, MaxRow As Long, wkbFinalized As Workbook) 

Dim wksFinalized As Worksheet 
Dim lCount As Long 
Dim lFinMaxRow As Long 
Dim DataRange As Variant 'per assylias, using a variant array to run through cells 
Dim FoundRange As Range 
    Application.Calculation = xlCalculationManual 
    With NewMIARep 
     DataRange = .Range("J2:K" & MaxRow) 
     For Each wksFinalized In wkbFinalized.Sheets 
      ShowAllRecords wksFinalized 
      lFinMaxRow = GetMaxRow(wksFinalized) 
      If lFinMaxRow > 1 Then 
       For lCount = 1 To MaxRow - 1 
        If Len(DataRange(lCount, 1)) = 0 And Len(DataRange(lCount, 2)) = 0 Then 
         'per Siddharth Rout, using Find instead of VLookup 
         Set FoundRange = wksFinalized.Range("A2:A" & lFinMaxRow).Find(What:=.Range("A" & lCount).value, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) 
         If Not FoundRange Is Nothing Then 
          DataRange(lCount, 1) = FoundRange.Offset(ColumnOffset:=12).value 
          DataRange(lCount, 2) = FoundRange.Offset(ColumnOffset:=2).value 
          Set FoundRange = Nothing 
         End If 
        End If 
       Next lCount   
      End If 
     Next wksFinalized 
    .Range("J2:K" & MaxRow).value = DataRange 
    .Range("J2:J" & MaxRow).NumberFormat = "mm/dd/yyyy" 
    End With 

    Application.Calculation = xlCalculationAutomatic 

End Sub 
+0

+1自分の答えを見つけるために;) –

2

VBAのセルを反復したくない場合は、EXTREMELY slowです。代わりに、必要なデータを配列に格納し、配列を処理してデータをシートに戻します。あなたのケースでは、以下のようなコードは(テストしていません):

Dim data as Variant 
Dim result as Variant 
Dim i as Long 
data = ActiveSheet.UsedRange 

ReDim result(1 To UBound(data,1), 1 To UBound(data,2)) As Variant 

For i = LBound(data,1) to UBound(data,1) 
    'do something here, for example 
    If data(i,1) = "" Then 
     result(i,1) = "=VLOOKUP($A1,$A:$G," & i & ",FALSE)" 
    Else 
     result(i,1) = data(i,1) 
    End If 
Next i 

ActiveSheet.Cells(1,1).Resize(Ubound(result, 1), UBound(result,2)) = result 
+0

これは参考になりましたが、@ Sidの応答と同じくらい速く速度を上げることはできませんでした。彼が答えを出さないなら、私はこれを受け入れるだろう。ありがとう! – Gaffi

+0

彼の答えが良かったら、彼がそれを投稿するか、自分で答えを投稿してそれを受け入れるかを受け入れるべきです。 – assylias

+0

これは両方の組み合わせです。彼はちょうど私のプロセスをさらに改善しました(1つのテストに基づいて)。 – Gaffi

関連する問題