0

我使用下面的代码将一列从一张纸复制到另一张纸,然后用 Null 值替换空白单元格:

'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

当我用它替换 for 语句时,Range("E2", Cells(500,5))它工作正常。

可能是什么问题?我无法弄清楚。谁能帮我这个?

4

3 回答 3

8

Excel 2007 有 1,048,576 行。

  1. 您的 For each 循环必须经过一百万个单元格,并且每次必须将一个单元格(及其所有属性)加载到内存中。单元对象的这种不断加载和卸载非常消耗资源。

  2. 每次将值分配给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 行/列的更多信息。

于 2013-02-24T19:36:23.057 回答
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
于 2013-02-24T22:02:12.540 回答
2

正如 Cabierberach 正确指出的那样,您当前的例程循环超过 1M 行。除了他和 JustinJDavies 的解决方案之外,请考虑以下 hack:

无需将值设置0为 ,No您只需更改格式,如果单元格No每次显示为 0这可以在没有宏的情况下通过将这种自定义格式应用于单元格来完成:0,-0,"No",@. 您可能需要将 替换为0您的默认格式 - 有关自定义数字格式的详细说明,请参阅此链接

如果你想在 VBA 中这样做,这一行就足够了:

Range("E2:E" & Cells(Rows.Count, 1).End(xlUp).Row).CustomFormat = "0,0,""No"",@"
于 2013-02-25T09:02:47.593 回答