在Excel中使用VBA循环遍历

我有一段代码花了太长的时间来处理一些文件。 更小的文件(更less的数据行)工作正常,但一旦我达到约150-300,它开始变慢,(有时我认为整个过程实际上只是挂起),我必须有时运行这个文件与最多6000。

我想为.FormulaR1C1中的一些单元插入VLookup()函数。 我知道我可以使用.Range("J2:J" & MaxRow)一次设置整个范围。 但是,我正在循环一个单元格块来检查这些单元格的值。 如果他们是空的, 那么我想申请的公式。 如果这些单元格已经有了值,那么我不想改变它们,所以我不认为整个范围选项对我来说是合适的(至less我没有把它弄清楚)。

 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 

我只是坚持这个?

非常感谢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 

你不想迭代VBA中的单元格:它极其缓慢。 相反,你把你需要的数据放到数组中,在数组上工作并把数据放回工作表。 在你的情况下,像下面的代码(未testing):

 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