我使用下面的代码将列从一个工作表复制到另一个工作表,然后用空值替换空白单元格:
'Copying If Employee
sourceSheet.Activate
Range(Cells(2, 7), Cells(Rows.Count, 7).End(xlUp)).Select
Selection.Copy
destSheet.Activate
Range("E2", Cells(Rows.Count, 7)).PasteSpecial
For Each cell In Range("E2", Cells(Rows.Count, 5))
If Len(cell.Value) = 0 Then
cell.Value = "No"
End If
当我用Range("E2", Cells(500,5))
替换for语句时,它工作正常。
可能是什么问题?我无法弄明白。任何人都可以帮我这个吗?
答案 0 :(得分:8)
Excel 2007有1,048,576行。
你的每个循环必须经过一百万个单元格,并且每次必须将一个单元格(包含其所有属性)加载到内存中。这种不断加载和卸载单元对象非常耗费资源。
每次将值No
分配给单元格时,Excel都会重新计算工作表,刷新屏幕并可能触发工作表/工作簿/单元格事件。所有这一切都在评估下一个细胞到下一个细胞之前。除非您拥有大量数据,否则在此示例中将会发生几十万次。
500个单元格数量要少得多,可以毫无问题地处理。
修改强>
获取最后一行。
如果您想获取包含数据的最后一个可见行,请使用:
With Workbooks(myWorkbook).Worksheets(myWorksheet)
LastRow = .Cells(.Rows.Count, "E").End(xlUp).Row
End With
如果您想获取包含数据的最后一行,无论它是可见还是隐藏,请使用:
With Workbooks(myWorkbook).Worksheets(myWorksheet)
LastRow =.Range("E2").EntireColumn.Find("*", .Cells(1, .Range("E2").Column), , , xlByRows, xlPrevious).Row
End With
了解更多信息Rondebruin有一个很好的网站,其中包含有关确定las行/列的详细信息。
答案 1 :(得分:2)
尝试
For Each cell In Range("E2", Cells(destSheet.UsedRange.Rows.Count, 5))
If Len(cell.Value) = 0 Then
cell.Value = "No"
End If
或更优雅(可能更快),
Dim calcStatus As XlCalculation
calcStatus = Application.Calculation
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
For Each cell In Range("E2:E" & destSheet.UsedRange.Rows.Count)
If Len(cell.Value) = 0 Then
cell.Value = "No"
End If
Application.Calculation = calcStatus
Application.ScreenUpdating = True
答案 2 :(得分:2)
正如Cabierberach正确指出的那样,你当前的例程循环超过1M行。除了他和JustinJDavies解决方案之外,请考虑这个黑客:
如果要在每次值为0
时显示No
的单元格,您只需更改格式,而不是将值No
设置为0
。通过将此自定义格式应用于单元格,可以在没有宏的情况下完成此操作:0,-0,"No",@
。您可能需要使用默认格式替换0
- 有关自定义数字格式的详细说明,请参阅this link。
如果你想在VBA中这样做,这一行就足够了:
Range("E2:E" & Cells(Rows.Count, 1).End(xlUp).Row).CustomFormat = "0,0,""No"",@"