几乎冻结我的程序的 for-loop 语句的问题
Problems with a for-loop statment that almost freezes my program
我有两个有效的 for 语句,但是,它们经过了太多的单元格,最终冻结了我的 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
首先,"freeze" 意味着在大多数情况下您的代码仍然是 运行ning(这可能比您预期的时间更长)。
你的代码中的问题是,你 运行 你循环遍历 all rows/columns 即使它们没有被使用(空)。
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
请注意,我为您的计数器变量 x
和 y
提供了更有意义的名称,因此您始终知道哪个是行计数器,哪个是列计数器。
替代你的循环
使用 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
如果你想要常量和公式数字,一个接一个地使用。
我有两个有效的 for 语句,但是,它们经过了太多的单元格,最终冻结了我的 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
首先,"freeze" 意味着在大多数情况下您的代码仍然是 运行ning(这可能比您预期的时间更长)。
你的代码中的问题是,你 运行 你循环遍历 all rows/columns 即使它们没有被使用(空)。
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
请注意,我为您的计数器变量 x
和 y
提供了更有意义的名称,因此您始终知道哪个是行计数器,哪个是列计数器。
替代你的循环
使用 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
如果你想要常量和公式数字,一个接一个地使用。