Excel макрос отключить обновление экрана

Хитрости »

20 Январь 2016              61463 просмотров


Рано или поздно у пишущих на Visual Basic for Applications возникает проблема — код хоть и облегчает жизнь и делает все автоматически, но очень долго. В этой статье я решил собрать несколько простых рекомендаций, которые помогут ускорить работу кода VBA, при этом в некоторых случаях весьма внушительно — в десятки, а то и больше, раз. Основной упор в статье сделан на начинающих, поэтому в начале статьи приводятся самые простые методы оптимизации. Более «глубокие» решения по оптимизации кода приведены в конце статьи, т.к. для применения данных решений необходим достаточный опыт работы в VB и сходу такие методы оптимизации кому-то могут быть непонятны.

  1. Если в коде есть много всяких Activate и Select, тем более в циклах — следует немедленно от них избавиться. Как это сделать я писал в статье: Select и Activate — зачем нужны и нужны ли?
  2. Обязательно на время выполнения кода отключить:
    • автоматический пересчет формул. Чтобы формулы не пересчитывались при каждой манипуляции на листе во время выполнения кода — это может дико тормозить код, если формул много:
      Application.Calculation = xlCalculationManual

      Если во время кода все же нужно пересчитывать какие-то диапазоны, то можно пересчитывать только их:

      Range("A1:C60").Calculate
    • обновление экрана, чтобы действия по изменению значений ячеек и пр. не мелькали. Зачем это надо? Т.к. все эти действия обращаются к графическому процессору и заставляют его трудиться для перерисовки экрана — это может значительно тормозить код:
      Application.ScreenUpdating = False
    • На всякий случай отключаем отслеживание событий. Нужно для того, чтобы Excel не выполнял никаких событийных процедур, которые могут быть в листе, в котором производятся изменения. Как правило это события изменения ячеек, активации листов и пр.:
      Application.EnableEvents = False
    • Если книга выводилась на печать или выводится на печать в процессе выполнения кода, то лучше убрать разбиение на печатные страницы.
      ActiveWorkbook.ActiveSheet.DisplayPageBreaks = False

      если печать производится внутри кода, то эту строку желательно вставить сразу после строки, выводящей лист на печать(при условии, что печать не происходит в цикле. В этом случае — по завершению цикла печати).
      Я советую всегда отключать разбиение на страницы, т.к. это может тормозить весьма значительно, т.к. заставляет при любом изменении на листах обращаться к принтеру и переопределять кол-во и размер печатных страниц. А это порой очень не быстро.

    • На всякий случай можно отключить отображение информации в строке статуса Excel(в каких случаях там вообще отображается информация и зачем можно узнать в статье: Отобразить процесс выполнения). Хоть это и не сильно поедает ресурсы — иногда может все же ускорить работу кода:
      Application.StatusBar = False

    Главное, что следует помнить — все эти свойства необходимо включить обратно после работы кода. Иначе могут быть проблемы с работой внутри Excel. Например, если забыть включить автопересчет формул — большинство формул будут пересчитывать исключительно принудительным методом — после нажатия сочетания клавиш Shift+F9. А если забыть отключить обновление экрана — то есть шанс заблокировать себе возможность работы на листах и книгах. Хотя по умолчанию свойство ScreenUpdating и должно возвращаться в True, если было отключено внутри процедуры — лучше не надеяться на это и привыкать возвращать все свойства на свои места принудительно. По сути все это сведется к нескольким строкам:

    'Возвращаем обновление экрана
    Application.ScreenUpdating = True
    'Возвращаем автопересчет формул
    Application.Calculation = xlCalculationAutomatic
    'Включаем отслеживание событий
    Application.EnableEvents = True

    Как такой код выглядит на практике. Предположим, надо записать в цикле в 10 000 строк значения:

    Sub TestOptimize()
    'отключаем обновление экрана
    Application.ScreenUpdating = False
    'Отключаем автопересчет формул
    Application.Calculation = xlCalculationManual
    'Отключаем отслеживание событий
    Application.EnableEvents = False
    'Отключаем разбиение на печатные страницы
    ActiveWorkbook.ActiveSheet.DisplayPageBreaks = False
     
    'Непосредственно код заполнения ячеек
    Dim lr As Long
    For lr = 1 To 10000
        Cells(lr, 1).Value = lr 'для примера просто пронумеруем строки
    Next
     
    'Возвращаем обновление экрана
    Application.ScreenUpdating = True
    'Возвращаем автопересчет формул
    Application.Calculation = xlCalculationAutomatic
    'Включаем отслеживание событий
    Application.EnableEvents = True
    End Sub

    Разрывы печатных страниц можно не возвращать — они тормозят работу в любом случае.

  3. Следует избегать циклов, вроде Do While для поиска последней ячейки. Часто такую ошибку совершают начинающие. Куда эффективнее и быстрее вычислять последнюю ячейку на всем листе или в конкретном столбце без этого тормозного цикла Do While. Я обычно использую
    lLastRow = Cells(Rows.Count,1).End(xlUp).Row

    другие варианты определения последней ячейки я детально описывал в статье: Как определить последнюю ячейку на листе через VBA?

Для более опытных пользователей VBA я приведу несколько решений по оптимизации кодов в различных ситуациях:

  • Самая хорошая оптимизация кода, если приходится работать с ячейками листа напрямую, обрабатывать их и, возможно, изменять значения, то быстрее все обработки делать в массиве и разом выгружать на листе. Например, код выше по заполнению ячеек номерами будет в этом случае выглядеть так:
    Sub TestOptimize_Array()
    'Непосредственно код заполнения ячеек
    Dim arr, lr As Long
    'запоминаем в массив одним махом все значения 10000 строк первого столбца
    arr = Cells(1, 1).Resize(10000).Value
    'если нужно заполнение для двух и более столбцов
    'arr = Cells(1, 1).Resize(10000, 2).Value
    'или 
    'arr = Range(Cells(1, 1),Cells(10000, 2)).Value
    'или автоматически вычисляем последнюю ячейку и заносим в массив данные, начиная с ячейки А3
    'llastr = Cells(Rows.Count, 1).End(xlUp).Row 'последняя ячейка столбца А
    'arr = Range(Cells(3, 1),Cells(llastr, 2)).Value
    For lr = 1 To 10000
        arr(lr,1) = lr 'заполняем массив порядковыми номерами
    Next
    'Выгружаем обработанный массив обратно на лист в те же ячейки
    Cells(1, 1).Resize(10000).Value = arr
    End Sub

    Но здесь следует учитывать и тот момент, что большие массивы могут просто вызвать переполнение памяти. Наиболее актуально это для 32-битных систем, где на VBA и Excel выделяется памяти меньше, чем в 64-битных системах

  • Если используете быстрый ЕСЛИ — IIF, то замените его на IF … Then … Else
  • Так же лучше вместо Switch() и Choose() применить тот же IF … Then … Else
  • В большинстве случаев проверять строку на «не пусто» лучше через Len(), чем прямое сравнение с пустотой: Len(s)=0 вместо s = «». Связано с тем, что работа со строками значительно медленнее, чем с числовыми данными и Len по сути не подсчитывает длину переменной, а берет это число непосредственно уже готовое из памяти. При сравнении же текста с пустой строкой(«»), VBA сначала создает в памяти переменную нулевой длинны, а уже потом сравнивает с ней наш текст. Поэтому в некоторых случаях так же ускоряет сравнение и в таком виде: s = vbNullString
  • Не применять объединение строк без необходимости. Например, s = «АВ», будет быстрее, чем: s =»А» & «В»
  • Не применять сравнение текстовых величин напрямую. Лучше применить встроенную функцию StrComp:
    If s <> s1 Then будет медленнее, чем
    If StrComp(s, s1, vbBinaryCompare) <> 0
    и тем более, если при сравнении необходимо не учитывать регистр:
    If LCase(s) <> LCase(s1) Then будет медленнее, чем
    If StrComp(s, s1, vbTextCompare) <> 0
  • Циклы For … Next в большинстве случаев работает быстрее, чем цикл Do … Lоор
  • Избегать присвоения переменным типа Variant. Хоть соблазн и велик — этот тип забирает много памяти и в дальнейшем замедляет работу кода. Так же для объектных переменных следует избегать по возможности безликого глобального типа Object и применять конкретный тип:
    Dim rRange as Object, wsSh as Object

    будет медленнее работать, чем:

    Dim rRange as Range, wsSh as Worksheet

    Причина в том, что при объявлении As Object мы не даем VBA практически никакой информации о типе данных, кроме того, что это какой-то объект. И VBA приходится «на лету» внутри кода при каждом обращении к такой переменной определять её конкретный тип(Range, Worksheet, Workbook, Chart и т.д.). Что опять же занимает время.

  • Если работаете с массивами, то можно при объявлении указать это явно:

    вместо

    Такая инициализация происходит быстрее.
    А еще лучше будет при этом еще и тип данных сразу присвоить:

    Dim arr() as string, arr2() as long

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

Конечно, это не все приемы и решения для оптимизации. Но на первых парах должно хватить. Плюс, всегда следует исходить из здравого смысла. Например, если код выполняется за 2 секунды, то вероятно нет смысла его дальше оптимизировать. Конечно, если этот код не из тех, которые просто изменяют значение одной-двух ячеек.


Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика

МЕНЮ САЙТА

  • 1
  • 2
  • 3
  • Главная

    • Информация о сайте

      • О сайте

      • Контакты

      • Карта сайта

      • Книга отзывов

      • Участники

      • Статистика

    • Развите сайта

      • Новости

      • Помочь сайту

    • Друзья

    • FAQ

  • Excel

    • Приемы работы

      • Рабочая область

      • Формулы

      • Сводные таблицы

      • Форматирование

      • Выпадающие списки

      • Примечания

      • Гиперссылки

    • Инструменты и настройки

      • Инструменты

      • Тонкая настройка

    • Импорт данных

    • Интеграция

      • Приложения офиса

  • Готовые решения

    • Excel

      • Формулы

      • Сводные таблицы

      • Диаграммы

      • Полезные приемы

    • VBA

      • Процедуры

      • Пользовательские функции

      • Полезные приемы

  • Форумы

    • Вопросы и решения

      • Вопросы по Excel

      • Вопросы по VBA

      • Готовые решения

      • Excel и другие приложения

    • Работа и общение

      • Неформальное общение

      • Мозговой штурм

      • Работа/Фриланс

    • Работа форума и сайта

      • Вопросы по работе форума и сайта

      • Объявления администрации

  • Библиотека

    • Книги по Excel

      • Функции и формулы

      • Графики и диаграммы

      • Сводные таблицы

      • Excel и VBA

    • Книги по VBA

      • Применение VBA в Excel

      • Программирование на VBA

    • Разное

      • Сборники книг

      • Книги для студентов ВУЗов

      • Специализированные книги

  • Видеосалон

    • Видео к статьям

    • Видеофайлы

  • Справочники

    • Функции листа Excel

    • Функции VBA

  • Разработчик

    • Код

    • Надстройки

    • Элементы управления

    • XLM

    • Программы

КАТЕГОРИИ РАЗДЕЛА

Процедуры
[13]

Пользовательские функции
[9]

Полезные приёмы
[45]

ОПРОСЫ

Какой версией Excel Вы пользуетесь?

Office 365

Excel 2021

Excel 2019

Excel 2016

Excel 2013

Excel 2010

Excel 2007

Excel 2003

Excel 2002

Excel 2000

Excel 1997 или ранее

Mac Excel

[ Результаты · Все опросы ]

Всего ответов: 55669

Главная » Готовые решения » VBA » Полезные приёмы

Отключение обновления экрана для ускорения работы макроса

30.07.2013, 11:54
Sub excample()
Application.ScreenUpdating = False
'Здесь находится Ваш код
Application.ScreenUpdating = True
End Sub 
  • 1
  • 2
  • 3
  • 4
  • 5

Добавил: Serge_007 |

| Теги: отключить обновление экрана, Application.ScreenUpdating, ускорения работы макроса

Просмотров: 32720

| Рейтинг: 4.3/6

Всего комментариев: 0

Добавлять комментарии могут только зарегистрированные пользователи.

[

Регистрация

|

Вход

]

Содержание

  1. VBA — отключить обновление экрана
  2. Отключить обновление экрана
  3. Включить обновление экрана
  4. Пример обновления экрана VBA
  5. Обновление экрана Обновить
  6. Настройки VBA — код ускорения
  7. Как ускорить и оптимизировать код VBA
  8. Excel vba отключить обновление экрана
  9. Как ускорить и оптимизировать код VBA
  10. Как отключить обновление экрана для другого приложения (блокнот)
  11. How to dou
  12. Расчет листового листа
  13. Отключение обновления экрана листа
  14. Отключение обновлений строки состояния
  15. Указание Excel на игнорирование событий
  16. Скрытие разрывов страниц
  17. Приостановка обновлений сводной таблицы
  18. Очистка от копирования и вставки
  19. Использование оператора With
  20. Избегание метода Select
  21. Ограничение поездок на рабочий лист
  22. Excel vba: Почему обновление экрана не обновляется, прежде чем отключать обновление экрана.
  23. Копилка знаний…..
  24. Ускоряем выполнение VBA кода, а так же убираем ненужные уведомления (всплывающие окна).
  25. Навигация по записям
  26. Добавить комментарий Отменить ответ

VBA — отключить обновление экрана

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

Отключить обновление экрана

1. Чтобы отключить ScreenUpdating, в начале кода поместите эту строку:

1 Application.ScreenUpdating = False

Включить обновление экрана

2. Чтобы снова включить ScreenUpdating, в конце кода поместите эту строку:

1 Application.ScreenUpdating = True

Пример обновления экрана VBA

Тогда ваша процедура будет выглядеть так:

1234567891011 Sub ScreenUpdating_Example ()Application.ScreenUpdating = False’Сделай что-нибудьДиапазон («a1»). Копировать диапазон («b1»)Диапазон («a2»). Копировать диапазон («b2»)Диапазон («a3»). Копировать диапазон («b3»)Application.ScreenUpdating = TrueКонец подписки

Обновление экрана Обновить

Отключение ScreenUpdating заставит ваш код VBA работать НАМНОГО быстрее, но это также сделает вашу работу более профессиональной. Конечные пользователи обычно не хотят видеть закулисные действия ваших процедур (особенно, когда процедура выполняется медленно). Кроме того, вы можете не захотеть, чтобы конечные пользователи видели скрытые функции (например, скрытые рабочие листы). Я рекомендую отключить (и снова включить) ScreenUpdating практически во всех ваших процедурах.

Однако бывают случаи, когда вы хотите, чтобы экран обновился. Чтобы обновить экран, вам нужно будет временно снова включить ScreenUpdating (нет команды «обновить» экрана):

123 Application.ScreenUpdating = True’Сделай что-нибудьApplication.ScreenUpdating = False

Настройки VBA — код ускорения

Есть несколько других настроек, с которыми можно поиграть, чтобы улучшить скорость вашего кода.

Отключение автоматических вычислений может ОГРОМНО изменить скорость:

1 Application.Calculation = xlManual

Отключение строки состояния также имеет небольшое значение:

1 Application.DisplayStatusBar = False

Если ваша рабочая книга содержит события, вам обычно следует отключать события в начале процедуры:

1 Application.EnableEvents = False

Наконец, ваш код VBA может замедлиться, когда Excel пытается повторно вычислить разрывы страниц (Примечание: не все процедуры будут затронуты). Чтобы отключить отображение разрывов страниц, используйте эту строку кода:

Источник

Как ускорить и оптимизировать код VBA

  1. Если в коде есть много всяких Activate и Select , тем более в циклах — следует немедленно от них избавиться. Как это сделать я писал в статье: Select и Activate — зачем нужны и нужны ли?
  2. Обязательно на время выполнения кода отключить:
    • автоматический пересчет формул . Чтобы формулы не пересчитывались при каждой манипуляции на листе во время выполнения кода — это может дико тормозить код, если формул много:

Если во время кода все же нужно пересчитывать какие-то диапазоны, то можно пересчитывать только их:

если печать производится внутри кода, то эту строку желательно вставить сразу после строки, выводящей лист на печать(при условии, что печать не происходит в цикле. В этом случае — по завершению цикла печати).
Я советую всегда отключать разбиение на страницы, т.к. это может тормозить весьма значительно, т.к. заставляет при любом изменении на листах обращаться к принтеру и переопределять кол-во и размер печатных страниц. А это порой очень не быстро.
На всякий случай можно отключить отображение информации в строке статуса Excel (в каких случаях там вообще отображается информация и зачем можно узнать в статье: Отобразить процесс выполнения). Хоть это и не сильно поедает ресурсы — иногда может все же ускорить работу кода:

Главное, что следует помнить — все эти свойства необходимо включить обратно после работы кода . Иначе могут быть проблемы с работой внутри Excel. Например, если забыть включить автопересчет формул — большинство формул будут пересчитывать исключительно принудительным методом — после нажатия сочетания клавиш Shift + F9 . А если забыть отключить обновление экрана — то есть шанс заблокировать себе возможность работы на листах и книгах. Хотя по умолчанию свойство ScreenUpdating и должно возвращаться в True, если было отключено внутри процедуры — лучше не надеяться на это и привыкать возвращать все свойства на свои места принудительно. По сути все это сведется к нескольким строкам:

‘Возвращаем обновление экрана Application.ScreenUpdating = True ‘Возвращаем автопересчет формул Application.Calculation = xlCalculationAutomatic ‘Включаем отслеживание событий Application.EnableEvents = True

Как такой код выглядит на практике. Предположим, надо записать в цикле в 10 000 строк значения:

Sub TestOptimize() ‘отключаем обновление экрана Application.ScreenUpdating = False ‘Отключаем автопересчет формул Application.Calculation = xlCalculationManual ‘Отключаем отслеживание событий Application.EnableEvents = False ‘Отключаем разбиение на печатные страницы ActiveWorkbook.ActiveSheet.DisplayPageBreaks = False ‘Непосредственно код заполнения ячеек Dim lr As Long For lr = 1 To 10000 Cells(lr, 1).Value = lr ‘для примера просто пронумеруем строки Next ‘Возвращаем обновление экрана Application.ScreenUpdating = True ‘Возвращаем автопересчет формул Application.Calculation = xlCalculationAutomatic ‘Включаем отслеживание событий Application.EnableEvents = True End Sub

Разрывы печатных страниц можно не возвращать — они тормозят работу в любом случае.
Следует избегать циклов, вроде Do While для поиска последней ячейки . Часто такую ошибку совершают начинающие. Куда эффективнее и быстрее вычислять последнюю ячейку на всем листе или в конкретном столбце без этого тормозного цикла Do While. Я обычно использую

другие варианты определения последней ячейки я детально описывал в статье: Как определить последнюю ячейку на листе через VBA?

Для более опытных пользователей VBA я приведу несколько решений по оптимизации кодов в различных ситуациях:

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

Sub TestOptimize_Array() ‘Непосредственно код заполнения ячеек Dim arr, lr As Long ‘запоминаем в массив одним махом все значения 10000 строк первого столбца arr = Cells(1, 1).Resize(10000).Value ‘если нужно заполнение для двух и более столбцов ‘arr = Cells(1, 1).Resize(10000, 2).Value ‘или ‘arr = Range(Cells(1, 1),Cells(10000, 2)).Value ‘или автоматически вычисляем последнюю ячейку и заносим в массив данные, начиная с ячейки А3 ‘llastr = Cells(Rows.Count, 1).End(xlUp).Row ‘последняя ячейка столбца А ‘arr = Range(Cells(3, 1),Cells(llastr, 2)).Value For lr = 1 To 10000 arr(lr,1) = lr ‘заполняем массив порядковыми номерами Next ‘Выгружаем обработанный массив обратно на лист в те же ячейки Cells(1, 1).Resize(10000).Value = arr End Sub

Но здесь следует учитывать и тот момент, что большие массивы могут просто вызвать переполнение памяти. Наиболее актуально это для 32-битных систем, где на VBA и Excel выделяется памяти меньше, чем в 64-битных системах

  • Если используете быстрый ЕСЛИ — IIF , то замените его на IF . Then . Else
  • Так же лучше вместо Switch() и Choose() применить тот же IF . Then . Else
  • В большинстве случаев проверять строку на «не пусто» лучше через Len() , чем прямое сравнение с пустотой: Len(s)=0 вместо s = «» . Связано с тем, что работа со строками значительно медленнее, чем с числовыми данными и Len по сути не подсчитывает длину переменной, а берет это число непосредственно уже готовое из памяти. При сравнении же текста с пустой строкой(«»), VBA сначала создает в памяти переменную нулевой длинны, а уже потом сравнивает с ней наш текст. Поэтому в некоторых случаях так же ускоряет сравнение и в таком виде: s = vbNullString
  • Не применять объединение строк без необходимости. Например, s = «АВ» , будет быстрее, чем: s =»А» & «В»
  • Не применять сравнение текстовых величин напрямую. Лучше применить встроенную функцию StrComp:
    If s <> s1 Then будет медленнее, чем
    If StrComp(s, s1, vbBinaryCompare) <> 0
    и тем более, если при сравнении необходимо не учитывать регистр:
    If LCase(s) <> LCase(s1) Then будет медленнее, чем
    If StrComp(s, s1, vbTextCompare) <> 0
  • Циклы For … Next в большинстве случаев работает быстрее, чем цикл Do . Lоор
  • Избегать присвоения переменным типа Variant . Хоть соблазн и велик — этот тип забирает много памяти и в дальнейшем замедляет работу кода. Так же для объектных переменных следует избегать по возможности безликого глобального типа Object и применять конкретный тип:

    Dim rRange as Object, wsSh as Object

    будет медленнее работать, чем:

    Dim rRange as Range, wsSh as Worksheet

    Причина в том, что при объявлении As Object мы не даем VBA практически никакой информации о типе данных, кроме того, что это какой-то объект. И VBA приходится «на лету» внутри кода при каждом обращении к такой переменной определять её конкретный тип(Range, Worksheet, Workbook, Chart и т.д.). Что опять же занимает время.
    Если работаете с массивами, то можно при объявлении указать это явно:

    Такая инициализация происходит быстрее.
    А еще лучше будет при этом еще и тип данных сразу присвоить:

    Dim arr() as string, arr2() as long

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

    Конечно, это не все приемы и решения для оптимизации. Но на первых парах должно хватить. Плюс, всегда следует исходить из здравого смысла . Например, если код выполняется за 2 секунды, то вероятно нет смысла его дальше оптимизировать. Конечно, если этот код не из тех, которые просто изменяют значение одной-двух ячеек.

    Статья помогла? Поделись ссылкой с друзьями!

    Источник

    Excel vba отключить обновление экрана

    Как ускорить и оптимизировать код VBA

    1. Если в коде есть много всяких Activate и Select , тем более в циклах — следует немедленно от них избавиться. Как это сделать я писал в статье: Select и Activate — зачем нужны и нужны ли?
    2. Обязательно на время выполнения кода отключить:
      • автоматический пересчет формул . Чтобы формулы не пересчитывались при каждой манипуляции на листе во время выполнения кода — это может дико тормозить код, если формул много:

    если печать производится внутри кода, то эту строку желательно вставить сразу после строки, выводящей лист на печать(при условии, что печать не происходит в цикле. В этом случае — по завершению цикла печати).
    На всякий случай можно отключить отображение информации в строке статуса Excel (в каких случаях там вообще отображается информация и зачем можно узнать в статье: Отобразить процесс выполнения). Хоть это и не сильно поедает ресурсы — иногда может все же ускорить работу кода:

    Главное, что следует помнить — все эти свойства необходимо включить обратно после работы кода . Иначе могут быть проблемы с работой внутри Excel. Например, если забыть включить автопересчет формул — большинство формул будут пересчитывать исключительно принудительным методом — Shift+F9. А если забыть отключить обновление экрана — то есть шанс заблокировать себе возможность работы на листах и книгах. Хотя по умолчанию свойство ScreenUpdating и должно возвращаться в True, если было отключено внутри процедуры — лучше не надеяться на это и привыкать возвращать все свойства на свои места принудительно. По сути все это сведется к нескольким строкам:

    ‘Возвращаем обновление экрана Application.ScreenUpdating = True ‘Возвращаем автопересчет формул Application.Calculation = xlCalculationAutomatic ‘Включаем отслеживание событий Application.EnableEvents = True

    Как такой код выглядит на практике. Предположим, надо записать в цикле в 10 000 строк значения:

    Sub TestOptimize() ‘отключаем обновление экрана Application.ScreenUpdating = False ‘Отключаем автопересчет формул Application.Calculation = xlCalculationManual ‘Отключаем отслеживание событий Application.EnableEvents = False ‘Отключаем разбиение на печатные страницы ActiveWorkbook.ActiveSheet.DisplayPageBreaks = False ‘Непосредственно код заполнения ячеек Dim lr As Long For lr = 1 To 10000 Cells(lr, 1).Value = lr ‘для примера просто пронумеруем строки Next ‘Возвращаем обновление экрана Application.ScreenUpdating = True ‘Возвращаем автопересчет формул Application.Calculation = xlCalculationAutomatic ‘Включаем отслеживание событий Application.EnableEvents = True End Sub

    Разрывы печатных страниц можно не возвращать — они тормозят работу в любом случае.
    Следует избегать циклов, вроде Do While для поиска последней ячейки . Часто такую ошибку совершают начинающие. Куда эффективнее и быстрее вычислять последнюю ячейку на всем листе или в конкретном столбце без этого тормозного цикла Do While. Я обычно использую

    другие варианты определения последней ячейки я детально описывал в статье: Как определить последнюю ячейку на листе через VBA?

    Для более опытных пользователей VBA я приведу несколько решений по оптимизации кодов в различных ситуациях:

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

    Sub TestOptimize_Array() ‘Непосредственно код заполнения ячеек Dim arr, lr As Long ‘запоминаем в массив одним махом все значения 10000 строк первого столбца arr = Cells(1, 1).Resize(10000).Value ‘если нужно заполнение для двух и более столбцов ‘arr = Cells(1, 1).Resize(10000, 2).Value ‘или ‘arr = Range(Cells(1, 1),Cells(10000, 2)).Value ‘или автоматически вычисляем последнюю ячейку и заносим в массив данные, начиная с ячейки А3 ‘llastr = Cells(Rows.Count, 1).End(xlUp).Row ‘последняя ячейка столбца А ‘arr = Range(Cells(3, 1),Cells(llastr, 2)).Value For lr = 1 To 10000 arr(lr,1) = lr ‘заполняем массив порядковыми номерами Next ‘Выгружаем обработанный массив обратно на лист в те же ячейки Cells(1, 1).Resize(10000).Value = arr End Sub

    Но здесь следует учитывать и тот момент, что большие массивы могут просто вызвать переполнение памяти. Наиболее актуально это для 32-битных систем, где на VBA и Excel выделяется памяти меньше, чем в 64-битных системах

  • Если используете быстрый ЕСЛИ — IIF , то замените его на IF . Then . Else
  • Так же лучше вместо Switch() и Choose() применить тот же IF . Then . Else
  • В большинстве случаев проверять строку на «не пусто» лучше через Len() , чем прямое сравнение с пустотой: Len(s)=0 вместо s = «» . Связано с тем, что работа со строками значительно медленнее, чем с числовыми данными
  • Не применять объединение строк без необходимости. Например, s = «АВ» , будет быстрее, чем: s =»А» & «В»
  • Не применять сравнение текстовых величин напрямую. Лучше применить встроенную функцию StrComp:
    If s <> s1 Then будет медленнее, чем
    If StrComp(s, s1, vbBinaryCompare) = 0
    и тем более, если при сравнении необходимо не учитывать регистр:
    If LCase(s) <> LCase(s1) Then будет медленнее, чем
    If StrComp(s, s1, vbTextCompare) = 0
  • Циклы For … Next в большинстве случаев работает быстрее, чем цикл Do . Lоор
  • Избегать присвоения переменным типа Variant . Хоть соблазн и велик — этот тип забирает много памяти и в дальнейшем замедляет работу кода. Так же для объектных переменных следует избегать по возможности безликого глобального типа Object и применять конкретный тип:

    Как отключить обновление экрана для другого приложения (блокнот)

    4 Badan [2016-12-09 12:55:00]

    Я написал макрос в vba, который открывает текстовый файл с помощью блокнота, выбирает все txt и копирует его в Excel. Я должен обрабатывать около 100 файлов ежедневно таким образом, и я хочу избавиться от мигающих изображений, которые я наблюдаю. Код работает, но проблема в том, что команда

    Не работает с записной книжкой. Я могу использовать только обычный фокус, иначе код не работает. Как я могу выполнить код ниже, не заметив, что файл блокнота открыт и обработан?

    Я не мог найти никакого рабочего решения.

    excel-vba csv notepad

    Вот быстрый ответ, как запустить Notepad, но скрыть окно и использовать vbHide вместо vbNormalFocus в вашей команде Shell :

    Но я очень сомневаюсь, что SendKeys будет работать над невидимым окном.

    Итак, это не ответ на вопрос, но вы считаете, что используете FileSystemObject и просто читаете файл без фактического открытия Notepad.exe ?

    Код будет работать с акцентированными символами, например. мой тестовый текстовый файл:

    Насколько я знаю, Application.ScreenUpdating применим только к вашему сеансу Excel, а не к другим программам, запущенным в Windows. Таким образом, чтобы фактически остановить появление этих окон — , но все еще можно прочитать содержимое окна, вам придется сделать что-то достаточно сложное с Windows API. Использовать FileSystemObject много, проще.

    0 Badan [2016-12-12 11:37:00]

    Наконец-то я нашел очень элегантное решение, которое может обрабатывать внешние приложения. Все, что вам нужно, это Роберт Шутт для написания этого шедеврального кода. Это делает блокнот размером 1 пиксель, поэтому никаких мигающих изображений не наблюдается. Это выглядит довольно сложно для меня, но это спасло мой день:

    How to dou

    Поскольку ваши макросы Excel становятся все более надежными и сложными, вы можете обнаружить, что они теряют производительность. При обсуждении макросов слово производительность обычно является синонимом speed . Скорость — это то, как быстро ваши процедуры VBA выполняют свои намеченные задачи. Ниже приведены десять способов помочь сохранить макросы Excel с оптимальным уровнем производительности.

    Расчет листового листа

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

    Вы можете использовать Приложение. Свойство Calculate, чтобы сообщить Excel переключиться на ручной режим расчета. Когда рабочая книга находится в режиме ручного вычисления, рабочая книга не будет пересчитываться до тех пор, пока вы явно не выполните расчет, нажав клавишу F9.

    Поместите Excel в ручной режим расчета, запустите свой код и затем вернитесь в автоматический режим расчета.

    Установка режима вычисления обратно в xlCalculationAutomatic автоматически приведет к пересчету рабочего листа, поэтому нет необходимости нажимать клавишу F9 после запуска макроса.

    Отключение обновления экрана листа

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

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

    После того, как свойство ScreenUpdating вернётся к True, Excel автоматически вызовет перерисовку экрана.

    Отключение обновлений строки состояния

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

    Важно отметить, что отключить обновление экрана отдельно от выключения отображения строки состояния. Строка состояния будет продолжать обновляться, даже если вы отключите обновление экрана. Вы можете использовать Приложение. Свойство DisplayStatusBar для временного отключения любых обновлений строки состояния, что еще больше улучшает производительность вашего макроса:

    Указание Excel на игнорирование событий

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

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

    Вы можете добавить еще один уровень повышения производительности, используя свойство EnableEvents, чтобы заставить Excel игнорировать события во время запуска макроса.

    Перед запуском макроса установите для свойства EnableEvents значение False. После того, как ваш макрокоманда закончен, вы можете вернуть свойство EnableEvents значение True.

    Скрытие разрывов страниц

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

    Вы можете избежать этого поведения, просто скрыв разрывы страниц перед запуском своего макроса.

    Установите для свойства листа DisplayPageBreaks значение False, чтобы скрыть разрывы страниц. Если вы хотите продолжать показывать разрывы страниц после запуска макроса, установите для свойства листа DisplayPageBreaks значение True.

    Приостановка обновлений сводной таблицы

    Если ваш макрос управляет сводными таблицами, которые содержат большие источники данных, вы можете испытывать слабую производительность при выполнении таких операций, как динамическое добавление или перемещение полей поворота.

    Вы можете улучшить производительность своего макроса, приостановив перерасчет сводной таблицы до тех пор, пока не будут сделаны все изменения поля поворота. Просто установите PivotTable. Свойство ManualUpdate для True, чтобы отложить пересчет, запустите свой макрокоманд и затем установите сводную таблицу. Свойство ManualUpdate вернется к False, чтобы вызвать пересчет.

    Очистка от копирования и вставки

    Важно помнить, что хотя Macro Recorder экономит время, написав код VBA для вас, он не всегда записывает наиболее эффективный код. Ярким примером является то, как Macro Recorder захватывает любое действие копирования и вставки, которое вы выполняете во время записи.

    Вы можете немного увеличить свои макросы, вырезав посредника и выполнив прямую копию из одной ячейки в ячейку назначения. Этот альтернативный код использует аргумент Destination для обхода буфера обмена и копирования содержимого ячейки A1 непосредственно в ячейку B1.

    Если вам нужно скопировать только значения (не форматирование или формулы), вы можете повысить производительность еще больше, избегая при этом метода копирования. Просто установите значение ячейки назначения на то же значение, которое находится в исходной ячейке. Этот метод примерно в 25 раз быстрее, чем при использовании метода Copy:

    Если вам нужно скопировать только формулы из одной ячейки в другую (а не значения или форматирование), вы можете установить формулу ячейки назначения той же формуле, содержащейся в исходной ячейке:

    Использование оператора With

    При записи макросов вы часто будете манипулировать одним и тем же объектом более одного раза. Вы можете сэкономить время и повысить производительность, используя оператор With для выполнения нескольких действий на данном объекте за один снимок.

    Оператор With, используемый в следующем примере, сообщает Excel применять все изменения форматирования за один раз:

    Привычка к чередованию действий в операторы With не только ускорит выполнение макросов, но и упростит чтение вашего макрокода.

    Избегание метода Select

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

    После записи ваших макросов, сделайте привычкой изменять сгенерированный код, чтобы удалить методы Select. В этом случае оптимизированный код будет выглядеть следующим образом:

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

    Ограничение поездок на рабочий лист

    Еще один способ ускорить работу с макросами — ограничить количество ссылок на данные рабочего листа в вашем коде. Всегда менее эффективно захватывать данные из рабочего листа, чем из памяти. Другими словами, ваши макросы будут работать намного быстрее, если им не придется многократно взаимодействовать с рабочим листом.

    Например, следующий простой код заставляет VBA непрерывно возвращаться к листам («Лист1»). Range («A1»), чтобы получить номер, необходимый для сравнения, выполняемого в инструкции If:

    Более эффективным способом является сохранение значения в листах («Лист1»). Range («A1») к переменной MyMonth. Таким образом, код ссылается на переменную MyMonth вместо рабочего листа:

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

    Excel vba: Почему обновление экрана не обновляется, прежде чем отключать обновление экрана.

    У меня есть суб, который начинается с вызова другого суб (который редактирует ячейки рабочей книги), а затем отключает обновление экрана и предупреждения. Дело в том, что первый юг, который редактирует книгу, находится перед вторым югу, ячейка не обновляется.

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

    EDIT: обновление Экран уже верно, когда mainSub начинается; Комментируя setupApp sub out , он помогает, потому что он явно запускается раньше, чем ячейки редактируются несколько позже.

    Создан 30 авг. 17 2017-08-30 13:36:04 Ans

    Есть ли приложение.ScreenUpdating = False в getStateNames? – Moosli 30 авг. 17 2017-08-30 14:27:07

    @Moosli Нет, нет – Ans 30 авг. 17 2017-08-30 14:32:24

    Хорошо, давайте отправимся в Кахт. Вы можете увидеть это в комментариях в моем ответе. – Moosli 30 авг. 17 2017-08-30 14:36:50

    Я действительно не понимаю, почему это не работает. Но вы можете попытаться вызвать SetupApp с помощью инструкции If. Для этого вам нужно привязать editSub к функции и в конце просто вернуть истинное значение. Что-то вроде этого:

    Второе решение

    Вы можете попытаться форсировать события с DoEvents для обновления экрана.

    Или Помещенный DoEvents сразу после того, как вы написаны в клетках.

    Если это не работает, вы можете попробовать метод Wait:

    Первое решение

    ли судимое вам повернуть ScreenUpdating на Перед выполнением Sub?

    Создан 30 авг. 17 2017-08-30 13:50:20 Moosli

    Не помогает. Экран updatin ** уже ** истинен при запуске суб. Комментирование второй суб ** помогает **, потому что она, очевидно, выполняется раньше, чем нужно. – Ans 30 авг. 17 2017-08-30 13:51:44

    Сколько кода в editSub? Becuase, если есть только несколько строк, может быть, что UpdateEvent должен замедляться, и он будет отключен до обновления экрана. – Moosli 30 авг. 17 2017-08-30 13:54:33

    Довольно много строк. Он берет некоторые данные, проверяет их, добавляет в массив и только затем редактирует ячейки со значениями из массива. – Ans 30 авг. 17 2017-08-30 13:56:28

    @Ans Хорошо, я добавил мой Awnser – Moosli 30 авг. 17 2017-08-30 14:05:06

    К сожалению, ни то, ни другое не помогает . Ожидание просто приводит к более длительному времени выполнения, в то время как ячейки все еще пусты, «DoEvents» ничего не влияет. – Ans 30 авг. 17 2017-08-30 14:14:20

    Можете ли вы опубликовать код из editSup? – Moosli 30 авг. 17 2017-08-30 14:19:49

    Я редактировал вопрос. – Ans 30 авг. 17 2017-08-30 14:22:53

    Копилка знаний…..

    Ускоряем выполнение VBA кода, а так же убираем ненужные уведомления (всплывающие окна).

    Для того чтобы ускорить выполнение VBA кода в Excel, а так же скрыть мерцание экрана, лишние пересчёты формул, различные уведомления, на которые нужно нажать для продолжения выполнения кода и которые часто раздражают (подтверждение открытия файлов, данные сохраненные как текст и тд), а так же убрать не нужные пересчет формул который происходят постоянно при обновлении данных на которые они ссылаются можно использовать следующие команды, которые нужно добавить или в начало кода или перед конкретным нужным участком (если вы в курсе).

    Excel.Application.ScreenUpdating = False ‘убирает обновление экрана. Можно использовать почти всегда — лишняя нагрузка на процессор.

    Excel.Application.DisplayAlerts = False ‘убирает всплывающие окна. Совсем. Использовать аккуратно.

    Excel.Application.EnablEevents = False ‘убирает обработку событий в Excel. События необходимо отключать для исключения зацикливания или выполнения незапланированных действий. Например при внесении одним макросом значения на лист и лишнего (не нужного) выполнения другого макроса по обработки события добавления значения на лист — который, как вариант, рассчитан на ручной ввод. Использовать только при необходимости.

    Excel.Application.Calculation = xlCalculationManual ‘убирает автопересчет формул и зависимых от них объектов. Можно и нужно использовать почти всегда — лишняя нагрузка на процессор, особенно если формулы использующие массивы или поиск.

    Не забываем ОБЯЗАТЕЛЬНО все вернуть обратно, чтобы пользователи не ругались = ) :

    Excel.Application.ScreenUpdating = True
    Excel.Application.DisplayAlerts = True
    Excel.Application.EnableEvents = True
    Excel.Application.Calculation = xlCalculationAutomatic

    Навигация по записям

    Добавить комментарий Отменить ответ

    Для отправки комментария вам необходимо авторизоваться.

    Источник

  • Содержание

    • Отключить обновление экрана
    • Включить обновление экрана
    • Пример обновления экрана VBA
    • Обновление экрана Обновить

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

    Отключить обновление экрана

    1. Чтобы отключить ScreenUpdating, в начале кода поместите эту строку:

    1 Application.ScreenUpdating = False

    Включить обновление экрана

    2. Чтобы снова включить ScreenUpdating, в конце кода поместите эту строку:

    1 Application.ScreenUpdating = True

    Тогда ваша процедура будет выглядеть так:

    1234567891011 Sub ScreenUpdating_Example ()Application.ScreenUpdating = False’Сделай что-нибудьДиапазон («a1»). Копировать диапазон («b1»)Диапазон («a2»). Копировать диапазон («b2»)Диапазон («a3»). Копировать диапазон («b3»)Application.ScreenUpdating = TrueКонец подписки

    Обновление экрана Обновить

    Отключение ScreenUpdating заставит ваш код VBA работать НАМНОГО быстрее, но это также сделает вашу работу более профессиональной. Конечные пользователи обычно не хотят видеть закулисные действия ваших процедур (особенно, когда процедура выполняется медленно). Кроме того, вы можете не захотеть, чтобы конечные пользователи видели скрытые функции (например, скрытые рабочие листы). Я рекомендую отключить (и снова включить) ScreenUpdating практически во всех ваших процедурах.

    Однако бывают случаи, когда вы хотите, чтобы экран обновился. Чтобы обновить экран, вам нужно будет временно снова включить ScreenUpdating (нет команды «обновить» экрана):

    123 Application.ScreenUpdating = True’Сделай что-нибудьApplication.ScreenUpdating = False

    Настройки VBA — код ускорения

    Есть несколько других настроек, с которыми можно поиграть, чтобы улучшить скорость вашего кода.

    Отключение автоматических вычислений может ОГРОМНО изменить скорость:

    1 Application.Calculation = xlManual

    Отключение строки состояния также имеет небольшое значение:

    1 Application.DisplayStatusBar = False

    Если ваша рабочая книга содержит события, вам обычно следует отключать события в начале процедуры:

    1 Application.EnableEvents = False

    Наконец, ваш код VBA может замедлиться, когда Excel пытается повторно вычислить разрывы страниц (Примечание: не все процедуры будут затронуты). Чтобы отключить отображение разрывов страниц, используйте эту строку кода:

    1 ActiveSheet.DisplayPageBreaks = False

    Вы поможете развитию сайта, поделившись страницей с друзьями

    если печать производится внутри кода, то эту строку желательно вставить сразу после строки, выводящей лист на печать(при условии, что печать не происходит в цикле. В этом случае — по завершению цикла печати).
    На всякий случай можно отключить отображение информации в строке статуса Excel (в каких случаях там вообще отображается информация и зачем можно узнать в статье: Отобразить процесс выполнения). Хоть это и не сильно поедает ресурсы — иногда может все же ускорить работу кода:

    Главное, что следует помнить — все эти свойства необходимо включить обратно после работы кода . Иначе могут быть проблемы с работой внутри Excel. Например, если забыть включить автопересчет формул — большинство формул будут пересчитывать исключительно принудительным методом — Shift+F9. А если забыть отключить обновление экрана — то есть шанс заблокировать себе возможность работы на листах и книгах. Хотя по умолчанию свойство ScreenUpdating и должно возвращаться в True, если было отключено внутри процедуры — лучше не надеяться на это и привыкать возвращать все свойства на свои места принудительно. По сути все это сведется к нескольким строкам:

    ‘Возвращаем обновление экрана Application.ScreenUpdating = True ‘Возвращаем автопересчет формул Application.Calculation = xlCalculationAutomatic ‘Включаем отслеживание событий Application.EnableEvents = True

    Как такой код выглядит на практике. Предположим, надо записать в цикле в 10 000 строк значения:

    Sub TestOptimize() ‘отключаем обновление экрана Application.ScreenUpdating = False ‘Отключаем автопересчет формул Application.Calculation = xlCalculationManual ‘Отключаем отслеживание событий Application.EnableEvents = False ‘Отключаем разбиение на печатные страницы ActiveWorkbook.ActiveSheet.DisplayPageBreaks = False ‘Непосредственно код заполнения ячеек Dim lr As Long For lr = 1 To 10000 Cells(lr, 1).Value = lr ‘для примера просто пронумеруем строки Next ‘Возвращаем обновление экрана Application.ScreenUpdating = True ‘Возвращаем автопересчет формул Application.Calculation = xlCalculationAutomatic ‘Включаем отслеживание событий Application.EnableEvents = True End Sub

    Разрывы печатных страниц можно не возвращать — они тормозят работу в любом случае.
    Следует избегать циклов, вроде Do While для поиска последней ячейки . Часто такую ошибку совершают начинающие. Куда эффективнее и быстрее вычислять последнюю ячейку на всем листе или в конкретном столбце без этого тормозного цикла Do While. Я обычно использую

    другие варианты определения последней ячейки я детально описывал в статье: Как определить последнюю ячейку на листе через VBA?

    Для более опытных пользователей VBA я приведу несколько решений по оптимизации кодов в различных ситуациях:

    Sub TestOptimize_Array() ‘Непосредственно код заполнения ячеек Dim arr, lr As Long ‘запоминаем в массив одним махом все значения 10000 строк первого столбца arr = Cells(1, 1).Resize(10000).Value ‘если нужно заполнение для двух и более столбцов ‘arr = Cells(1, 1).Resize(10000, 2).Value ‘или ‘arr = Range(Cells(1, 1),Cells(10000, 2)).Value ‘или автоматически вычисляем последнюю ячейку и заносим в массив данные, начиная с ячейки А3 ‘llastr = Cells(Rows.Count, 1).End(xlUp).Row ‘последняя ячейка столбца А ‘arr = Range(Cells(3, 1),Cells(llastr, 2)).Value For lr = 1 To 10000 arr(lr,1) = lr ‘заполняем массив порядковыми номерами Next ‘Выгружаем обработанный массив обратно на лист в те же ячейки Cells(1, 1).Resize(10000).Value = arr End Sub

    Но здесь следует учитывать и тот момент, что большие массивы могут просто вызвать переполнение памяти. Наиболее актуально это для 32-битных систем, где на VBA и Excel выделяется памяти меньше, чем в 64-битных системах

    Избегать присвоения переменным типа Variant . Хоть соблазн и велик — этот тип забирает много памяти и в дальнейшем замедляет работу кода. Так же для объектных переменных следует избегать по возможности безликого глобального типа Object и применять конкретный тип:

    Как отключить обновление экрана для другого приложения (блокнот)

    4 Badan [2016-12-09 12:55:00]

    Я написал макрос в vba, который открывает текстовый файл с помощью блокнота, выбирает все txt и копирует его в Excel. Я должен обрабатывать около 100 файлов ежедневно таким образом, и я хочу избавиться от мигающих изображений, которые я наблюдаю. Код работает, но проблема в том, что команда

    Не работает с записной книжкой. Я могу использовать только обычный фокус, иначе код не работает. Как я могу выполнить код ниже, не заметив, что файл блокнота открыт и обработан?

    Я не мог найти никакого рабочего решения.

    excel-vba csv notepad

    Вот быстрый ответ, как запустить Notepad, но скрыть окно и использовать vbHide вместо vbNormalFocus в вашей команде Shell :

    Но я очень сомневаюсь, что SendKeys будет работать над невидимым окном.

    Итак, это не ответ на вопрос, но вы считаете, что используете FileSystemObject и просто читаете файл без фактического открытия Notepad.exe ?

    Код будет работать с акцентированными символами, например. мой тестовый текстовый файл:

    Насколько я знаю, Application.ScreenUpdating применим только к вашему сеансу Excel, а не к другим программам, запущенным в Windows. Таким образом, чтобы фактически остановить появление этих окон — , но все еще можно прочитать содержимое окна, вам придется сделать что-то достаточно сложное с Windows API. Использовать FileSystemObject много, проще.

    0 Badan [2016-12-12 11:37:00]

    Наконец-то я нашел очень элегантное решение, которое может обрабатывать внешние приложения. Все, что вам нужно, это Роберт Шутт для написания этого шедеврального кода. Это делает блокнот размером 1 пиксель, поэтому никаких мигающих изображений не наблюдается. Это выглядит довольно сложно для меня, но это спасло мой день:

    How to dou

    Поскольку ваши макросы Excel становятся все более надежными и сложными, вы можете обнаружить, что они теряют производительность. При обсуждении макросов слово производительность обычно является синонимом speed . Скорость — это то, как быстро ваши процедуры VBA выполняют свои намеченные задачи. Ниже приведены десять способов помочь сохранить макросы Excel с оптимальным уровнем производительности.

    Расчет листового листа

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

    Вы можете использовать Приложение. Свойство Calculate, чтобы сообщить Excel переключиться на ручной режим расчета. Когда рабочая книга находится в режиме ручного вычисления, рабочая книга не будет пересчитываться до тех пор, пока вы явно не выполните расчет, нажав клавишу F9.

    Поместите Excel в ручной режим расчета, запустите свой код и затем вернитесь в автоматический режим расчета.

    Установка режима вычисления обратно в xlCalculationAutomatic автоматически приведет к пересчету рабочего листа, поэтому нет необходимости нажимать клавишу F9 после запуска макроса.

    Отключение обновления экрана листа

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

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

    После того, как свойство ScreenUpdating вернётся к True, Excel автоматически вызовет перерисовку экрана.

    Отключение обновлений строки состояния

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

    Важно отметить, что отключить обновление экрана отдельно от выключения отображения строки состояния. Строка состояния будет продолжать обновляться, даже если вы отключите обновление экрана. Вы можете использовать Приложение. Свойство DisplayStatusBar для временного отключения любых обновлений строки состояния, что еще больше улучшает производительность вашего макроса:

    Указание Excel на игнорирование событий

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

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

    Вы можете добавить еще один уровень повышения производительности, используя свойство EnableEvents, чтобы заставить Excel игнорировать события во время запуска макроса.

    Перед запуском макроса установите для свойства EnableEvents значение False. После того, как ваш макрокоманда закончен, вы можете вернуть свойство EnableEvents значение True.

    Скрытие разрывов страниц

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

    Вы можете избежать этого поведения, просто скрыв разрывы страниц перед запуском своего макроса.

    Установите для свойства листа DisplayPageBreaks значение False, чтобы скрыть разрывы страниц. Если вы хотите продолжать показывать разрывы страниц после запуска макроса, установите для свойства листа DisplayPageBreaks значение True.

    Приостановка обновлений сводной таблицы

    Если ваш макрос управляет сводными таблицами, которые содержат большие источники данных, вы можете испытывать слабую производительность при выполнении таких операций, как динамическое добавление или перемещение полей поворота.

    Вы можете улучшить производительность своего макроса, приостановив перерасчет сводной таблицы до тех пор, пока не будут сделаны все изменения поля поворота. Просто установите PivotTable. Свойство ManualUpdate для True, чтобы отложить пересчет, запустите свой макрокоманд и затем установите сводную таблицу. Свойство ManualUpdate вернется к False, чтобы вызвать пересчет.

    Очистка от копирования и вставки

    Важно помнить, что хотя Macro Recorder экономит время, написав код VBA для вас, он не всегда записывает наиболее эффективный код. Ярким примером является то, как Macro Recorder захватывает любое действие копирования и вставки, которое вы выполняете во время записи.

    Вы можете немного увеличить свои макросы, вырезав посредника и выполнив прямую копию из одной ячейки в ячейку назначения. Этот альтернативный код использует аргумент Destination для обхода буфера обмена и копирования содержимого ячейки A1 непосредственно в ячейку B1.

    Если вам нужно скопировать только значения (не форматирование или формулы), вы можете повысить производительность еще больше, избегая при этом метода копирования. Просто установите значение ячейки назначения на то же значение, которое находится в исходной ячейке. Этот метод примерно в 25 раз быстрее, чем при использовании метода Copy:

    Если вам нужно скопировать только формулы из одной ячейки в другую (а не значения или форматирование), вы можете установить формулу ячейки назначения той же формуле, содержащейся в исходной ячейке:

    Использование оператора With

    При записи макросов вы часто будете манипулировать одним и тем же объектом более одного раза. Вы можете сэкономить время и повысить производительность, используя оператор With для выполнения нескольких действий на данном объекте за один снимок.

    Оператор With, используемый в следующем примере, сообщает Excel применять все изменения форматирования за один раз:

    Привычка к чередованию действий в операторы With не только ускорит выполнение макросов, но и упростит чтение вашего макрокода.

    Избегание метода Select

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

    После записи ваших макросов, сделайте привычкой изменять сгенерированный код, чтобы удалить методы Select. В этом случае оптимизированный код будет выглядеть следующим образом:

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

    Ограничение поездок на рабочий лист

    Еще один способ ускорить работу с макросами — ограничить количество ссылок на данные рабочего листа в вашем коде. Всегда менее эффективно захватывать данные из рабочего листа, чем из памяти. Другими словами, ваши макросы будут работать намного быстрее, если им не придется многократно взаимодействовать с рабочим листом.

    Например, следующий простой код заставляет VBA непрерывно возвращаться к листам («Лист1»). Range («A1»), чтобы получить номер, необходимый для сравнения, выполняемого в инструкции If:

    Более эффективным способом является сохранение значения в листах («Лист1»). Range («A1») к переменной MyMonth. Таким образом, код ссылается на переменную MyMonth вместо рабочего листа:

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

    Excel vba: Почему обновление экрана не обновляется, прежде чем отключать обновление экрана.

    У меня есть суб, который начинается с вызова другого суб (который редактирует ячейки рабочей книги), а затем отключает обновление экрана и предупреждения. Дело в том, что первый юг, который редактирует книгу, находится перед вторым югу, ячейка не обновляется.

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

    EDIT: обновление Экран уже верно, когда mainSub начинается; Комментируя setupApp sub out , он помогает, потому что он явно запускается раньше, чем ячейки редактируются несколько позже.

    Создан 30 авг. 17 2017-08-30 13:36:04 Ans

    Есть ли приложение.ScreenUpdating = False в getStateNames? – Moosli 30 авг. 17 2017-08-30 14:27:07

    @Moosli Нет, нет – Ans 30 авг. 17 2017-08-30 14:32:24

    Хорошо, давайте отправимся в Кахт. Вы можете увидеть это в комментариях в моем ответе. – Moosli 30 авг. 17 2017-08-30 14:36:50

    Я действительно не понимаю, почему это не работает. Но вы можете попытаться вызвать SetupApp с помощью инструкции If. Для этого вам нужно привязать editSub к функции и в конце просто вернуть истинное значение. Что-то вроде этого:

    Второе решение

    Вы можете попытаться форсировать события с DoEvents для обновления экрана.

    Или Помещенный DoEvents сразу после того, как вы написаны в клетках.

    Если это не работает, вы можете попробовать метод Wait:

    Первое решение

    ли судимое вам повернуть ScreenUpdating на Перед выполнением Sub?

    Создан 30 авг. 17 2017-08-30 13:50:20 Moosli

    Не помогает. Экран updatin ** уже ** истинен при запуске суб. Комментирование второй суб ** помогает **, потому что она, очевидно, выполняется раньше, чем нужно. – Ans 30 авг. 17 2017-08-30 13:51:44

    Сколько кода в editSub? Becuase, если есть только несколько строк, может быть, что UpdateEvent должен замедляться, и он будет отключен до обновления экрана. – Moosli 30 авг. 17 2017-08-30 13:54:33

    Довольно много строк. Он берет некоторые данные, проверяет их, добавляет в массив и только затем редактирует ячейки со значениями из массива. – Ans 30 авг. 17 2017-08-30 13:56:28

    @Ans Хорошо, я добавил мой Awnser – Moosli 30 авг. 17 2017-08-30 14:05:06

    К сожалению, ни то, ни другое не помогает . Ожидание просто приводит к более длительному времени выполнения, в то время как ячейки все еще пусты, «DoEvents» ничего не влияет. – Ans 30 авг. 17 2017-08-30 14:14:20

    Можете ли вы опубликовать код из editSup? – Moosli 30 авг. 17 2017-08-30 14:19:49

    Я редактировал вопрос. – Ans 30 авг. 17 2017-08-30 14:22:53

    Копилка знаний…..

    Ускоряем выполнение VBA кода, а так же убираем ненужные уведомления (всплывающие окна).

    Для того чтобы ускорить выполнение VBA кода в Excel, а так же скрыть мерцание экрана, лишние пересчёты формул, различные уведомления, на которые нужно нажать для продолжения выполнения кода и которые часто раздражают (подтверждение открытия файлов, данные сохраненные как текст и тд), а так же убрать не нужные пересчет формул который происходят постоянно при обновлении данных на которые они ссылаются можно использовать следующие команды, которые нужно добавить или в начало кода или перед конкретным нужным участком (если вы в курсе).

    Excel.Application.ScreenUpdating = False ‘убирает обновление экрана. Можно использовать почти всегда — лишняя нагрузка на процессор.

    Excel.Application.DisplayAlerts = False ‘убирает всплывающие окна. Совсем. Использовать аккуратно.

    Excel.Application.EnablEevents = False ‘убирает обработку событий в Excel. События необходимо отключать для исключения зацикливания или выполнения незапланированных действий. Например при внесении одним макросом значения на лист и лишнего (не нужного) выполнения другого макроса по обработки события добавления значения на лист — который, как вариант, рассчитан на ручной ввод. Использовать только при необходимости.

    Excel.Application.Calculation = xlCalculationManual ‘убирает автопересчет формул и зависимых от них объектов. Можно и нужно использовать почти всегда — лишняя нагрузка на процессор, особенно если формулы использующие массивы или поиск.

    Не забываем ОБЯЗАТЕЛЬНО все вернуть обратно, чтобы пользователи не ругались = ) :

    Excel.Application.ScreenUpdating = True
    Excel.Application.DisplayAlerts = True
    Excel.Application.EnableEvents = True
    Excel.Application.Calculation = xlCalculationAutomatic

    Навигация по записям

    Добавить комментарий Отменить ответ

    Для отправки комментария вам необходимо авторизоваться.

    Похожие статьи

    Благодарю всех за пояснения.

    БМВ, Ваш пример и правда гораздо нагляднее.
    sokol92, Вы  правы, думаю и у меня так и было раньше, а проблема не в  этом. Значение  у меня в False переключается, а вот обновление экрана  при этом по  прежнему происходит.
    Дмитрий(The_Prist) Щербаков, Ваши пояснения особо в тему, потому что это как раз то, что мне нужно.

    Моя «основная» процедура выглядит примерно так:

    Код
    Private Sub General()
    Application.ScreenUpdating = False
    '...
    Call SubProcedure
    '...
    Debug.Print Application.ScreenUpdating
    Application.ScreenUpdating = True
    End Sub

    Значение свойства ScreenUpdating меняется только дважды — на входе переключается на False и на выходе обратно на True (что, как я понял лучше всё-таки делать). Я проверял в разных подпроцедурах сохраняет ли свойство ScreenUpdating значение False — и оно везде сохраняется вплоть до возвращения обратно в головную процедуру. Т.е. насколько я понимаю, код должен работать как и задумано — обновление экрана выключено в ходе выполнения всех подпроцедур.

    Однако несмотря на то, что ScreenUpdating=False, обновление экрана все равно происходит, это заметно чисто визуально. Хотя до недавнего времени этот же файл работал нормально (изменений в коде не производилось). Поэтому я и подумал, что ScreenUpdating включается при выходе из подпроцедур, хотя теперь понимаю что это не так.

    Любопытный момент: если убрать строчку Application.ScreenUpdating = True из головной процедуры, всё начинает работать корректно (обновление экрана включается только в самом конце — при выходе из головной процедуры — автоматически).

    Я не могу найти никакого логичного объяснения такому поведению приложения.

    Return to VBA Code Examples

    In this Article

    • Disable ScreenUpdating
    • Enable ScreenUpdating
    • VBA ScreenUpdating Example
    • ScreenUpdating Refresh
      • VBA Settings – Speed Up Code
    • VBA Coding Made Easy

    As cool as it looks watching your VBA macro manipulate the screen, you can help your Macro run faster if you turn off (disable) ScreenUpdating.

    Disable ScreenUpdating

    1. To disable ScreenUpdating, At the beginning of your code put this line:

    Application.ScreenUpdating = False

    Enable ScreenUpdating

    2. To re-enable ScreenUpdating, At the end of your code put this line:

    Application.ScreenUpdating = True

    VBA ScreenUpdating Example

    Your procedure will then look like this:

    Sub ScreenUpdating_Example()
        Application.ScreenUpdating = False
    
        'Do Something
        Range("a1").Copy Range("b1")
        Range("a2").Copy Range("b2")
        Range("a3").Copy Range("b3")
    
    
        Application.ScreenUpdating = True
    End Sub

    vba screen updating

    ScreenUpdating Refresh

    Disabling ScreenUpdating will make your VBA code run MUCH faster, but it will also make your work appear more professional. End-users typically don’t want to see the behind the scenes actions of your procedures (especially when the procedure runs slow). Also, you may not want end-users to see the behind the scenes functionality (ex. Hidden Worksheets). I recommend disabling (and re-enabling) ScreenUpdating in virtually all of your procedures.

    However, there are some times when you want the screen to refresh. To refresh the screen, you will need to temporarily turn back on ScreenUpdating (there is no screen “refresh” command):

        Application.ScreenUpdating = True
        'Do Something
        Application.ScreenUpdating = False

    VBA Settings – Speed Up Code

    There are several other settings to play with to improve your code speed.

    Disabling Automatic Calculations can make a HUGE difference in speed:

    Application.Calculation = xlManual

    Disabling the Status Bar will also make a small difference:

    Application.DisplayStatusBar = False

    If your workbook contains events you should usually disable events at the beginning of your procedure:

    Application.EnableEvents = False

    Last, your VBA code can be slowed down when Excel tries to re-calculate page breaks (Note: not all procedures will be impacted).  To disable displaying page breaks use this line of code:

    ActiveSheet.DisplayPageBreaks = False

    VBA Coding Made Easy

    Stop searching for VBA code online. Learn more about AutoMacro – A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!

    VBA Turn Off On ScreenUpdating

    VBA Coding Made Easy

    Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
    vba save as

    Learn More!

    Понравилась статья? Поделить с друзьями:
  • Excel макрос оператор или
  • Excel макрос оператор for
  • Excel макрос объявление переменных
  • Excel макрос объединение ячеек с одинаковыми значениями
  • Excel макрос обращение к листу