Проблемы с зацикливанием, которое почти останавливает мою программу - PullRequest
0 голосов
/ 09 июля 2019

У меня есть два утверждения for, которые работают, однако, они проходят через столько ячеек, что заканчивают тем, что замораживают мое превосходство в течение приблизительно 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 Ответ

1 голос
/ 09 июля 2019

Прежде всего, «заморозка» означает, что в большинстве случаев ваш код все еще выполняется (что может занять больше времени, чем вы ожидаете).

Проблема в вашем коде заключается в том, что вы запускаете циклчерез все строки / столбцы, даже если они не используются (пусто).

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 метод , чтобы найти все ячейки с числами и отформатировать их сразу , что должно быть удивительно быстрее.

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

Если вы хотите, чтобы числа с постоянными и формулами использовали оба по порядку.

...