Как ускорить работу макроса в Excel 2003?

У меня есть макрос, который копирует данные из одной ячейки в другую и использует VLOOKUP формула, между прочим. Моя таблица содержит около 2000 строк.

когда я запускаю его в Excel 2003, Excel начинает замедляться, поскольку макрос обрабатывает строки 500 и выше. Становится еще хуже, когда он достигает 1000-го ряда. Он занимает более 5 часов.

в Excel 2007, однако, макрос выполняется только полчаса.

может ли кто-нибудь помочь мне найти хороший решение?

5
задан Ellesa
21.02.2023 8:23 Количество просмотров материала 3597
Распечатать страницу

2 ответа

блог, предложенный tumchaaditya, предлагает отличные предложения, которые стоит реализовать, но я сомневаюсь, что они помогут здесь.

для меня ключевой вопрос в том, что макрос замедляется. У вас есть такие команды, как:

StrA = StrA & NewData

ReDim Preserve MyArray(1 To UBound(MyArray)+1)

эти команды делают StrA и MyArray немного больше. Для каждого цикла интерпретатор должен найти место для большего объекта, скопировать данные из старого объекта, а затем освободить старый объект для сборки мусора. Каждый раз, когда вы сделайте StrA или MyArray немного больше, этот процесс занимает больше времени. Я не знаю, почему проблема с Excel 2003; возможно, в Excel 2007 имеет лучший сборщик мусора.

Если вы накапливаете данные из каждой строки, что-то вроде этого намного лучше:

Option Explicit
Type SRowDtl      ' The definition of a User Type must preceed any routines
  Info1 As String
  Info2 As Long
  Info3() As Double
End Type

Sub ProcessRows()

  Dim RowDtl() as SRowDtl
  Dim InxRowDtlCrntMax as Long 

  ReDim RowDtl(NumberOfRows)
  InxRowDtlCrntMax = -1 

  For Each Row ....

     ' Store data from new row
     InxRowDtlCrntMax = InxRowDtlCrntMax+1

     RowDtl(InxRowDtlCrntMax).Info1 = xxx
     RowDtl(InxRowDtlCrntMax).Info2 = yyy
     RowDtl(InxRowDtlCrntMax).Info3(5) = zzz

  Next

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

2
отвечен Tony Dallimore 2023-02-22 16:11

Я не могу диагностировать точную причину, пока не посмотрю на ваш код. Но сейчас, смотрите следующие ссылки: Office.Com - производительность в Excel VBA для кодирования лучшей практики

Ozgrid.com VBA для ускорения ВБА код

они описывают, как оптимизировать производительность любого макроса excel.

  1. ускорить код и остановить мерцание экрана

    Application.ScreenUpdating=False
    Application.ScreenUpdating=True
    
  2. предотвращение расчет во время выполнения кода

    Application.Calculation = xlCalculationManual
    Application.Calculation = xlCalculationAutomatic
    
  3. ускорение кода при наличии событий листа или книги.

    также останавливает бесконечные циклы в событиях

    Application.EnableEvents = False
    Application.EnableEvents = True
    
  4. Используйте оператор With при работе с объектами

    With Range("A1")
        .Font.Bold = True
        .Interior.ColorIndex = 6
    End With
    
  5. используйте VbNullString вместо = ""при необходимости по умолчанию строковую переменную обратно в значение по умолчанию""

    strWords = "Cats"
    strWords = vbNullString
    
  6. вставка формулы относительной в диапазон ячеек: быстрее, чем автозаполнение или копирование

    Range("A1:A200").FormulaR1C1 = "=SUM(RC[1]:RC[5])"
    
  7. по возможности избегайте копирования и вставки (обход буфера обмена)

    Sheet1.Range("A1:A200").Copy Destination:=Sheet2.Range("B1")
    
  8. всегда объявляйте переменные правильно!

    Dim wSheet as Worksheet
    Set wSheet = Sheet1
    Set wSheet = Nothing
    
2
отвечен tumchaaditya 2023-02-22 18:28

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх