2012-03-15 3 views
1

일부 파일을 처리하는 데 너무 오래 걸리는 코드 블록이 있습니다. 작은 파일 (적은 데이터 행)은 제대로 작동하지만, 일단 150-300 정도되면 느린 속도로 시작합니다 (때로는 전체 프로세스가 실제로 멈추는 것 같아요). 그리고 때때로이 파일을 최대로 실행해야합니다. 6,000Excel에서 VBA를 사용하여 범위를 반복합니다.

에있는 VLookup() 함수에 여러 셀을 연결하려고합니다. .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

각 행에 '계산'을해야합니까? 그렇지 않은 경우 계산을 수동으로 변경하십시오. 또한 스크린 업데이트를 끄기 :'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

글쎄, 둘 다의 조합입니다. 그의 프로세스가 더 향상되었습니다 (하나의 테스트를 기반으로). – Gaffi

관련 문제