Application.EnableEvents is a property in Excel VBA where you can specify whether you want events to take place when the VBA code is running or not.
An event is usually attached to an object. VBA Events could include things such as activating a worksheet or saving a workbook or double-clicking on a cell.
Excel VBA allows you to create event-specific code, where you can specify what code to run in case the user double-clicks on a cell. In this case, this would be the double-click event.
Similarly, you can have a code that is run as soon as a new worksheet is activated in the workbook.
Now, these events are useful, but sometimes you may not want them to work.
For example, if you’re running a code that will activate and loop through all the open worksheets one by one, you may not want to execute the event code (in case you have it) when each sheet is activated.
In such cases, you can set the Application.EnableEvents property to false, making sure the events are turned off when the code is running.
Now that you have a better understanding of what Application.EnableEvents does (I hope), let’s see the syntax and some examples.
Below is the syntax of the Application.Events
Application.Events
where, the application is the object (when using this in Excel VBA, Excel is the application), and Events is the property.
So you can set the Application.Events property to either True or False.
Application.Events = True
or
Application.Events = False
When you set this to TRUE, events will run as usual in Excel VBA, and if you set this to FALSE, events would stop working (for the whole VBA).
One caveat here is that if you set this to FALSE, remember to set it back to TRUE again (which is the default and expected behavior of this property)
Now let’s see an example of how to use it
Application.EnableEvents Example
Below is a code where the main code is flanked by the Application.EnableEvents property.
Sub ExampleCode() Application.EnableEvents = False ThisWorkbook.Save Application.EnableEvents = True End Sub
In the above code, the ThisWorkbook.Save is flanked by Application.EnableEvents properties being set first to FALSE and then to TRUE.
When you run this code, in case there are any events associated with the workbook getting saved, it will not be run. And since you have set the property back to TRUE in the last line, this will not impact other macros in your workbook.
Note: In case you’re calling other subroutines from one of the subroutines that use Application.EnableEvents, you need to remember to make sure you turn it back on. Also, remember that when you run this code and in case of Excel finds any errors while the code is running, the last line will not be executed (and Application.EnableEvents will not get back to TRUE).
Application.EnableEvents Not Working
Remember that Application.EnableEvents would not work with Userforms events and controls.
Here is an article that talks about some of the disadvantages of using Application.EnableEvents and an alternative way to handle events in Excel VBA.
So this is all that you needed to know about the Application.EnableEvents property in Excel VBA.
Hope you found this tutorial useful!
Other Excel tutorials you may like:
- How to Remove Macros from Excel? 3 Simple Methods
- How to Delete a Sheet in Excel Using VBA
- How to Unhide All Rows in Excel with VBA
- Using Application.GetSaveAsFilename in VBA in Excel (Examples)
- SetFocus in Excel VBA – How to Use it?
- How to Open Excel Files Using VBA
- Subscript Out of Range Error in VBA – How to Fix!
EnableEvents Property of Application Object VBA
EnableEvents Application Property in Excel VBA is used to enable events for the specified object. It has Boolean value that is either True or False. Please find more details about EnableEvents Application Property in the following section. When EnableEvents property set to True, while running any procedure it will enable the events.
- VBA EnableEvents Application Property – Syntax
- VBA EnableEvents Application Property: Example 1
- VBA EnableEvents Application Property- Instructions
VBA EnableEvents Application Property – Syntax
Here is the syntax for EnableEvents Property of application object in Excel VBA.
Application. EnableEvents
Where EnableEvents as String.
In the above syntax Application represents object and EnableEvents is the Property of Application object.
VBA EnableEvents Application Property: Example 1
Please find the below example for EnableEvents Property of application object in excel VBA. The below example disables the event and saves the workbook. So that the events cannot perform any task.
Sub Appl_EnableEvents() Application.EnableEvents = False ThisWorkbook.Save Application.EnableEvents = True End Sub
VBA EnableEvents Application Property – Instructions
Please follow the below steps to execute the VBA code to save the excel file.
Step 1: Open any existing Excel Application.
Step 2: Press Alt+F11 – This will open the VBA Editor Window.
Step 3: Insert a code module from then insert menu.
Step 4: Copy the above code and paste in the code module which have inserted in the above step.
Step 5: Now press F5 to execute the code.
A Powerful & Multi-purpose Templates for project management. Now seamlessly manage your projects, tasks, meetings, presentations, teams, customers, stakeholders and time. This page describes all the amazing new features and options that come with our premium templates.
Save Up to 85% LIMITED TIME OFFER
All-in-One Pack
120+ Project Management Templates
Essential Pack
50+ Project Management Templates
Excel Pack
50+ Excel PM Templates
PowerPoint Pack
50+ Excel PM Templates
MS Word Pack
25+ Word PM Templates
Ultimate Project Management Template
Ultimate Resource Management Template
Project Portfolio Management Templates
-
-
- In this topic:
-
- VBA EnableEvents Application Property – Syntax
- VBA EnableEvents Application Property: Example 1
- VBA EnableEvents Application Property – Instructions
VBA Reference
Effortlessly
Manage Your Projects
120+ Project Management Templates
Seamlessly manage your projects with our powerful & multi-purpose templates for project management.
120+ PM Templates Includes:
One Comment
-
Hans Schulze
May 19, 2020 at 9:07 AM — ReplyEnable WHAT events? Multithreading? Examples?
Effectively Manage Your
Projects and Resources
ANALYSISTABS.COM provides free and premium project management tools, templates and dashboards for effectively managing the projects and analyzing the data.
We’re a crew of professionals expertise in Excel VBA, Business Analysis, Project Management. We’re Sharing our map to Project success with innovative tools, templates, tutorials and tips.
Project Management
Excel VBA
Download Free Excel 2007, 2010, 2013 Add-in for Creating Innovative Dashboards, Tools for Data Mining, Analysis, Visualization. Learn VBA for MS Excel, Word, PowerPoint, Access, Outlook to develop applications for retail, insurance, banking, finance, telecom, healthcare domains.
Page load link
Go to Top
На чтение 31 мин. Просмотров 19.3k.
Когда вы создаете или записываете макрос в Excel, вам нужно запустить макрос, чтобы выполнить шаги в коде.
Несколько способов запуска макроса включают использование диалогового окна макроса, назначение макроса кнопке, использование ярлыка и т.д.
Помимо этих запускаемых пользователем макросов, вы также можете использовать события VBA для запуска макроса.
Содержание
- События Excel VBA — Введение
- Различные типы событий Excel VBA
- Где поставить код, связанный с событием
- Понимание последовательности событий
- Понимание роли аргументов в событиях VBA
- События на уровне рабочей книги (поясняются примерами)
- События уровня рабочего листа (объясненные с примерами)
- Событие Excel VBA OnTime
- Событие Excel VBA OnKey
- Отключение событий в VBA
- Влияние событий Undo Stack
Позвольте мне сначала объяснить, что такое событие в VBA.
Событие — это действие, которое может инициировать выполнение указанного макроса.
Например, когда вы открываете новую книгу, это событие. Когда вы вставляете новый лист, это событие. Если дважды щелкнуть ячейку, это событие.
В VBA есть много таких событий, и вы можете создавать коды для этих событий. Это означает, что как только происходит событие, и если вы указали код для этого события, этот код будет немедленно выполнен.
Excel автоматически сделает это, как только заметит, что событие произошло. Таким образом, вам нужно только написать код и поместить его в правильную подпрограмму события (это будет описано далее в этой статье).
Например, если вы вставляете новый лист и хотите, чтобы он имел префикс года, вы можете написать для него код.
Теперь, когда кто-нибудь вставляет новый лист, этот код будет автоматически выполняться и добавлять префикс года к имени листа.
Другой пример: вы хотите изменить цвет ячейки, когда кто-то дважды щелкает по ней. Вы можете использовать событие двойного щелчка для этого.
Точно так же вы можете создавать коды VBA для многих таких событий (рассмотрим позже в этой статье).
Ниже приведена краткая картинка, показывающая событие двойного щелчка в действии. Как только я дважды щелкну по ячейке A1. Excel мгновенно открывает окно сообщения, в котором отображается адрес ячейки.
Двойной щелчок — это событие, а отображение окна сообщения — это то, что я указал в коде, когда происходит событие двойного щелчка.
Хотя приведенный выше пример является бесполезным событием, я надеюсь, что он поможет вам понять, как это происходит.
Различные типы событий Excel VBA
В Excel есть разные объекты — например, сам Excel (к которому мы часто обращаемся как приложение), рабочие книги, рабочие таблицы, диаграммы и т.д.
Каждый из этих объектов может иметь различные события, связанные с ним. Например:
- Если вы создаете новую книгу, это событие уровня приложения.
- Если вы добавляете новый лист, это событие уровня книги.
- Если вы измените значение в ячейке на листе, это событие уровня рабочего листа.
Ниже приведены различные типы событий, которые существуют в Excel:
- События уровня рабочего листа. Это типы событий, которые запускаются на основе действий, выполненных в рабочем листе. Примеры этих событий включают изменение ячейки на рабочем листе, изменение выделения, двойной щелчок по ячейке, щелчок правой кнопкой мыши по ячейке и т.д.
- События на уровне рабочей книги. Эти события будут инициироваться на основе действий на уровне рабочей книги. Примеры таких событий включают добавление новой рабочей таблицы, сохранение рабочей книги, открытие рабочей книги, печать части или всей рабочей книги и т.д.
- События уровня приложения: это события, которые происходят в приложении Excel. Примером этого может быть закрытие любой из открытых рабочих книг или открытие новой рабочей книги.
- События уровня пользовательской формы: эти события будут инициироваться на основе действий в пользовательской форме. Примеры этого включают инициализацию пользовательской формы или нажатие кнопки в пользовательской форме.
- События диаграммы: это события, относящиеся к листу диаграммы. Лист диаграммы отличается от рабочего листа. Примеры таких событий могут включать изменение серии диаграммы или изменение размера диаграммы.
- События OnTime и OnKey. Это два события, которые не соответствуют ни одной из перечисленных выше категорий. Поэтому я перечислил их отдельно. Событие «OnTime» позволяет вам выполнить код в определенное время или по истечении определенного времени. Событие «OnKey» позволяет выполнить код, когда используется определенное нажатие клавиши (или комбинация нажатий клавиш).
Где поставить код, связанный с событием
В приведенном выше разделе я рассмотрел различные типы событий.
В зависимости от типа события вам необходимо поместить код в соответствующий объект.
Например, если это событие, связанное с рабочим листом, оно должно идти в окне кода объекта рабочего листа. Если она связана с книгой, она должна идти в окне кода для объекта книги.
В VBA разные объекты — такие как Worksheets, Workbooks, Chart Sheets, UserForms и т.д. Имеют собственные окна кода. Вам необходимо поместить код события в окно кода соответствующего объекта. Например, если это событие уровня рабочей книги, вам нужно иметь код события в окне кода рабочей книги.
Следующие разделы охватывают места, где вы можете поместить код события:
В окне кода Worksheet
Когда вы откроете VB Editor (используя сочетание клавиш ALT + F11), вы заметите объект рабочих таблиц в Project Explorer. Для каждого листа в книге вы увидите один объект.
Если дважды щелкнуть объект листа, в который вы хотите поместить код, откроется окно кода для этого листа.
Хотя вы можете начать писать код с нуля, гораздо лучше выбрать событие из списка параметров и позволить VBA автоматически вставить соответствующий код для выбранного события.
Для этого вам нужно сначала выбрать рабочий лист из выпадающего списка в левом верхнем углу окна кода.
После выбора рабочего листа из выпадающего списка вы получите список всех событий, связанных с рабочим листом. Вы можете выбрать тот, который вы хотите использовать, из выпадающего списка в правом верхнем углу окна кода.
Как только вы выберете событие, оно автоматически введет первую и последнюю строку кода для выбранного события. Теперь вы можете добавить свой код между двумя строками.
Примечание. Как только вы выберете «Worksheet» в раскрывающемся списке, вы увидите две строки кода в окне кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появились по умолчанию.
Обратите внимание, что каждый лист имеет собственное окно кода. Когда вы вводите код для Лист1, он будет работать только в том случае, если событие происходит в Лист1.
В окне кода ThisWorkBook
Точно так же как рабочие листы, если у вас есть код события уровня книги, вы можете поместить его в окно кода ThisWorkbook.
Когда вы дважды щелкните на ThisWorkbook, он откроет окно кода для него.
Вам нужно выбрать Workbook из выпадающего списка в верхнем левом углу окна кода.
После выбора Workbook из выпадающего списка вы получите список всех событий, связанных с Workbook. Вы можете выбрать тот, который вы хотите использовать, из выпадающего списка в правом верхнем углу окна кода.
Как только вы выберете событие, оно автоматически введет первую и последнюю строку кода для выбранного события. Теперь вы можете добавить свой код между двумя строками.
Примечание. Как только вы выберете Workbook из выпадающего списка, вы увидите две строки кода в окне кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появились по умолчанию.
В окне кода Userform
Когда вы создаете пользовательские формы в Excel, вы также можете использовать события пользовательской формы для выполнения кодов на основе определенных действий. Например, вы можете указать код, который будет выполняться при нажатии кнопки.
Хотя объекты Sheet и ThisWorkbook уже доступны при открытии редактора VB, пользовательская форма — это то, что вам нужно создать в первую очередь.
Чтобы создать пользовательскую форму, щелкните правой кнопкой мыши любой из объектов, перейдите на вкладку «Вставка» и выберите «UserForm».
Это вставит объект UserForm в книгу.
Если дважды щелкнуть пользовательскую форму (или любой объект, который вы добавляете в пользовательскую форму), откроется окно кода для пользовательской формы.
Теперь, так же как рабочие листы или ThisWorkbook, вы можете выбрать событие, и оно вставит первую и последнюю строку для этого события. И тогда вы можете добавить код в середине этого.
В окне кода Chart
В Excel вы также можете вставлять листы диаграмм (которые отличаются от листов). Лист диаграмм должен содержать только диаграммы.
Вставив лист диаграммы, вы сможете увидеть объект листа диаграммы в редакторе VB.
Вы можете добавить код события в окно кода листа диаграммы, как мы это делали на листе.
Дважды щелкните объект листа Chart в Project Explorer. Это откроет окно кода для листа диаграммы.
Теперь вам нужно выбрать Chart из выпадающего списка в верхнем левом углу окна кода.
После выбора Chart из выпадающего списка вы получите список всех событий, связанных с листом Chart. Вы можете выбрать тот, который вы хотите использовать, из выпадающего списка в правом верхнем углу окна кода.
Примечание. Как только вы выберете Chart из выпадающего списка, вы заметите две строки кода в окне кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появились по умолчанию.
В Class Module
Class Module должны быть вставлены так же, как пользовательские формы.
Модуль класса может содержать код, связанный с приложением, которым может быть сам Excel и встроенные диаграммы.
Я расскажу о модуле класса в качестве отдельного учебного пособия в ближайшие недели.
Обратите внимание, что кроме событий OnTime и OnKey, ни одно из перечисленных выше событий не может быть сохранено в обычном модуле VBA.
Понимание последовательности событий
Когда вы запускаете событие, оно не происходит изолированно. Это также может привести к последовательности нескольких триггеров.
Например, когда вы вставляете новый лист, происходит следующее:
- Добавлен новый рабочий лист
- Предыдущая рабочая таблица деактивируется
- Новый лист активируется
Хотя в большинстве случаев вам не нужно беспокоиться о последовательности, если вы создаете сложные коды, основанные на событиях, лучше знать последовательность, чтобы избежать неожиданных результатов.
Понимание роли аргументов в событиях VBA
Прежде чем мы перейдем к примерам событий и удивительным вещам, которые вы можете с ним сделать, я должен рассмотреть одну важную концепцию.
В событиях VBA было бы два типа кодов:
- Без каких-либо аргументов
- С аргументами
И в этом разделе я хочу быстро осветить роль аргументов.
Ниже приведен код без аргументов (круглые скобки пусты):
Private Sub Workbook_Open() MsgBox "Не забудьте заполнить расписание" End Sub
С помощью приведенного выше кода, когда вы открываете рабочую книгу, она просто показывает окно сообщения с сообщением — «Не забудьте заполнить расписание».
Теперь давайте посмотрим на код, который имеет аргумент.
Private Sub Workbook_NewSheet(ByVal Sh As Object) Sh.Range("A1") = Sh.Name End Sub
Приведенный выше код использует аргумент Sh, который определен как тип объекта. Аргумент Sh может быть рабочим листом или листом диаграммы, так как указанное выше событие вызывается при добавлении нового листа.
Присвоив новый лист, который добавляется к книге, объектной переменной Sh, VBA позволил нам использовать его в коде. Поэтому, чтобы обратиться к новому названию листа, я могу использовать Sh.Name.
Концепция аргументов будет полезна при ознакомлении с примерами событий VBA в следующих разделах.
События на уровне рабочей книги (поясняются примерами)
Ниже приведены наиболее часто используемые события в книге.
Событие | Что запускает событие |
Activate | Когда книга активирована |
AfterSave | Когда книга установлена как надстройка |
BeforeSave | Когда рабочая книга сохранена |
BeforeClose | Когда рабочая книга закрыта |
BeforePrint | Когда печатается книга |
Deactivate | Когда книга деактивирована |
NewSheet | Когда добавляется новый лист |
Open | Когда рабочая книга открыта |
SheetActivate | Когда любой лист в книге активирован |
SheetBeforeDelete | При удалении любого листа |
SheetBeforeDoubleClick | При двойном щелчке по любому листу |
SheetBeforeRightClick | При щелчке правой кнопкой мыши по любому листу |
SheetCalculate | Когда любой лист рассчитывается или пересчитывается |
SheetDeactivate | Когда рабочая книга деактивирован |
SheetPivotTableUpdate | При обновлении книги |
SheetSelectionChange | При изменении рабочей книги |
WindowActivate | Когда книга активирована |
WindowDeactivate | Когда книга деактивирована |
Обратите внимание, что это не полный список.
Помните, что код для события Workbook хранится в окне кода объектов ThisWorkbook.
Теперь давайте посмотрим на некоторые полезные события из рабочей книги и посмотрим, как они могут быть использованы в вашей повседневной работе.
Событие Workbook Open
Допустим, вы хотите показать пользователю дружеское напоминание, чтобы заполнять его расписания при каждом открытии определенной рабочей книги.
Вы можете использовать приведенный ниже код, чтобы сделать это:
Private Sub Workbook_Open() MsgBox "Не забудьте заполнить расписание" End Sub
Теперь, как только вы откроете рабочую книгу с этим кодом, она покажет вам окно сообщения с указанным сообщением.
При работе с этим кодом (или с кодами событий рабочей книги в целом) необходимо знать несколько вещей:
- Если в книге есть макрос, и вы хотите сохранить его, вам нужно сохранить его в формате .XLSM. В противном случае код макроса будет потерян.
- В приведенном выше примере код события будет выполняться только при включенных макросах. Может появиться желтая полоса, запрашивающая разрешение на включение макросов. Пока это не включено, код события не выполняется.
- Код события Workbook помещается в окно кода объекта ThisWorkbook.
Вы можете дополнительно уточнить этот код и показать сообщение только пятницы.
Код ниже сделает это:
Private Sub Workbook_Open() wkday = Weekday(Date) If wkday = 6 Then MsgBox "Не забудьте заполнить расписание" End Sub
Обратите внимание, что в функции «Weekday» воскресенье присваивается значение 1, понедельник — 2 и т. Д.
Поэтому на пятницу я использовал 6.
Событие Open Workbook может быть полезно во многих ситуациях, таких как:
- Когда вы хотите показать приветственное сообщение человеку, когда книга открыта.
- Когда вы хотите отобразить напоминание, когда рабочая книга открыта.
- Если вы хотите всегда активировать один конкретный лист в книге, когда она открыта.
- Когда вы хотите открыть связанные файлы вместе с книгой.
- Если вы хотите фиксировать дату и время каждый раз, когда открывается рабочая книга.
Событие Workbook NewSheet
Событие NewSheet запускается при вставке нового листа в рабочую книгу.
Допустим, вы хотите ввести значение даты и времени в ячейку A1 вновь вставленного листа. Вы можете использовать приведенный ниже код, чтобы сделать это:
Private Sub Workbook_NewSheet(ByVal Sh As Object) On Error Resume Next Sh.Range("A1") = Format(Now, "dd-mmm-yyyy hh:mm:ss") End Sub
Приведенный выше код использует «On Error Resume Next» для обработки случаев, когда кто-то вставляет лист диаграммы, а не лист. Поскольку на листе диаграммы нет ячейки A1, будет отображаться ошибка, если «On Error Resume Next» не используется.
Другой пример может быть, когда вы хотите применить некоторые базовые настройки или форматирование к новому листу, как только он будет добавлен. Например, если вы хотите добавить новый лист и хотите, чтобы он автоматически получал серийный номер (до 100), то вы можете использовать код ниже.
Private Sub Workbook_NewSheet(ByVal Sh As Object) On Error Resume Next With Sh.Range("A1") .Value = "S. No." .Interior.Color = vbBlue .Font.Color = vbWhite End With For i = 1 To 100 Sh.Range("A1").Offset(i, 0).Value = i Next i Sh.Range("A1", Range("A1").End(xlDown)).Borders.LineStyle = xlContinuous End Sub
Приведенный выше код также немного форматирует. Это дает ячейке заголовка синий цвет и делает шрифт белым. Это также применяет границу ко всем заполненным ячейкам.
Приведенный выше код является примером того, как короткий код VBA может помочь вам украсть несколько секунд каждый раз, когда вы вставляете новый лист (на случай, если вам придется каждый раз это делать).
Событие Workbook BeforeSave
Событие «BeforeSave» запускается при сохранении книги. Обратите внимание, что событие инициируется сначала, а затем рабочая книга сохраняется.
При сохранении книги Excel возможны два сценария:
- Вы сохраняете его в первый раз, и он покажет диалоговое окно Сохранить как.
- Вы уже сохранили его ранее, и он просто сохранит и перезапишет изменения в уже сохраненной версии.
Теперь давайте рассмотрим несколько примеров, где вы можете использовать событие BeforeSave.
Предположим, у вас есть новая книга, которую вы сохраняете впервые, и вы хотите напомнить пользователю о необходимости сохранить ее на диске K, затем вы можете использовать следующий код:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) If SaveAsUI Then MsgBox "Сохраните этот файл на диске K" End Sub
В приведенном выше коде, если файл никогда не был сохранен, SaveAsUI имеет значение True и вызывает диалоговое окно Save As. Приведенный выше код будет отображать сообщение до появления диалогового окна «Save As».
Другим примером может быть обновление даты и времени, когда файл сохраняется в определенной ячейке.
Приведенный ниже код вставляет отметку даты и времени в ячейку A1 листа She1 при каждом сохранении файла.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Worksheets("Лист1").Range("A1") = Format(Now, "dd-mmm-yyyy hh:mm:ss") End Sub
Обратите внимание, что этот код выполняется, как только пользователь сохраняет рабочую книгу. Если книга сохраняется в первый раз, в ней отобразится диалоговое окно «Save As». Но код уже выполняется к тому времени, когда вы видите диалоговое окно Save As. На этом этапе, если вы решите отменить и не сохранить книгу, дата и время уже будут введены в ячейку.
Событие Workbook BeforeClose
Событие «BeforeClose» происходит непосредственно перед закрытием книги.
Приведенный ниже код защищает все рабочие листы до их закрытия.
Private Sub Workbook_BeforeClose(Cancel As Boolean) Dim sh As Worksheet For Each sh In ThisWorkbook.Worksheets sh.Protect Next sh End Sub
Помните, что код события срабатывает, как только вы закрываете книгу.
Об этом событии важно знать, что не имеет значения, закрыта ли рабочая книга или нет.
В случае, если рабочая книга не была сохранена, и вы увидите приглашение с вопросом о том, сохранять рабочую книгу или нет, и вы нажмете Отмена, она не сохранит вашу рабочую книгу. Однако код события уже был бы выполнен к тому времени.
Событие Workbook BeforePrint
Когда вы даете команду печати (или команду предварительного просмотра), запускается событие «BeforePrint».
Приведенный ниже код будет пересчитывать все рабочие листы до их печати.
Private Sub Workbook_BeforePrint(Cancel As Boolean) For Each ws in Worksheets ws.Calculate Next ws End Sub
Когда пользователь печатает книгу, событие вызывается независимо от того, печатает ли он всю книгу или только ее часть.
Другой пример, приведенный ниже, — это код, который добавляет дату и время в нижний колонтитул при печати рабочей книги.
Private Sub Workbook_BeforePrint(Cancel As Boolean) Dim ws As Worksheet For Each ws In ThisWorkbook.Worksheets ws.PageSetup.LeftFooter = "Напечатано - " & Format(Now, "dd-mmm-yyyy hh:mm") Next ws End Sub
События уровня рабочего листа (объясненные с примерами)
События рабочего листа происходят на основе триггеров в рабочем листе.
Ниже приведены наиболее часто используемые события на листе.
Событие | Что запускает событие |
Activate | Когда лист активирован |
BeforeDelete | Перед удалением листа |
BeforeDoubleClick | Перед двойным щелчком на листе |
BeforeRightClick | Перед щелчком правой кнопкой мыши по рабочему листу |
Calculate | До того, как рабочий лист будет рассчитан или пересчитан |
Change | При изменении ячеек на листе |
Deactivate | Когда лист деактивирован |
PivotTableUpdate | При обновлении сводной таблицы на листе |
SelectionChange | Когда выбор на рабочем листе изменяется |
Обратите внимание, что это не полный список. Вы можете найти полный список здесь.
Помните, что код события Worksheet хранится в окне кода объекта рабочего листа (в том, в котором вы хотите, чтобы событие было запущено). В одной книге может быть несколько рабочих листов, и ваш код будет запущен только тогда, когда событие происходит в рабочей таблице, в которой оно размещено.
Теперь давайте посмотрим на некоторые полезные события на листе и посмотрим, как их можно использовать в вашей повседневной работе.
Событие Worksheet Activate
Это событие вызывается при активации рабочего листа.
Приведенный ниже код снимает защиту листа, как только он активирован.
Private Sub Worksheet_Activate() ActiveSheet.Unprotect End Sub
Вы также можете использовать это событие, чтобы убедиться, что конкретная ячейка или диапазон ячеек (или именованный диапазон) выбран, как только вы активируете рабочую таблицу. Приведенный ниже код выберет ячейку D1, как только вы активируете лист.
Private Sub Worksheet_Activate() ActiveSheet.Range("D1").Select End Sub
Событие Worksheet Change
Событие изменения запускается всякий раз, когда вы вносите изменения в лист.
Ну .. не всегда.
Есть некоторые изменения, которые вызывают событие, а некоторые нет. Вот список некоторых изменений, которые не вызовут событие:
- При изменении форматирования ячейки (размер шрифта, цвет, рамка и т.д.).
- Когда вы объединяете клетки. Это удивительно, так как иногда объединение ячеек также удаляет содержимое из всех ячеек, кроме верхнего левого.
- Когда вы добавляете, удаляете или редактируете комментарий к ячейке.
- Когда вы сортируете диапазон ячеек.
- Когда вы используете поиск цели.
Следующие изменения могут вызвать событие (даже если вы думаете, что не должно):
- Копирование и вставка форматирования вызовут событие.
- Очистка форматирования вызовет событие.
- Запуск проверки орфографии вызовет событие.
Ниже код будет отображать окно сообщения с адресом ячейки, которая была изменена.
Private Sub Worksheet_Change(ByVal Target As Range) MsgBox "Вы только что изменились " & Target.Address End Sub
Хотя это бесполезный макрос, он показывает, как использовать аргумент Target, чтобы узнать, какие ячейки были изменены.
Теперь давайте посмотрим пару более полезных примеров.
Предположим, у вас есть диапазон ячеек (скажем, A1: D10), и вы хотите показать подсказку и спросить пользователя, действительно ли он хочет изменить ячейку в этом диапазоне, вы можете использовать приведенный ниже код.
Отображается подсказка с двумя кнопками — «Да» и «Нет». Если пользователь выбирает «Да», изменение выполняется, в противном случае оно отменяется.
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Row <= 10 And Target.Column <= 4 Then Ans = MsgBox("Вы вносите изменения в ячейки в A1: D10. Вы уверены, что хотите это?", vbYesNo) End If If Ans = vbNo Then Application.EnableEvents = False Application.Undo Application.EnableEvents = True End If End Sub
В приведенном выше коде мы проверяем, находится ли целевая ячейка в первых 4 столбцах и первых 10 строках. Если это так, появится окно сообщения. Кроме того, если пользователь выбрал «Нет» в окне сообщения, изменение отменяется (с помощью команды Application.Undo).
Обратите внимание, что я использовал Application.EnableEvents = False перед строкой Application.Undo. И затем я изменил его, используя Application.EnableEvent = True в следующей строке.
Это необходимо, поскольку, когда происходит отмена, это также вызывает событие изменения. Если я не установлю для параметра EnableEvent значение False, он продолжит вызывать событие изменения.
Вы также можете отслеживать изменения в именованном диапазоне, используя событие изменения. Например, если у вас есть именованный диапазон с именем «DataRange», и вы хотите показать подсказку на случай, если пользователь внесет изменение в этот именованный диапазон, вы можете использовать код ниже:
Private Sub Worksheet_Change(ByVal Target As Range) Dim DRange As Range Set DRange = Range("DataRange") If Not Intersect(Target, DRange) Is Nothing Then MsgBox "Вы только что внесли изменения в диапазон данных" End If End Sub
Приведенный выше код проверяет, имеет ли ячейка / диапазон, в котором вы внесли изменения, какие-либо ячейки, общие для диапазона данных. Если это так, он показывает окно сообщения.
Событие SelectionChange Workbook
Событие изменения выбора запускается всякий раз, когда в рабочем листе есть изменение выбора.
Приведенный ниже код будет пересчитывать лист, как только вы измените выбор.
Private Sub Worksheet_SelectionChange(ByVal Target As Range) Application.Calculate End Sub
Другой пример этого события — когда вы хотите выделить активную строку и столбец выбранной ячейки.
Что-то, как показано ниже:
Следующий код может сделать это:
Private Sub Worksheet_SelectionChange(ByVal Target As Range) Cells.Interior.ColorIndex = xlNone With ActiveCell .EntireRow.Interior.Color = RGB(248, 203, 173) .EntireColumn.Interior.Color = RGB(180, 198, 231) End With End Sub
Код сначала удаляет цвет фона из всех ячеек, а затем применяет цвет, упомянутый в коде, к активной строке и столбцу.
И это проблема с этим кодом. Что он удаляет цвет со всех клеток.
Если вы хотите выделить активную строку / столбец, не изменяя цвета в других ячейках, используйте технику, показанную в этом руководстве.
Событие Workbook DoubleClick
Это одно из моих любимых событий на листе, и вы увидите много учебных пособий, в которых я использовал это.
Это событие срабатывает при двойном щелчке по ячейке.
Позвольте мне показать вам, как это круто.
С помощью приведенного ниже кода вы можете дважды щелкнуть ячейку, и она применит цвет фона, изменит цвет шрифта и сделает текст в ячейке жирным;
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Cancel = True With Target .Interior.Color = vbBlue .Font.Color = vbWhite .Font.Bold = True End With End Sub
Это может быть полезно, когда вы просматриваете список ячеек и хотите выделить несколько выбранных. Хотя вы можете использовать клавишу F4, чтобы повторить последний шаг, он сможет применить только один вид форматирования. С этим событием двойного щелчка вы можете применить все три с помощью двойного щелчка.
Обратите внимание, что в приведенном выше коде я сделал значение Cancel = True.
Это сделано для того, чтобы действие двойного щелчка по умолчанию было отключено — то есть войти в режим редактирования. Если Cancel = True, Excel не переведет вас в режим редактирования, если дважды щелкнуть ячейку.
Вот еще один пример.
Если у вас есть список дел в Excel, вы можете использовать событие двойного щелчка, чтобы применить формат перечеркивания, чтобы пометить задачу как выполненную.
Как показано ниже:
Вот код, который сделает это:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Cancel = True CurrFormat = Target.Font.Strikethrough If CurrFormat Then Target.Font.Strikethrough = False Else Target.Font.Strikethrough = True End If End Sub
Обратите внимание, что в этом коде я сделал двойной щелчок в качестве события переключения. Если дважды щелкнуть ячейку, она проверяет, был ли уже применен формат зачеркивания. Если это так, двойной щелчок удаляет зачеркнутый формат, а если этого не было, то применяется зачеркнутый формат.
Событие Excel VBA OnTime
События, которые мы видели до сих пор в этой статье, были связаны с одним из объектов Excel, будь то рабочая книга, рабочий лист, лист диаграммы или пользовательские формы и т.д.
Событие OnTime отличается от других событий, поскольку оно может быть сохранено в обычном модуле VBA (тогда как другие должны были быть помещены в окно кода объектов, таких как ThisWorkbook или Worksheets или UserForms).
В обычном модуле VBA он используется как метод объекта приложения.
Причина, по которой это считается событием, заключается в том, что оно может быть запущено в зависимости от указанного вами времени. Например, если я хочу, чтобы лист пересчитывался каждые 5 минут, я могу использовать для него событие OnTime.
Или, если я хочу показать сообщение / напоминание в определенное время дня, я могу использовать событие OnTime.
Ниже приведен код, который будет показывать сообщение в 2 часа дня каждый день.
Sub MessageTime() Application.OnTime TimeValue("14:00:00"), "ShowMessage" End Sub Sub ShowMessage() MsgBox "Время обеда" End Sub
Помните, что вам нужно поместить этот код в обычный модуль VBA,
Кроме того, хотя событие OnTime будет запускаться в указанное время, макрос необходимо запускать вручную в любое время. После запуска макроса он будет ждать до 14:00, а затем вызовет макрос «ShowMessage».
Макрос ShowMessage будет отображать сообщение.
Событие OnTime принимает четыре аргумента:
Application.OnTime (Самое раннее время, Процедура, Последнее время, Расписание)
- EarliestTime: время, когда вы хотите запустить процедуру.
- Procedure: имя процедуры, которая должна быть запущена.
- LatestTime (Необязательно): Если другой код выполняется и указанный код не может быть запущен в указанное время, вы можете указать LatestTime, которого он должен ждать. Например, это может быть EarliestTime + 45 (что означает, что он будет ждать 45 секунд, пока другая процедура завершится). Если даже через 45 секунд процедура не может быть запущена, она прекращается. Если вы не укажете это, Excel подождет, пока код может быть запущен, а затем запустит его.
- Schedule (необязательно): если установлено значение «ИСТИНА», оно планирует новую процедуру времени. Если ЛОЖЬ, то это отменяет ранее установленную процедуру. По умолчанию это ИСТИНА
В приведенном выше примере мы использовали только первые два аргумента.
Давайте посмотрим на другой пример.
Приведенный ниже код будет обновлять лист каждые 5 минут.
Dim NextRefresh as Date Sub RefreshSheet() ThisWorkbook.Worksheets("Лист1").Calculate NextRefresh = Now + TimeValue("00:05:00") Application.OnTime NextRefresh, "RefreshSheet" End Sub Sub StopRefresh() On Error Resume Next Application.OnTime NextRefresh, "RefreshSheet", , False End Sub
Приведенный выше код обновляет лист каждые 5 минут.
Он использует функцию «Now», чтобы определить текущее время, а затем добавляет 5 минут к текущему времени.
Событие OnTime будет продолжаться до тех пор, пока вы его не остановите. Если вы закроете книгу, а приложение Excel все еще будет запущено (другие книги открыты), книга, в которой запущено событие OnTime, снова откроется.
Это лучше сделать, если специально остановить событие OnTime.
В приведенном выше коде у меня есть код StopRefresh, но вам нужно выполнить его, чтобы остановить событие OnTime. Вы можете сделать это вручную, назначить ее кнопке и сделать это, нажав кнопку или вызвав ее из события закрытия рабочей книги.
Private Sub Workbook_BeforeClose(Cancel As Boolean) Call StopRefresh End Sub
Вышеупомянутый код события «BeforeClose» находится в окне кода ThisWorkbook.
Событие Excel VBA OnKey
Когда вы работаете с Excel, он продолжает отслеживать нажатия клавиш, которые вы используете. Это позволяет нам использовать нажатия клавиш в качестве триггера для события.
С помощью события OnKey вы можете указать нажатие клавиши (или комбинацию нажатий клавиш) и код, который должен выполняться при использовании этого нажатия клавиши. При нажатии этих клавиш выполняется код для него.
Точно так же, как событие OnTime, у вас должен быть способ отменить событие OnKey. Кроме того, когда вы устанавливаете событие OnKey для определенного нажатия клавиши, оно становится доступным во всех открытых книгах.
Прежде чем я покажу вам пример использования события OnKey, позвольте мне сначала поделиться кодами клавиш, которые вам доступны в VBA.
Ключ | Код |
Backspace | {BACKSPACE} or {BS} |
Break | {BREAK} |
Caps Lock | {CAPSLOCK} |
Delete | {DELETE} or {DEL} |
Down Arrow | {DOWN} |
End | {END} |
Enter | ~ |
Enter (on the nueric keypad) | {ENTER} |
Escape | {ESCAPE} or {ESC} |
Home | {HOME} |
Ins | {INSERT} |
Left Arrow | {LEFT} |
NumLock | {NUMLOCK} |
PageDown | {PGDN} |
PageUp | {PGUP} |
RightArrow | {RIGHT} |
Scroll Lock | {SCROLLOCK} |
Tab | {TAB} |
Up Arrow | {UP} |
F1 through F15 | {F1} through {F15} |
Когда вам нужно использовать любое событие onkey, вам нужно использовать код для него.
В приведенной выше таблице приведены коды для однократных нажатий.
Вы также можете комбинировать их со следующими кодами:
Shift: + (знак плюс)
Контроль: ^ (Карет)
Alt:% (в процентах)
Например, для Alt F4 вам нужно использовать код: «% {F4}» — где% для клавиши ALT, а {F4} для клавиши F4.
Теперь давайте посмотрим на примере (помните, код для событий OnKey находится в обычном модуле VBA).
Когда вы нажимаете клавишу PageUp или PageDown, она переходит на 29 строк выше / ниже активной ячейки (по крайней мере, это то, что она делает на моем ноутбуке).
Если вы хотите, чтобы он перескакивал только на 5 строк одновременно, вы можете использовать следующий код:
Sub PageUpDOwnKeys() Application.OnKey "{PgUp}", "PageUpMod" Application.OnKey "{PgDn}", "PageDownMod" End Sub Sub PageUpMod() On Error Resume Next ActiveCell.Offset(-5, 0).Activate End Sub Sub PageDownMod() On Error Resume Next ActiveCell.Offset(5, 0).Activate End Sub
Когда вы запускаете первую часть кода, он запускает события OnKey. Как только это будет выполнено, использование PageUp и клавиши PageDown заставит курсор перескакивать только на 5 строк за раз.
Обратите внимание, что мы использовали «On Error Resume Next», чтобы убедиться, что ошибки игнорируются. Эти ошибки могут возникать, когда вы нажимаете клавишу PageUp, даже если вы находитесь в верхней части листа. Поскольку больше нет строк для перехода, код покажет ошибку. Но так как мы использовали «On Error Resume Next», он будет проигнорирован.
Чтобы убедиться, что эти события OnKey доступны, вам нужно запустить первую часть кода. Если вы хотите, чтобы это было доступно, как только вы откроете рабочую книгу, вы можете поместить ее в окно кода ThisWorkbook.
Private Sub Workbook_Open() Application.OnKey "{PgUp}", "PageUpMod" Application.OnKey "{PgDn}", "PageDownMod" End Sub
Приведенный ниже код вернет ключи к их нормальной работе.
Sub Cancel_PageUpDownKeysMod() Application.OnKey "{PgUp}" Application.OnKey "{PgDn}" End Sub
Если вы не укажете второй аргумент в методе OnKey, он вернет нажатие клавиши к своей обычной функциональности.
В случае, если вы хотите отменить функциональность нажатия клавиши, чтобы Excel ничего не делал при использовании этого нажатия клавиши, вам нужно использовать пустую строку в качестве второго аргумента.
В приведенном ниже коде Excel ничего не будет делать, когда мы используем ключи PageUp или PageDown.
Sub Ignore_PageUpDownKeys() Application.OnKey "{PgUp}", "" Application.OnKey "{PgDn}", "" End Sub
Отключение событий в VBA
Иногда вам может потребоваться отключить события, чтобы ваш код работал правильно.
Например, предположим, что у меня есть диапазон (A1: D10), и я хочу показать сообщение всякий раз, когда ячейка изменяется в этом диапазоне. Поэтому я показываю окно сообщения и спрашиваю пользователя, уверены ли они, что хотят внести изменения. Если ответ «Да», изменение внесено, и если ответ «Нет», VBA отменит его.
Вы можете использовать следующий код:
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Row <= 10 And Target.Column <= 4 Then Ans = MsgBox("Вы вносите изменения в ячейки в A1: D10. Вы уверены, что хотите это?", vbYesNo) End If If Ans = vbNo Then Application.Undo End If End Sub
Проблема с этим кодом заключается в том, что когда пользователь выбирает «Нет» в окне сообщения, действие отменяется (как я использовал Application.Undo).
Когда происходит отмена, и значение возвращается к исходному, событие изменения VBA снова инициируется, и пользователю снова отображается то же самое окно сообщения.
Это означает, что вы можете продолжать нажимать НЕТ в окне сообщения, и оно будет отображаться. Это происходит, когда вы застряли в бесконечном цикле в этом случае.
Чтобы избежать таких случаев, вам нужно отключить события, чтобы событие изменения (или любое другое событие) не срабатывало.
Следующий код будет хорошо работать в этом случае:
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Row <= 10 And Target.Column <= 4 Then Ans = MsgBox("Вы вносите изменения в ячейки в A1: D10. Вы уверены, что хотите это?", vbYesNo) End If If Ans = vbNo Then Application.EnableEvents = False Application.Undo Application.EnableEvents = True End If End Sub
В приведенном выше коде, прямо над строкой Application.Undo, мы использовали — Application.EnableEvents = False.
Если для параметра EnableEvents установлено значение False, это не приведет к возникновению какого-либо события (в текущей или любой открытой рабочей книге).
После того, как мы завершили операцию отмены, мы можем переключить свойство EnableEvents на True.
Имейте в виду, что отключение событий влияет на все книги, которые в данный момент открыты (или открыты, когда для параметра EnableEvents установлено значение False). Например, как часть кода, если вы откроете новую книгу, событие Workbook Open не будет работать.
Влияние событий Undo Stack
Позвольте мне сначала рассказать вам, что такое Undo Stack.
Когда вы работаете в Excel, он продолжает следить за вашими действиями. Когда вы делаете ошибку, вы всегда можете использовать Control + Z, чтобы вернуться к предыдущему шагу (то есть отменить ваше текущее действие).
Если вы дважды нажмете Control + Z, это вернет вас назад на два шага. Эти шаги, которые вы выполнили, сохраняются как часть Undo Stack.
Любое событие, которое изменяет рабочий лист, уничтожает этот стек отмены. Это означает, что если я выполнил 5 действий до запуска события, я не смогу использовать Control + Z, чтобы вернуться к этим предыдущим шагам. Запуск события уничтожил этот стек для меня.
В приведенном ниже коде я использую VBA для ввода метки времени в ячейку A1 при каждом изменении в листе.
Private Sub Worksheet_Change(ByVal Target As Range) Application.EnableEvents = False Range("A1").Value = Format(Now, "dd-mmm-yyyy hh:mm:ss") Application.EnableEvents = True End Sub
Поскольку я делаю изменения в листе, это уничтожит Undo Stack.
Также обратите внимание, что это не ограничивается только событиями.
Если у вас есть код, который хранится в обычном модуле VBA, и вы вносите изменения в рабочую таблицу, это также уничтожит Undo Stack в Excel.
Например, приведенный ниже код просто вводит текст «Hello» в ячейку A1, но даже выполнение этого приведет к разрушению
Undo Stack.
Sub TypeHello() Range("A1").Value = "Привет" End Sub
title | keywords | f1_keywords | ms.prod | api_name | ms.assetid | ms.date | ms.localizationpriority |
---|---|---|---|---|---|---|---|
Application.EnableEvents property (Excel) |
vbaxl10.chm133240 |
vbaxl10.chm133240 |
excel |
Excel.Application.EnableEvents |
5e14ce7b-02f6-03d4-2dfc-1df05a032301 |
04/04/2019 |
medium |
Application.EnableEvents property (Excel)
True if events are enabled for the specified object. Read/write Boolean.
Syntax
expression.EnableEvents
expression A variable that represents an Application object.
Example
This example disables events before a file is saved so that the BeforeSave event doesn’t occur.
Application.EnableEvents = False ActiveWorkbook.Save Application.EnableEvents = True
[!includeSupport and feedback]
Содержание
- Использование событий с объектами Excel
- Пример
- См. также
- Поддержка и обратная связь
- Производительность Excel: советы по оптимизации производительности
- Оптимизация ссылок и ссылок
- Не используйте прямую ссылку и обратную ссылку
- Минимизация использования циклических ссылок с помощью итерации
- Избегайте связей между книгами
- Свертывание связей между листами
- Свернуть используемый диапазон
- Разрешить дополнительные данные
- Использование ссылок на структурированные таблицы (рекомендуется)
- Кроме того, можно использовать ссылки на целые столбцы и строки.
- Кроме того, используйте динамические диапазоны.
- Повышение времени вычисления подстановки
- Общие сведения о параметрах подстановки
- Используйте INDEX и MATCH или OFFSET вместо ВПР
- Ускорение поиска
- Использование двух подстановок для отсортированных данных с отсутствующими значениями
- Использование функции IFERROR для несортированных данных с отсутствующими значениями
- Использование MATCH и INDEX для поиска точного соответствия в нескольких столбцах
- Использование INDEX для набора смежных строк или столбцов
- Использование MATCH для возврата прямоугольного блока ячеек
- Использование MATCH и INDEX для двухмерного поиска
- Использование диапазона подмножества для подстановки с несколькими индексами
- Рассмотрите варианты трехмерного подстановки
- Использование поиска с подстановочными знаками
- Оптимизация формул массива и SUMPRODUCT
- Рассмотрите варианты использования СУММ для формул массива с несколькими условиями
- Определение приоритета нескольких условий СУММЕСЛИ, СЧЁТЕСЛИ И других функций семейства IFS
- Рассмотрите варианты использования SUMPRODUCT для формул массива с несколькими условиями
- Использование SUMPRODUCT для умножения и добавления диапазонов и массивов
- Помните о потенциальных препятствиях для вычислений массивов и функций
- Эффективное использование функций
- Избегайте однопоточных функций
- Использование таблиц для функций, обрабатывающих диапазоны
- Сокращение изменяющихся функций
- Использование определяемых пользователем функций C или C++
- Использование более быстрых пользовательских функций VBA
- Сведите к минимуму диапазон ячеек, на которые ссылались СУММ и СУММЕСЛИ
- Использование подстановочных знаков SUMIF, COUNTIF, SUMIFS, COUNTIFS и других функций IFS
- Выбор метода для период-к-дате и накопительных SUM
- Вычисление сумм подмножества
- Использование ПРОМЕЖУТОЧНЫХ ИТОГОВ для отфильтрованных списков
- Использование функции AGGREGATE
- Избегайте использования DFunctions
- Создание более быстрых макросов VBA
- Отключить все, кроме основных компонентов во время выполнения кода
- Чтение и запись больших блоков данных в одной операции
- Использовать. Значение2, а не . Значение или . Текст при чтении данных из диапазона Excel
- Избегайте выбора и активации объектов
- Использование этих дополнительных оптимизаций производительности VBA
- Рассмотрите производительность и размер форматов файлов Excel
- Открытие, закрытие и сохранение книг
- Выполнение дополнительных оптимизаций производительности
- Заключение
- См. также
- Поддержка и обратная связь
Использование событий с объектами Excel
Вы можете написать процедуры событий в Microsoft Excel на уровне листа, диаграммы, таблицы запросов, книги или приложения. Например, событие Activate происходит на уровне листа, а событие SheetActivate доступно как на уровне книги, так и на уровне приложения. Событие SheetActivate для книги возникает при активации любого листа в книге. На уровне приложения событие SheetActivate возникает при активации любого листа в любой открытой книге.
Процедуры листа, диаграммы и событий доступны для любого открытого листа или книги. Чтобы написать процедуры событий для внедренной диаграммы, объекта QueryTable или объекта Application , необходимо создать новый объект с помощью ключевого слова WithEvents в модуле класса.
Используйте свойство EnableEvents для включения или отключения событий. Например, использование метода Save для сохранения книги приводит к возникновению события BeforeSave. Это можно предотвратить, задав для свойства EnableEvents значение False перед вызовом метода Save .
Пример
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
Производительность Excel: советы по оптимизации производительности
Применимо к: Excel | | Excel 2013 Office 2016 | VBA
Следуйте этим советам по оптимизации многих часто возникающих препятствий производительности в Excel.
Оптимизация ссылок и ссылок
Узнайте, как повысить производительность, связанную с типами ссылок и ссылок.
Не используйте прямую ссылку и обратную ссылку
Чтобы повысить ясность и избежать ошибок, спроектируйте формулы так, чтобы они не ссылались на другие формулы или ячейки (справа или ниже). Прямая ссылка обычно не влияет на производительность вычислений, за исключением крайних случаев для первого вычисления книги, когда создание разумной последовательности вычислений может занять больше времени, если существует много формул, для которых требуется отложить вычисление.
Минимизация использования циклических ссылок с помощью итерации
Вычисление циклических ссылок с итерациями выполняется медленно, так как требуется несколько вычислений, и эти вычисления являются однопоточными. Часто можно «раскрутить» циклические ссылки с помощью алгебры, чтобы итеративное вычисление больше не требовалось. Например, при расчете денежного потока и процентов попробуйте вычислить денежный поток до процента, вычислить процент, а затем вычислить денежный поток, включая проценты.
Excel вычисляет циклические ссылки по листу без учета зависимостей. Таким образом, если циклические ссылки охватывают несколько листов, скорость вычислений обычно снижается. Попробуйте переместить все циклические ссылки на один лист или оптимизировать последовательность вычислений на листе, чтобы избежать ненужных вычислений.
Перед началом итеративных вычислений в Excel должен быть выполнен пересчет книги, в ходе которого определяются все циклические ссылки и зависимости. Этот процесс эквивалентен двум или трем итерациям вычислений.
После определения циклических ссылок и зависимостей на каждой итерации приложение Excel вычисляет не только все ячейки в циклической ссылке, но также и ячейки, зависящие от ячеек в цепочке циклической ссылке, и переменные ячейки с зависимостями. Сложное вычисление, которое зависит от ячеек в циклической ссылке, более эффективно поместить в отдельную закрытую книгу, которую следует открыть и пересчитать уже после того, как будет вычислена циклическая ссылка.
Важно уменьшить количество ячеек в циклических вычислениях и время вычисления, затраченного этими ячейками.
Избегайте связей между книгами
Избегайте связей между книгами, когда это возможно; они могут быть медленными, легко сломанными, и не всегда легко найти и исправить.
Использование небольшого числа крупных книг обычно (но не всегда) более эффективно, чем использование множества небольших книг. Некоторые исключения из этого могут быть, когда у вас есть много внешних вычислений, которые настолько редко пересчитываются, что имеет смысл поместить их в отдельную книгу или если у вас недостаточно ОЗУ.
Попробуйте использовать простые прямые ссылки на ячейки в закрытых книгах. Это позволяет избежать пересчета всех связанных книг при пересчете любых книг. Кроме того, вы можете увидеть значения, считанные Excel из закрытой книги, что часто важно для отладки и аудита книги.
Если не удается избежать использования связанных книг, попробуйте оставить все нужные книги открытыми (при этом книги, на которые указывают связи, следует открывать после того, как открыты книги, из которых исходят связи).
Свертывание связей между листами
Разбиение книги на множество листов обычно делает ее более простой в использовании, однако снижает производительность вычислений ссылок на другие листы относительно ссылок в пределах одного листа.
Свернуть используемый диапазон
Чтобы сохранить память и уменьшить размер файла, Excel пытается сохранить сведения только о той области листа, которая использовалась. Эта область называется используемый диапазон. Некоторые операции редактирования и форматирования охватывают область, значительно превышающую диапазон, который на данный момент считается используемым. Это может привести к проблемам, связанным с производительностью и размером файла.
Вы можете проверить видимый используемый диапазон на листе с помощью клавиш CTRL+END. Если это слишком много, рекомендуется удалить все строки и столбцы ниже и справа от последней использованной ячейки, а затем сохранить книгу. Перед этим следует создать резервную копию. Если некоторые формулы содержат диапазоны, указывающие или ссылающиеся на удаленные области, эти диапазоны будут уменьшены в размере или получат значение #Н/Д.
Разрешить дополнительные данные
Если в листы часто добавляются строки или столбцы данных, необходимо найти способ автоматического задания ссылок формул Excel на новые области данных вместо того, чтобы каждый раз искать и обновлять формулы.
Для этого можно использовать в формулах большой диапазон, который выходит далеко за пределы текущей области данных. Тем не менее, в некоторых случаях это может привести к неэффективным вычислениям и сложностям при обслуживании, поскольку при удалении строк и столбцов диапазон может быть уменьшен без уведомления.
Использование ссылок на структурированные таблицы (рекомендуется)
Начиная с Excel 2007, можно использовать структурированные ссылки на таблицы, которые автоматически расширяются и сжимаются по мере увеличения или уменьшения размера указанной таблицы.
Такой подход имеет ряд преимуществ:
Существует меньше недостатков производительности, чем альтернативные варианты ссылок на целые столбцы и динамические диапазоны.
На одном листе легко создать несколько таблиц данных.
Возможность расширения и сокращения внедренных в таблицу формул в соответствии с изменением размера области данных.
Кроме того, можно использовать ссылки на целые столбцы и строки.
Альтернативный подход заключается в использовании ссылки на столбец целиком, например, $A:$A. Эта ссылка возвращает все строки в столбце A. В этом случае все добавляемые данные всегда будут включаться в ссылку.
Такой подход имеет свои преимущества и недостатки:
Многие встроенные функции Excel (SUM, SUMIF) эффективно вычисляют ссылки на столбцы целиком, поскольку они автоматически распознают последнюю использованную строку в столбце. Тем не менее, функции вычисления массивов, такие как SUMPRODUCT, либо не могут обрабатывать ссылки на столбцы целиком, либо вычисляют все ячейки в столбце.
Определяемые пользователем функции не распознают последнюю используемую строку в столбце автоматически и, следовательно, часто вычисляют ссылки на целые столбцы неэффективно. Тем не менее, запрограммировать пользовательские функции на распознавание последней использованной строки достаточно легко.
При наличии нескольких таблиц данных на одном листе трудно использовать ссылки на целые столбцы.
В Excel 2007 и более поздних версиях формулы массива могут обрабатывать ссылки на целые столбцы, но это приводит к принудительному вычислению для всех ячеек в столбце, включая пустые. Для крупных таблиц, содержащих миллионы строк, это может привести к существенному снижению производительности.
Кроме того, используйте динамические диапазоны.
С помощью функций OFFSET или INDEX и COUNTA в определении именованного диапазона можно динамически расширять и сжимать область, на которую ссылается именованный диапазон. Например, создайте определенное имя, используя одну из следующих формул:
При использовании имени динамического диапазона в формуле он автоматически расширяется для включения новых записей.
Использование формулы INDEX для динамического диапазона, как правило, предпочтительнее формулы OFFSET , так как недостаток OFFSET заключается в том, что она является изменяющейся функцией, которая будет вычисляться при каждом пересчете.
Производительность снижается, так как функция COUNTA в формуле динамического диапазона должна проверять много строк. Это снижение производительности можно свести к минимуму, сохранив часть формулы COUNTA в отдельной ячейке или заданном имени, а затем сославшись на ячейку или имя в динамическом диапазоне:
Вы также можете использовать такие функции, как INDIRECT , для создания динамических диапазонов, но INDIRECT является изменчивым и всегда вычисляет однопотоковые.
Применение динамических диапазонов имеет свои преимущества и недостатки:
Динамические диапазоны эффективно использовать для ограничения числа вычислений, выполняемых формулами массива.
Для использования нескольких динамических диапазонов в одном столбце требуются специальные функции подсчета.
Использование большого числа динамических диапазонов может привести к снижению производительности.
Повышение времени вычисления подстановки
В Office 365 версии 1809 и более поздних функции Excel ВПР, ГПР и ПОИСКПОЗ для поиска точного совпадения в несортированных данных выполняются как никогда быстро при поиске в нескольких столбцах (или строках с помощью ГПР) из одного диапазона таблицы.
При этом для более ранних версий Excel поиск по-прежнему является часто значительным препятствием для вычислений. Тем не менее, существует много способов оптимизации вычисления поиска. Если используется параметр точного совпадения, время вычисления функции пропорционально числу ячеек, проверяемому до нахождения совпадения. Для поиска в больших диапазонах это время может быть достаточно велико.
Время поиска с использованием параметров приблизительного совпадения VLOOKUP, HLOOKUP и MATCH для отсортированных данных достаточно мало и не увеличивается существенно с изменением длины диапазона, для которого выполняется поиск. В этом случае характеристики аналогичны характеристикам двоичного поиска.
Общие сведения о параметрах подстановки
Убедитесь, что вы понимаете параметры сопоставления типов и диапазонов поиска в MATCH, VLOOKUP и HLOOKUP.
В следующем примере кода показан синтаксис функции MATCH. Дополнительные сведения см. в описании метода Match объекта WorksheetFunction.
Matchtype=1 возвращает наибольшее совпадение, меньшее или равное значению подстановки, если массив подстановки отсортирован по возрастанию (приблизительное совпадение). Если массив подстановки не отсортирован по возрастанию, функция MATCH вернет неправильный ответ. Параметр по умолчанию — приблизительное соответствие по возрастанию.
Matchtype=0 запрашивает точное совпадение. При этом предполагается, что данные не отсортированы.
Matchtype=-1 возвращает наименьшее совпадение, значение которого не меньше значения поиска, при сортировке массива поиска по убыванию (приблизительное совпадение).
В следующем примере кода показан синтаксис функций VLOOKUP и HLOOKUP. Дополнительные сведения см. в описании методов ВПР и ГПР объекта WorksheetFunction.
Range-lookup=TRUE возвращает наибольшее совпадение, значение которого не превышает значение поиска (приблизительное совпадение). Это параметр по умолчанию. Табличные массивы должны быть отсортированы по возрастанию.
Range-lookup=FALSE запрашивает точное совпадение. При этом предполагается, что данные не отсортированы.
По возможности рекомендуется избегать поиска неотсортированных данных, поскольку это влечет за собой снижение производительности. Если данные отсортированы, но требуется точное совпадение, см. раздел Использование двух подстановок для отсортированных данных с отсутствующими значениями.
Используйте INDEX и MATCH или OFFSET вместо ВПР
Попробуйте использовать функции INDEX и MATCH вместо VLOOKUP. Хотя функция ВПР выполняется немного быстрее (примерно на 5 процентов быстрее), проще и использует меньше памяти, чем сочетание MATCH и INDEX или OFFSET, дополнительная гибкость, которую часто предлагают MATCH и INDEX , позволяет значительно сэкономить время. Например, можно сохранить результат точного совпадения MATCH в ячейке и затем повторно использовать его в нескольких выражениях INDEX.
Функция INDEX является быстрой и является энергонезависимой функцией, которая ускоряет пересчет. Функция OFFSET также работает быстро; однако это изменчивая функция, которая иногда значительно увеличивает время, затрачиваемое на обработку цепочки вычислений.
Преобразовать VLOOKUP в INDEX и MATCH легко. Следующие два оператора возвращают один и тот же ответ:
Ускорение поиска
Поскольку поиск с точным совпадением может выполняться достаточно медленно, можно рассмотреть следующие способы повышения производительности:
Используйте один лист. Поиски и данные на одном листе будут храниться быстрее.
По возможности сначала выполняйте сортировку данных (функция SORT работает быстрее). После выполнения функции SORT используйте приблизительное совпадение.
Если требуется выполнить поиск с точным совпадением, попробуйте максимально ограничить диапазон сканируемых ячеек. Используйте таблицы и структурированные ссылки или имена динамических диапазонов вместо того, чтобы ссылаться на большое количество строк или столбцов. В некоторых случаях можно заранее вычислить нижние и верхние границы диапазона для поиска.
Использование двух подстановок для отсортированных данных с отсутствующими значениями
Два приблизительных совпадения значительно быстрее, чем одно точное совпадение для поиска более нескольких строк. (Точка безубыточного останова составляет около 10–20 строк.)
Если вы можете отсортировать данные, но по-прежнему не можете использовать приблизительное совпадение, так как не можете быть уверены, что искомое значение существует в диапазоне подстановки, можно использовать следующую формулу:
В первой части формулы осуществляется поиск приблизительного совпадения для самого столбца поиска.
Вы можете проверить, совпадает ли ответ из столбца подстановки со значением подстановки (в этом случае точное совпадение) с помощью следующей формулы:
Если эта формула возвращает значение True, вы нашли точное совпадение, поэтому вы можете выполнить приблизительный поиск еще раз, но на этот раз верните ответ из нужного столбца.
Если ответ из столбца подстановки не совпадает со значением подстановки, у вас отсутствует значение, и формула возвращает значение notexist.
Обратите внимание, что если выполняется поиск значения, которое меньше, чем минимальное значение в списке, отображается сообщение об ошибке. Можно реализовать обработку этой ошибки с помощью функции IFERROR или добавить в список минимальное тестовое значение.
Использование функции IFERROR для несортированных данных с отсутствующими значениями
Если необходимо использовать точный поиск соответствия для несортированных данных и вы не можете быть уверены, существует ли значение подстановки, часто необходимо обработать возвращаемое #N/A, если совпадение не найдено. Начиная с Excel 2007, вы можете использовать функцию IFERROR , которая является простой и быстрой.
В более ранних версиях можно применять простой, но более медленный способ с использованием функции IF, подразумевающий выполнение двух операций поиска.
Чтобы избежать двойного поиска точного совпадения, можно один раз выполнить поиск MATCH с точным совпадением, сохранить результат в ячейке, а затем проверять этот результат перед выполнением функции INDEX.
Если нельзя использовать две ячейки, воспользуйтесь функцией COUNTIF. Как правило, это быстрее, чем поиск точного соответствия.
Использование MATCH и INDEX для поиска точного соответствия в нескольких столбцах
Во многих случаях можно многократно использовать сохраненное точное совпадение MATCH. Например, при выполнении точного поиска в нескольких столбцах результатов можно сэкономить время, используя одно выражение MATCH и несколько выражений INDEX вместо множества выражений VLOOKUP.
Добавьте дополнительный столбец для match , чтобы сохранить результат ( stored_row ), и для каждого столбца результата используйте следующее:
Также можно использовать функцию VLOOKUP в формуле массива. (Формулы массива необходимо вводить с помощью клавиш CTRL+-SHIFT+ВВОД. Excel добавит < и >, чтобы показать, что это формула массива).
Использование INDEX для набора смежных строк или столбцов
Одна операция поиска может возвращать несколько ячеек. Для поиска в непрерывной последовательности из нескольких столбцов можно использовать функцию INDEX в формуле массива, что позволит возвращать несколько столбцов за один раз (используйте 0 в качестве номера столбца). Также можно использовать INDEX для возврата нескольких строк за один раз.
Это выражение возвращает столбцы с A по J из сохраненной строки, созданной предыдущим выражением MATCH.
Использование MATCH для возврата прямоугольного блока ячеек
Используйте функции MATCH и OFFSET для возврата прямоугольного блока ячеек.
Использование MATCH и INDEX для двухмерного поиска
Вы можете эффективно выполнять подстановку двумерной таблицы, используя отдельные подстановки для строк и столбцов таблицы с помощью функции INDEX с двумя встроенными функциями MATCH : одна для строки и одна для столбца.
Использование диапазона подмножества для подстановки с несколькими индексами
На больших листах часто может потребоваться выполнить поиск с помощью нескольких индексов, таких как поиск объемов продуктов в стране. Для этого можно объединить индексы и выполнить поиск с использованием объединенных значений поиска. Тем не менее, такой подход неэффективен по двум причинам:
Операция объединения строк требует больших затрат вычислительных ресурсов.
Поиск охватывает большой диапазон.
Часто более эффективно вычислить диапазон подмножества для подстановки (например, путем поиска первой и последней строк для страны, а затем поиска продукта в этом диапазоне подмножества).
Рассмотрите варианты трехмерного подстановки
Чтобы выполнять поиск в таблице в дополнение к строке и столбцу, можно использовать следующие способы, в которых основной акцент делается на способ поиска или выбора таблицы в Excel.
Если каждая таблица, которую требуется найти (третье измерение), хранится в виде набора именованных структурированных таблиц, имен диапазонов или таблицы текстовых строк, представляющих диапазоны, вы можете использовать функции CHOOSE или INDIRECT .
В некоторых случаях более эффективно будет использовать функцию CHOOSE и имена диапазонов. Функция CHOOSE не является переменной, однако оптимально подходит только при наличии небольшого числа таблиц. В этом примере динамически используется TableLookup_Value для выбора имени диапазона ( TableName1, TableName2, . ), которое будет использоваться для таблицы подстановки.
В следующем примере функция INDIRECT используется для TableLookup_Value динамического создания имени листа, используемого для таблицы подстановки. Этот метод достаточно прост и эффективен при работе с большим числом таблиц. Так как INDIRECT является изменяющейся однопоточной функцией, поиск вычисляется по одному потоку при каждом вычислении, даже если данные не изменились. Использование этого метода выполняется медленно.
Также можно использовать функцию VLOOKUP для поиска имени листа или текстовой строки, которые будут использоваться для таблицы, а затем с помощью функции INDIRECT преобразовать полученный текст в диапазон.
Другой способ заключается в объединении всех таблиц в одну большую таблицу с дополнительным столбцом, в котором содержатся идентификаторы каждой таблицы. Этот способ можно применять для поиска по нескольким индексам, который показан в предыдущих примерах.
Использование поиска с подстановочными знаками
Функции MATCH, VLOOKUP и HLOOKUP позволяют использовать подстановочные знаки ? (любой один символ) и * (без символов или любое количество символов) в алфавитном точном совпадении. В некоторых случаях такой метод может использоваться для поиска уникального совпадения.
Оптимизация формул массива и SUMPRODUCT
Применение формул массива и функций SUMPRODUCT дает широкие возможности, однако при этом следует соблюдать осторожность. Для одной формулы массива может потребоваться много вычислений.
Чем меньшее число ячеек и выражений вычисляется в формуле массива, тем выше будет скорость ее вычисления. Помните, что формула массива немного похожа на изменяющуюся формулу: если какая-либо из ячеек, на которую она ссылается, изменилась, является изменчивой или была пересчитана, формула массива вычисляет все ячейки формулы и вычисляет все виртуальные ячейки, необходимые для вычисления.
Оптимизация скорости вычисления формул массива:
Выведите ссылки на выражения и диапазоны за пределы формул массива в отдельные вспомогательные столбцы и строки. Это позволит более эффективно использовать процесс интеллектуального пересчета в Excel.
Не задавайте ссылки на строки целиком или большее, чем требуется, число строк и столбцов. Формулы массива принудительно вычисляют все ссылки на ячейки в формуле (в том числе и ссылки на пустые и неиспользуемые ячейки). Поскольку начиная с версии Excel 2007 поддерживается более миллиона строк, формула массива, ссылающаяся на столбец целиком, будет вычисляться очень медленно.
Начиная с версии Excel 2007, по возможности используйте структурированные ссылки, чтобы свести к минимуму число ячеек, которые вычисляются в формуле массива.
В версиях, предшествующих Excel 2007, по возможности используйте имена динамических диапазонов. Несмотря на то, что при таком подходе используется переменная функция, это позволит свести к минимуму размеры диапазонов.
Обращайте внимание на формулы массива, ссылающиеся одновременно на строку и столбец: в этом случае вычисляется прямоугольный диапазон.
По возможности, используйте функцию SUMPRODUCT. Она работает несколько быстрее по сравнению с эквивалентной формулой массива.
Рассмотрите варианты использования СУММ для формул массива с несколькими условиями
Вместо формул массива всегда следует использовать функции SUMIFS, COUNTIFS и AVERAGEIFS , так как они вычисляются гораздо быстрее. Excel 2016 представлены быстрые функции MAXIFS и MINIFS.
В версиях, предшествующих Excel 2007, формулы массива часто используются для вычисления суммы с несколькими условиями. Это относительно простой (особенно если используется Мастер суммирования Excel), однако зачастую очень медленный способ. Обычно те же результаты можно получить гораздо быстрее. При работе с небольшим числом формул СУММ с несколькими условиями можно использовать функцию DSUM, которая значительно быстрее эквивалентной формулы массива.
Если все же требуется использовать формулы массива, можно применять следующие эффективные методы для повышения их скорости:
Используйте имена динамических диапазонов или ссылки на структурированные таблицы, чтобы свести к минимуму количество ячеек.
Разделите несколько условий на столбец вспомогательных формул, возвращающих значение True или False для каждой строки, а затем сослаться на вспомогательный столбец в формуле СУММЕСЛИ или массива. Может показаться, что это не приведет к сокращению числа вычислений для одной формулы массива; однако большую часть времени он позволяет процессу интеллектуального пересчета пересчитывать только формулы во вспомогательном столбце, которые необходимо пересчитать.
Рассмотрите возможность объединения всех условий в одно, для которого будет использоваться функция SUMIF.
Если данные можно отсортировать, подсчитайте группы строк и ограничьте формулы массива просмотром групп подмножества.
Определение приоритета нескольких условий СУММЕСЛИ, СЧЁТЕСЛИ И других функций семейства IFS
Эти функции по очереди оценивают каждое из условий слева направо. Таким образом, более эффективно поставить на первое место наиболее ограничивающее условие, чтобы последующие условия должны были смотреть только на наименьшее количество строк.
Рассмотрите варианты использования SUMPRODUCT для формул массива с несколькими условиями
Начиная с Excel 2007, всегда следует использовать функции SUMIFS, СЧЁТЕСЛИ И AVERAGEIFS, а в Excel 2016 функции MAXIFS и MINIFS вместо формул SUMPRODUCT, где это возможно.
В более ранних версиях применение функции SUMPRODUCT вместо формул массива SUM давало ряд преимуществ:
SUMPRODUCT не обязательно вводить массив с помощью клавиш CTRL+SHIFT+ВВОД.
Функция SUMPRODUCT обычно выполняется несколько быстрее (от 5 до 10 процентов).
Используйте SUMPRODUCT для формул массива с несколькими условиями следующим образом:
В этом примере и Condition2 являются условными выражениями, Condition1 такими как $A$1:$A$10000 . Поскольку условные выражения вместо числовых данных возвращают значения True или False, их необходимо привести к числовым значениям в функции SUMPRODUCT. Это можно сделать, используя два знака минус (—), добавив 0 (+0) или умножив на 1 (x1). Использование — выполняется немного быстрее, чем +0 или x1.
Обратите внимание, что размер и форма диапазонов или массивов, которые используются в суммируемых диапазонах и условных выражениях, должны быть одинаковыми. При этом они не могут содержать столбцы целиком.
Кроме того, можно напрямую умножить термины внутри SUMPRODUCT, а не разделять их запятыми:
Обычно это немного медленнее, чем использование синтаксиса запятой, и выдает ошибку, если диапазон суммирования содержит текстовое значение. Однако он немного более гибкий, так как диапазон для суммирования может иметь, например, несколько столбцов, если условия имеют только один столбец.
Использование SUMPRODUCT для умножения и добавления диапазонов и массивов
В некоторых случаях, например, при вычислении средневзвешенных значений, когда требуется перемножение диапазонов чисел и суммирование результатов, применение синтаксиса функции SUMPRODUCT с разделением запятыми может быть на 20–25 процентов эффективнее, чем использование функции SUM с вводом массива.
Все эти три формулы дают одинаковый результат, но третья формула, использующая синтаксис запятых для SUMPRODUCT, занимает только около 77 процентов времени вычисления, необходимого для двух других формул.
Помните о потенциальных препятствиях для вычислений массивов и функций
Ядро вычислений Excel оптимизировано для работы с формулами массива и функциями, ссылающимися на диапазоны. Тем не менее, при нестандартном использовании таких формул и функций в некоторых случаях возможно существенное увеличение времени вычисления.
При обнаружении проблем при вычислениях с применением формул и функций диапазонов следует обратить внимание на наличие следующих препятствий:
Частично перекрывающиеся ссылки.
Формулы массива и функции диапазонов, ссылающиеся на блок ячеек, которые вычисляются в другой формуле массива или функции диапазона. Такие ситуации достаточно часто происходят во время анализа временных последовательностей.
Наличие различных наборов формул, один из которых ссылается по строке, а второй ссылается на первый набор по столбцу.
Крупный набор одностроковых формул массива, охватывающих блок столбцов с функцией SUM в нижней части каждого столбца.
Эффективное использование функций
Функции значительно расширяют возможности Excel, но способ их использования часто может повлиять на время вычисления.
Избегайте однопоточных функций
Большинство собственных функций Excel хорошо работают с многопотоковые вычисления. Однако по возможности избегайте использования следующих однопоточных функций:
- Определяемые пользователем функции VBA и службы автоматизации, но определяемые пользователем функции на основе XLL могут быть многопотоковые.
- PHONETIC
- ЯЧЕЙКА, когда используется аргумент «format» или «address»
- СМЕЩ
- ПОЛУЧИТЬ.ДАННЫЕ.СВОДНОЙ.ТАБЛИЦЫ
- КУБЭЛЕМЕНТ
- КУБЗНАЧЕНИЕ
- КУБСВОЙСТВОЭЛЕМЕНТА
- КУБМНОЖ
- КУБПОРЭЛЕМЕНТ
- КУБЭЛЕМЕНТКИП
- КУБЧИСЛОЭЛМНОЖ
- АДРЕС, где указан пятый параметр () sheet_name
- Любая функция базы данных (БДСУММ, ДСРЗНАЧ, и т. д.), которая ссылается на сводную таблицу
- ТИП.ОШИБКИ
- ГИПЕРССЫЛКА
Использование таблиц для функций, обрабатывающих диапазоны
Для таких функций, как SUM, SUMIF и SUMIFS , обрабатывающих диапазоны, время вычисления пропорционально количеству используемых ячеек, которые вы суммируете или подсчитываете. Неиспользуемые ячейки не проверяются, поэтому ссылки на целые столбцы относительно эффективны, но лучше убедиться, что вы не включаете больше используемых ячеек, чем нужно. Используйте таблицы или вычисляйте диапазоны подмножества или динамические диапазоны.
Сокращение изменяющихся функций
Применение переменных функций может уменьшить скорость пересчета, поскольку в таком случае увеличивается число пересчитываемых при каждом вычислении формул.
Зачастую можно уменьшить число переменных функций, используя функцию INDEX вместо OFFSET и функцию CHOOSE вместо INDIRECT. Тем не менее , OFFSET — это быстрая функция, которую часто можно использовать в творческих способах, позволяющих быстро вычислять.
Использование определяемых пользователем функций C или C++
Определяемые пользователем функции, запрограммированные на C или C++ и использующие API C (функции надстроек XLL), обычно выполняются быстрее, чем определяемые пользователем функции, разработанные с помощью VBA или автоматизации (надстройки XLA или automation). Дополнительные сведения см. в статьеDeveloping Excel 2010 XLLs.
Производительность определяемых пользователем функций VBA определяется тем, как вы программировать и вызывать их.
Использование более быстрых пользовательских функций VBA
Обычно использовать вычисления формул и функции листа Excel быстрее, чем использовать определяемые пользователем функции VBA. Это связано с тем, что при применении каждой пользовательской функции небольшой объем ресурсов расходуется на вызов функции и достаточно значительный объем ресурсов на передачу данных из Excel в такую функцию. Тем не менее, эффективно проработанные и вызываемые функции могут выполняться значительно быстрее по сравнению со сложными формулами массива.
Убедитесь, что все ссылки на ячейки листа в пользовательской функции помещены во входные параметры, а не в тело самой функции, что позволяет избежать добавления ненужных элементов Application.Volatile.
Если необходимо иметь много формул, использующих определяемые пользователем функции, убедитесь, что вы находитесь в режиме вычисления вручную и что вычисление инициируется из VBA. Пользовательские функции VBA вычисляются значительно медленнее, если вычисление вызывается не из VBA (например, в автоматическом режиме или с помощью клавиши F9 в ручном режиме). Это особенно актуально, когда редактор Visual Basic (ALT+F11) открыт или был открыт в текущем сеансе Excel.
В этом случае можно перехватывать нажатие клавиши F9 и выполнять перенаправление в подпрограмму вычисления VBA, как показано ниже. Добавьте эту подпрограмму в модуль Thisworkbook .
Добавьте в стандартный модуль следующую подпрограмму.
Определяемые пользователем функции в надстройках службы автоматизации (Excel 2002 и более поздних версий) не влечет за собой дополнительных затрат редактора Visual Basic, так как они не используют интегрированный редактор. Другие характеристики производительности пользовательских функций Visual Basic 6 в надстройках автоматизации аналогичны функциям VBA.
Если пользовательская функция обрабатывает каждую ячейку диапазона, следует объявить входной параметр как диапазон, назначить его переменной, содержащей массив, и реализовать его циклический перебор. Для эффективной обработки ссылок на столбцы целиком необходимо использовать подмножество входного диапазона, разбив его на пересечении с используемым диапазоном, как показано в этом примере.
Если для обработки диапазона в пользовательской функции используются функции листа или методы объектной модели Excel, зачастую более эффективно хранить диапазон в виде объектной переменной, чем передавать все данные из Excel в такую функцию.
Если определяемая пользователем функция вызывается в начале цепочки вычислений, ее можно передать как нерасчетные аргументы. Внутри определяемой пользователем функции можно обнаружить нерасчетные ячейки с помощью следующего теста для пустых ячеек, содержащих формулу:
Для каждого вызова определяемой пользователем функции и для каждой передачи данных из Excel в VBA существуют временные затраты. Иногда определяемая пользователем функция с формулой массива с несколькими ячейками может помочь свести к минимуму эти издержки, объединяя несколько вызовов функций в одну функцию с диапазоном входных данных с несколькими ячейками, который возвращает диапазон ответов.
Сведите к минимуму диапазон ячеек, на которые ссылались СУММ и СУММЕСЛИ
Функции Excel SUM и SUMIF часто используются при работе с большим числом ячеек. Время вычисления этих функций пропорционально числу охватываемых ячеек, поэтому рекомендуется свести к минимуму диапазон ячеек, на которые ссылаются функции.
Использование подстановочных знаков SUMIF, COUNTIF, SUMIFS, COUNTIFS и других функций IFS
Используйте подстановочные знаки ? (любой один символ) и * (без символов или любого количества символов) в критериях для алфавитных диапазонов в составе функций SUMIF, COUNTIFS, СЧЁТЕСЛИ и других функций IFS.
Выбор метода для период-к-дате и накопительных SUM
Существует два метода выполнения период-к-дата или кумулятивные suM. Предположим, что числа, которые требуется суммировать суммой суммы , находятся в столбце A, а столбец B будет содержать совокупную сумму; вы можете выполнить одно из следующих действий:
Вы можете создать формулу в столбце B, например, =SUM($A$1:$A2) и перетащить ее вниз по мере необходимости. В качестве начальной ячейки для функции СУММ зафиксирована ячейка A1, однако, поскольку конечная ячейка содержит относительную ссылку на строку, ее номер автоматически увеличивается для каждой строки.
Вы можете создать формулу, например =$A1 в ячейках B1 и =$B1+$A2 B2, и перетащить ее вниз по мере необходимости. В этом случае накопительная сумма в ячейке будет вычисляться посредством сложения значения в текущей строке с накопительной суммой в предыдущей строке (аналогично применению функции SUM).
Для набора из 1000 строк при первом способе приложение Excel выполняет около 500 000 вычислений. Для этого же набора второй способ требует всего 2000 вычислений.
Вычисление сумм подмножества
При наличии нескольких отсортированных индексов в таблице (например, Сайт в области) часто можно сэкономить значительное время вычислений, динамически вычисляя адрес диапазона подмножеств строк (или столбцов), используемых в функциях SUM или SUMIF .
Чтобы вычислить адрес диапазона подмножества строк или столбцов, выполните следующие действия:
Подсчитайте число строк для каждого подблока.
Чтобы определить начальную строку каждого блока, суммируйте число строк накопительно.
Используйте функцию OFFSET, указав в качестве параметра начальную строку и число строк, чтобы вернуть в функцию SUM или SUMIF поддиапазон, который охватывает только определенный блок строк.
Использование ПРОМЕЖУТОЧНЫХ ИТОГОВ для отфильтрованных списков
С помощью функции SUBTOTAL можно суммировать (функция SUM) отфильтрованные списки. Функция SUBTOTAL эффективна в использовании, поскольку, в отличие от функции SUM, она пропускает следующие элементы:
Скрытые в результате фильтрации списка строки. Начиная с версии Excel 2003, можно также выполнять функцию SUBTOTAL, пропуская все скрытые, а не только отфильтрованные строки.
Другие функции SUBTOTAL.
Использование функции AGGREGATE
Функция AGGREGATE — это эффективный и эффективный способ вычисления 19 различных методов агрегирования данных (таких как SUM, MEDIAN, PERCENTILE и LARGE). ФУНКЦИЯ AGGREGATE позволяет игнорировать скрытые или отфильтрованные строки, значения ошибок и вложенные функции SUBTOTAL и AGGREGATE .
Избегайте использования DFunctions
Функции DSUM, DCOUNT, DAVERAGE и аналогичные им работают намного быстрее по сравнению с эквивалентными формулами массива. Недостатком таких функций является то, что условие должно находиться в отдельном диапазоне, что делает их использование непрактичным во многих случаях. Начиная с версии Excel 2007, вместо этих функций следует использовать функции SUMIFS, COUNTIFS и AVERAGEIFS.
Создание более быстрых макросов VBA
Ниже приведены советы по созданию более быстрых макросов VBA.
Отключить все, кроме основных компонентов во время выполнения кода
Чтобы повысить производительность макросов VBA, явно отключите функциональность, которая не требуется во время выполнения кода. Часто один пересчет или один перерисовка после выполнения кода — это все, что необходимо и может повысить производительность. После выполнения кода восстановите функциональность в исходное состояние.
При выполнении макросов VBA обычно можно отключать следующие функции:
Application.ScreenUpdating Отключить обновление экрана. Если параметр Application.ScreenUpdating имеет значение False, Excel не перерисовывает экран. Во время выполнения кода экран быстро обновляется, и пользователю обычно не нужно видеть каждое обновление. Обновление экрана один раз после выполнения кода повышает производительность.
Application.DisplayStatusBar Отключите строку состояния. Если параметр Application.DisplayStatusBar имеет значение False, excel не отображает строку состояния. Параметр строки состояния отделен от параметра обновления экрана, поэтому вы по-прежнему можете отображать состояние текущей операции, даже если экран не обновляется. Однако если вам не нужно отображать состояние каждой операции, отключение строки состояния во время выполнения кода также повышает производительность.
Application.Calculation Переключитесь на ручное вычисление. Если параметр Application.Calculation имеет значение xlCalculationManual, Excel вычисляет книгу только тогда, когда пользователь явно инициирует вычисление. В режиме автоматического вычисления Excel определяет время вычисления. Например, при каждом изменении значения ячейки, связанного с формулой, Excel пересчитывает формулу. При переключении режима вычисления на ручной можно подождать, пока не будут обновлены все ячейки, связанные с формулой, перед пересчетом книги. Пересчитывая книгу только при необходимости во время выполнения кода, можно повысить производительность.
Application.EnableEvents Отключить события. Если параметр Application.EnableEvents имеет значение False, Excel не вызывает события. Если надстройки прослушивают события Excel, эти надстройки потребляют ресурсы на компьютере при записи событий. Если надстройке не требуется записывать события, возникающие во время выполнения кода, отключение событий повышает производительность.
ActiveSheet.DisplayPageBreaks Отключить разрывы страниц. Если параметр ActiveSheet.DisplayPageBreaks имеет значение False, Excel не отображает разрывы страниц. Не нужно пересчитывать разрывы страниц во время выполнения кода, а вычисление разрывов страниц после выполнения кода повышает производительность.
Не забудьте восстановить исходное состояние этих функций после выполнения кода.
В следующем примере показаны функции, которые можно отключить в процессе выполнения макроса VBA.
Чтение и запись больших блоков данных в одной операции
Для оптимизации кода рекомендуется явно уменьшить число операций по передаче данных между приложением Excel и кодом. Вместо перебора ячеек по одной при получении и установке значений, рекомендуется получать и устанавливать значения для целого диапазона ячеек в одной строке с помощью переменной, содержащей двумерный массив значений. В следующем примере кода показано сравнение этих двух методов.
Ниже приведен неоптимизированный пример кода, в котором осуществляется перебор ячеек по одной для получения и установки значений ячеек в диапазоне A1:C10000. Эти ячейки не содержат формул.
Ниже показан оптимизированный пример кода, в котором для получения и установки значений одновременно всех ячеек в диапазоне A1:C10000 используется массив. Эти ячейки не содержат формул.
Использовать. Значение2, а не . Значение или . Текст при чтении данных из диапазона Excel
- . Текст возвращает форматируемое значение ячейки. Это происходит медленно, может вернуть ### при увеличении масштаба пользователем и потерять точность.
- . Значение возвращает валюту VBA или переменную даты VBA, если диапазон был отформатирован как Дата или Валюта. Это происходит медленно, может потерять точность и вызвать ошибки при вызове функций листа.
- . Значение 2 работает быстро и не изменяет данные, извлекаемые из Excel.
Избегайте выбора и активации объектов
Процесс выбора и активации объектов сопряжен со значительно большими затратами вычислительных ресурсов, чем указание прямых ссылок на объекты. Путем прямой ссылки на объект , например Range или Shape , можно повысить производительность. В следующем примере кода показано сравнение этих двух методов.
В следующем примере кода показан неоптимированный код, который выделяет каждую фигуру на активном листе и изменяет текст на «Hello».
В следующем примере кода показан оптимизированный код, который ссылается на каждую фигуру напрямую и изменяет текст на «Hello».
Использование этих дополнительных оптимизаций производительности VBA
Ниже приведен список дополнительных параметров, влияющих на производительность, которые можно оптимизировать в коде VBA:
Возвращайте результаты посредством присвоения массива напрямую переменной Range.
Объявляйте переменные с явными типами. Это позволит избежать затрат ресурсов на определение типа данных при выполнении кода (многократное выполнение таких операций в цикле существенно скажется на производительности).
Для простых, часто используемых в коде функций можно самостоятельно реализовать функции в VBA вместо использования объекта WorksheetFunction. Дополнительные сведения см. в статье Использование более быстрых пользовательских функций VBA.
Воспользуйтесь методом Range.SpecialCells для уменьшения числа ячеек, с которыми взаимодействует код.
Учитывайте повышение производительности, если вы реализовали свою функциональность с помощью API C в пакете SDK для XLL. Дополнительные сведения см. в документации по пакету Excel 2010 XLL SDK.
Рассмотрите производительность и размер форматов файлов Excel
Начиная с версии Excel 2007, в приложении Excel поддерживается более широкий набор форматов файлов по сравнению с более ранними версиями. Если не учитывать варианты формата файлов макросов, шаблонов, надстройки, PDF и XPS, три основных формата — XLS, XLSB и XLSX.
Формат XLS
Формат XLS является аналогом такого же формата в более ранних версиях. При использовании этого формата размер книги ограничен 256 столбцами и 65 536 строками. При сохранении книги Excel 2007 или Excel 2010 в формате XLS выполняется проверка совместимости. Размер файла практически всегда совпадает с файлами предыдущих версий (иногда сохраняется некоторая дополнительная информация), а производительность может быть несколько ниже, чем в более ранних версиях. Функции многопоточной оптимизации порядка вычислений, реализованные в Excel, в формате XLS не сохраняются. В связи с этим, после сохранения книги в формате XLS, ее закрытия и повторного открытия скорость вычислений может снизиться.
Формат XLSB
Двоичный формат XLSB впервые представлен в Excel 2007. Он структурирован в виде сжатой папки, содержащей много двоичных файлов. Он гораздо компактнее, чем формат XLS, но объем сжатия зависит от содержимого книги. Например, для десяти разных книг степень сжатия может находиться в диапазоне от 2 до 8 (в среднем обычно степень сжатия находится в районе 4). Начиная с версии Excel 2007, производительность при открытии и сохранении в этом формате лишь незначительно ухудшается по сравнению с форматом XLS.
Формат XLSX
XLSX — это XML-формат, который был представлен и используется по умолчанию в приложении Excel 2007. Формат XLSX — это сжатая папка, содержащая много XML-файлов (если изменить расширение имени файла на .zip, можно открыть сжатую папку и проверить ее содержимое). В большинстве случаев размер XLSX-файла превышает размер файла в формате XLSB (в среднем около 1,5 раз), однако его размер по-прежнему будет значительно меньше размера аналогичного XLS-файла. Открытие и сохранение файлов в этом формате занимает несколько больше времени по сравнению с XLSB-файлами.
Открытие, закрытие и сохранение книг
Иногда открытие, закрытие и сохранение книг может занимать значительно больше времени, чем их вычисление. В некоторых случаях это связано с большим размером книги, однако могут быть и другие причины такого поведения.
Если одна или несколько книг открываются и закрываются слишком медленно, это может быть вызвано одной из следующих причин.
Временные файлы.
Временные файлы могут накапливаться в каталоге WindowsTemp (в Windows 95, Windows 98 и Windows ME) или в каталоге Documents and SettingsUser NameLocal SettingsTemp (в Windows 2000 и Windows XP). Excel создает эти файлы для книги и элементов управления, используемых в открытых книгах. Кроме того, временные файлы могут создаваться программами установки ПО. Если приложение Excel перестало отвечать, может потребоваться удаление этих файлов вручную.
Слишком много временных файлов может вызвать проблемы, поэтому иногда их следует удалять. Однако если у вас установлено программное обеспечение, требующее перезагрузки компьютера, но вы еще не сделали этого, перед удалением временных файлов следует перезапустить.
Простой способ открыть временный каталог — в меню «Пуск» Windows: нажмите кнопку Пуск, а затем нажмите кнопку Выполнить. В текстовом поле введите %temp%, а затем нажмите кнопку ОК.
Отслеживание изменений в общей книге
Отслеживание изменений в общей книге влечет за собой значительное увеличение размера файла книги.
Фрагментарный файл подкачки
Убедитесь, что файл подкачки Windows располагается на диске, на котором достаточно свободного места и регулярно выполняется дефрагментация.
Книга со структурой, защищенной паролем
Книга, структура которого защищена паролем (меню> Средства Защита>введите> необязательный пароль), открывается и закрывается гораздо медленнее, чем книга, защищенная без дополнительного пароля.
Проблемы с используемым диапазоном
Слишком большой размер используемого диапазона обычно влечет за собой снижение скорости открытия и увеличение размера файла, особенно в том случае, когда такой диапазон содержит скрытые строки или столбцы нестандартной высоты или ширины. Дополнительные сведения о проблемах с используемым диапазоном см. в разделе Минимизация используемого диапазона.
Большое количество элементов управления на листах
Большое количество элементов управления (флажки, гиперссылки и т. д.) на листах может замедлить открытие книги из-за количества используемых временных файлов. Это также может вызвать проблемы с открытием или сохранением книги в глобальной сети (или даже в локальной сети). При возникновении этой проблемы следует рассмотреть возможность перепроектирования книги.
Большое количество ссылок на другие книги
Перед открытием книги, содержащей ссылки, рекомендуется по возможности открыть книги, на которые она ссылается. Зачастую бывает гораздо эффективнее открыть книгу, чем считывать данные по ссылкам на закрытую книгу.
Параметры антивирусного сканера
Некоторые параметры антивирусной программы могут вызывать проблемы или снижение скорости при открытии, закрытии или сохранении книг, особенно на сервере. Если есть основания предполагать наличие такого рода проблем, попробуйте на время отключить антивирусную программу.
Медленное вычисление приводит к медленному открытию и сохранению
В некоторых случаях Excel пересчитывает книгу при ее открытии или сохранении. Если время вычисления книги является длительным и вызывает проблему, убедитесь, что для вычисления задано значение вручную, и рассмотрите возможность отключения параметра «Вычислить перед сохранением» (Tools>Options>Calculation).
Файлы панели инструментов (XLB)
Проверьте размер файла панели инструментов. Типичный файл панели инструментов составляет от 10 ДО 20 КБ. Вы можете найти файлы XLB, выполнив поиск *.xlb с помощью поиска Windows. У каждого пользователя есть уникальный XLB-файл. Добавление, изменение или настройка панелей инструментов увеличивает размер файла toolbar.xlb. При удалении файла удаляются все настройки панели инструментов (переименование ее «toolbar. OLD» безопаснее). При следующем открытии Excel создается новый XLB-файл.
Выполнение дополнительных оптимизаций производительности
Вы можете повысить производительность в следующих областях.
Сводные таблицы
Сводные таблицы эффективно подходят для обобщения крупных объемов данных.
Итоги в качестве окончательных результатов. Если требуется формировать итоги и промежуточные итоги в составе конечных результатов для книги, рекомендуется использовать сводные таблицы.
Итоги в качестве промежуточных результатов. С помощью сводных таблиц можно создавать эффективные сводные отчета. Тем не менее, не рекомендуется создавать формулы, в которых результаты сводной таблицы используются в качестве промежуточных итогов в цепочке вычислений, если не соблюдаются следующие условия:
Сводные таблицы надлежащим образом обновляются в процессе вычисления.
Сводные таблицы не изменялись, и данные по-прежнему видимы.
Если все же требуется использовать данные сводных таблиц в качестве промежуточных результатов, используйте функцию GETPIVOTDATA.
Условные форматы и проверка данных
Применение условного форматирования и проверки данных бывает крайне полезным, однако слишком активное использование этих функций может повлечь за собой существенное снижение скорости вычислений. Если ячейка отображается, каждая формула условного формата вычисляется при каждом вычислении и при обновлении отображения ячейки, содержащей условный формат. В объектной модели Excel представлено свойство Worksheet.EnableFormatConditionsCalculation, с помощью которого можно включать и отключать вычисление условных форматов.
Определенные имена
Определенные имена — это одна из самых полезных возможностей приложения Excel, однако их применение может увеличить время вычисления. Использование имен, ссылающихся на другие листы, существенно усложняет процесс вычисления. Кроме того, настоятельно не рекомендуется использовать вложенные имена, которые ссылаются на другие имена.
Поскольку имена вычисляются при каждом вычислении формулы, которая ссылается на них, не рекомендуется помещать в определенные имена функции и формулы, требующие большого объема вычислений. В таких случаях гораздо более эффективно будет поместить такие функции и формулы в произвольную резервную ячейку и задавать ссылки на эту ячейку непосредственно или по имени.
Формулы, которые используются только иногда
Многие книги содержат значительное количество формул и подстановок, которые связаны с получением входных данных в соответствующую форму для вычислений или используются в качестве защитных мер против изменения размера или формы данных. Если у вас есть блоки формул, которые используются только иногда, можно скопировать и вставить специальные значения, чтобы временно исключить формулы, или поместить их в отдельную, редко открываемую книгу. Так как ошибки на листе часто возникают из-за того, что формулы были преобразованы в значения, предпочтительнее использовать метод отдельной книги.
Использование достаточного объема памяти
32-разрядная версия Excel может использовать до 2 ГБ ОЗУ или до 4 ГБ ОЗУ для 32-разрядных версий Excel 2013 и 2016 с поддержкой больших адресов. Тем не менее, компьютер, на котором работает приложение Excel, также потребляет определенный объем ресурсов памяти. Соответственно, если на компьютере установлено ровно 2 ГБ ОЗУ, приложение Excel не сможет полностью использовать допустимый объем памяти в 2 ГБ, поскольку часть ресурсов будет зарезервирована для операционной системы и других выполняемых программ. Чтобы оптимизировать производительность Excel на 32-разрядном компьютере, рекомендуется иметь на компьютере не менее 3 ГБ ОЗУ.
64-разрядная версия Excel не имеет ограничения в 2 ГБ или до 4 ГБ. Дополнительные сведения см. в разделе «Большие наборы данных и 64-разрядная версия Excel» статьи Производительность Excel: улучшения производительности и ограничений.
Заключение
В этой статье рассматриваются способы оптимизации функциональных возможностей Excel, таких как ссылки, подстановки, формулы, функции и код VBA, чтобы избежать распространенных препятствий и повысить производительность.
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник