Сценарии VBA работают медленно - PullRequest
0 голосов
/ 19 марта 2020

Я новичок в VBA. Мне нужно выполнить код из нескольких листов (l oop). Однако для заполнения колонки требуется около 10 минут. Строк много, поэтому имеет смысл, что код займет некоторое время, но это не должно занять более 3 минут.

Sub Stocks():

    'Add columns where we will calculate the values
    For Each ws In Worksheets

      ws.Cells(1, 9).Value = "Ticker"
      ws.Cells(1, 10).Value = "Yearly Change"
      ws.Cells(1, 11).Value = "Percentage Change"
      ws.Cells(1, 12).Value = "Total Stock Volume"


    'Create a loop to search the next different value on column A and print it on Column I

    Dim ticker_row As Double
    ticker_row = 2

    LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
    For i = 2 To LastRow

        If ws.Cells(i + 1, 1).Value <> Cells(i, 1).Value Then

        ticker_symbol = ws.Cells(i, 1).Value
        ws.Range("I" & ticker_row).Value = ticker_symbol
        ticker_row = ticker_row + 1

        End If

    Next i

    Next ws

End Sub

Ответы [ 3 ]

1 голос
/ 19 марта 2020

Это распространенная проблема для новых программистов VBA. VBA очень медленно работает с диапазонами. Каждый раз, когда вы читаете значение из диапазона, и каждый раз, когда вы записываете значение в диапазон, требуется намного больше времени обработки, чем вы ожидаете.

Однако чтение большого диапазона в переменную массива в VBA считается как только одно действие чтения, цикл по массиву в VBA чрезвычайно быстр, а запись большого массива обратно в диапазон в Excel также считается только одним действием записи. Внесение этого изменения, вероятно, приведет к тому, что вашему коду потребуется от 1 до 2 секунд для запуска.

Есть много сайтов, которые go подробно описывают, как прочитать диапазон значений в переменную массива и сделать обработка в VBA, прежде чем записывать результаты обратно в Excel. Google: "VBA L oop Through Array"

Хорошая пара ссылок:

http://www.cpearson.com/excel/ArraysAndRanges.aspx

https://excelmacromastery.com/excel-vba-array/

0 голосов
/ 20 марта 2020

Попробуйте это:

Sub Stocks():

    Dim ticker_row As Long, data, ws As Worksheet, currentticker, i As Long

    'Add columns where we will calculate the values
    For Each ws In Worksheets

        ws.Cells(1, 9).Value = "Ticker"
        ws.Cells(1, 10).Value = "Yearly Change"
        ws.Cells(1, 11).Value = "Percentage Change"
        ws.Cells(1, 12).Value = "Total Stock Volume"

        'get the data in a 2D array
        data = ws.Range(ws.Range("A2"), _
                        ws.Cells(Rows.Count, 1).End(xlUp)).Value

        ticker_row = 2

        currentticker = Chr(0)
        'loop over the array and check for new ticker value
        For i = 1 To UBound(data, 1)
            If data(i, 1) <> currentticker Then
                'new ticker - add to list
                ws.Range("I" & ticker_row).Value = data(i, 1)
                ticker_row = ticker_row + 1
                currentticker = data(i, 1)
            End If
        Next i

    Next ws

End Sub
0 голосов
/ 19 марта 2020

Когда вы взаимодействуете с объектной моделью Excel, она может быть очень медленной. Существуют две вещи, которые существенно замедляют процесс: 1. обновление экрана после каждого взаимодействия с ячейкой и 2. повторный расчет листа после каждого взаимодействия с ячейкой. Ваш код, кажется, не выполняет никаких вычислений, но вы взаимодействуете с экраном. Я предлагаю вам обернуть ваш код следующим:

В начале всего вашего кода

   'Turn off screen updating and auto recalc
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

В конце всего вашего кода

    'Turn screen updating and auto recalc back on
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic

Если вы хотите получить возможно, вы можете установить переменную для хранения текущего значения Application.Calculation и вернуть его к начальному значению, когда закончите

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...