for循环语句的问题几乎冻结了我的程序

时间:2019-07-09 12:11:30

标签: excel vba for-loop freeze

我有两个陈述,但是它们经过了很多单元,最终冻结了我的excel大约15秒到半分钟。我需要帮助,找到一种在不冻结excel的情况下运行代码的方法。

如果单元格中的语句正确(从第5行向下运行,行数未说明),我的代码之一就是公式。我的第二个代码将NumberFormat更改为"0,00",这是有问题的,因为我有很多带有数字的单元格。最好以与For-If语句不同的方式编写代码,但是除了下面提供的方法之外,我无法使其工作。我尝试添加一个DoEvents,它什么也没改变,程序仍然冻结。

导致我的程序运行缓慢的第一个代码:

For x = 5 To Rows.Count
If Application.WorksheetFunction.IsNumber(ws.Cells(x, 2)) = True Then
    ws.Cells(x, 14).FormulaR1C1 = "Formula 1"
    ws.Cells(x, 15).FormulaR1C1 = "Formula 2"
    ws.Cells(x, 16).FormulaR1C1 = "Formula 3"
    ws.Cells(x, 17).FormulaR1C1 = "Formula 4"
    ws.Cells(x, 18).FormulaR1C1 = "Formula 5"
ElseIf Application.WorksheetFunction.IsNumber(ws.Cells(x, 2)) = False Then
    Exit For
End If
Next x

第二个代码使我的程序在完成之前冻结了几秒钟:

For y = 2 To Columns.Count
For x = 5 To Rows.Count
If Application.WorksheetFunction.IsNumber(ws.Cells(x, y)) = True Then
    ws.Cells(x, y).NumberFormat = "0.00"
    ws.Cells(x, y).HorizontalAlignment = xlCenter
    ws.Cells(x, y).VerticalAlignment = xlCenter
Else
    Exit For
End If
Next x, y

1 个答案:

答案 0 :(得分:1)

首先,“冻结”意味着在大多数情况下您的代码仍在运行(这可能比您期望的时间更长)。

代码中的问题是,即使没有使用(空),也要通过所有行/列运行循环。

For x = 5 To Rows.Count

将循环限制为实际数据量。找到最后使用的行,例如

Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row 'last used row in column A

并在循环中使用

Dim iRow As Long
For iRow = 5 To LastRow

您也可以使用相同的方法找到最后使用的列

Dim LastCol As Long
LastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column 'last used column in row 1

并在其他循环中使用

Dim iCol As Long
For iCol = 2 To LastCol

所以你最终会得到类似的东西

Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row 'last used row in column A

Dim LastCol As Long
LastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column 'last used column in row 1 

Dim iRow As Long, iCol As Long
For iCol = 2 To LastCol 
    For iRow = 5 To LastRow
        If Application.WorksheetFunction.IsNumber(ws.Cells(iRow, iCol)) = True Then
            ws.Cells(iRow, iCol).NumberFormat = "0.00"
            ws.Cells(iRow, iCol).HorizontalAlignment = xlCenter
            ws.Cells(iRow, iCol).VerticalAlignment = xlCenter
        Else
            Exit For
        End If
    Next iRow
Next iCol

请注意,我给您的计数器变量xy赋予了更有意义的名称,因此您始终知道哪个是行计数器,哪个是列计数器。


替代循环

使用Range.SpecialCells method查找所有带有数字的单元格并立即格式化,应该会更快。

Dim CellsWithNumbers As Range
Set CellsWithNumbers = ws.Cells.SpecialCells(xlCellTypeConstants, xlNumbers)

If Not CellsWithNumbers Is Nothing Then
    With CellsWithNumbers 
        .NumberFormat = "0.00"
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
    End With
End With

如果要查找所有带有数值结果的公式,请使用xlCellTypeFormulas

Dim CellsWithNumbers As Range
Set CellsWithNumbers = ws.Cells.SpecialCells(xlCellTypeFormulas, xlNumbers)

If Not CellsWithNumbers Is Nothing Then
    With CellsWithNumbers 
        .NumberFormat = "0.00"
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
    End With
End With

如果要使用常量和公式编号,请一个接一个地使用。