2006 г.
Биллиг Владимир Арнольдович
Интернет-Университет Информационных Технологий, INTUIT.ru
Назад Оглавление Вперёд
События объекта Excel.Application
Объект Excel.Application
может обрабатывать 21 событие, возникающие при работе с теми или иными объектами приложения Excel. Почти половина из этих событий возникает в процессе работы с объектом Workbook
, другая половина событий связана с такими объектами, как страница документа (объект Sheet
) и окно (объект Window
). Практически все события, за исключением одного события NewWorkBook
, могут быть обработаны на двух уровнях - объектом Application
и объектом Workbook
. Но прежде чем поговорить, о том, какие события может обрабатывать объект Application
, в каких случаях следует проводить обработку события на уровне объекта Application
, а в каких - на уровне объекта Workbook
, давайте разберемся, как заставить объект Excel.Application
вообще реагировать на события.
Создание объекта Application, реагирующего на события
Для всех приложений Office 2000 соответствующие объекты Application
хотя и могут реагировать на события, но появляются как объекты без событий. И нужно приложить некоторые усилия, чтобы создать новый объект Application With Events
, который может реагировать на события. Причина возникающих сложностей кроется в логике построения программного проекта, изначально принятой в Office. Дело в том, что обработчики событий, возникающих при работе с теми или иными объектами, следует размещать в специальных модулях - обработчиках событий. Для большинства стандартных объектов Office эти модули создаются автоматически в момент создания основного объекта. Так, например, при создании документа в его проекте автоматически создается модуль, обрабатывающий события этого документа, - для Excel это модуль с именем "ЭтаКнига" (ThisWorkbook). Только в этом модуле и можно создать обработчики событий объекта Workbook
и всех объектов, реагирующих на события, например, элементов управления, встраиваемых непосредственно в документ.
Объект Application
, единый для всех рабочих книг, по понятным причинам не вписывается в эту общую схему и для него такой модуль автоматически не создается, потому, естественно, эту работу приходится выполнять программисту.
Для того чтобы заставить реагировать на события объект Excel.Application
, необходимо выполнить четыре шага:
- Создать модуль, задающий собственный класс для объекта
Excel.Application
, в котором можно будет размещать обработчики возникающих событий. Устроен этот класс очень просто и состоит в момент создания из одной строчки, поскольку класс не имеет методов и имеет ровно одно свойство, задающее объект Application
с событиями. Конечно, позже этот класс будет пополняться обработчиками событий. Вот как выглядит на этапе создания описание этого класса, которому я в своем примере дал имя AppWithEvents
. Option Explicit
'Класс, описывающий объект Application With Events.
'Класс не имеет методов, задается одним свойством.
Public WithEvents ExApp As Application
- Следующее, что необходимо сделать - это определить объект вновь созданного класса
AppWithEvents
. И эта задача решается в одну строчку. Объявление объекта я поместил в раздел объявлений созданного ранее стандартного модуля. Заметьте, необходимо не только объявить объект, но и создать его, используя спецификатор New
. Public AppWithEv As New AppWithEvents
- Третьим шагом является связывание двух объектов
Application
, стандартного и созданного объекта, умеющего реагировать на события. По-видимому, лучшим местом, где следует осуществить связывание, является обработчик события Open того документа, в котором описан класс AppWithEvents
. Тогда после открытия этого документа и вплоть до его закрытия Excel будет реагировать на события, связанные с объектом Excel.Application
. Вот как осуществляется связывание: Private Sub Workbook_Open()
'Связывание двух объектов Application -
'стандартного и реагирующего на события.
Set AppWithEv.ExApp = Excel.Application
End Sub
- На этом шаге созданный класс
AppWithEvents
можно расширить, добавив в него обработчики событий объекта Application
. Я приведу пока текст только одного обработчика, который обрабатывает событие NewWorkBook
, возникающее при создании новой книги. Private Sub ExApp_NewWorkbook(ByVal Wb As Workbook)
'Обработка события - создание новой книги.
Static Num As Integer
Num = Num + 1
MsgBox ("Число вновь созданных книг - " & Num _
& vbCrLf & "Новая книга - " & Wb.Name _
& " открыта в " & Time)
End Sub
Вот как выглядит сообщение, появляющееся при открытии новой книги:
Рис. 3.2. Сообщение об открытии новой книги
События, связанные с рабочей книгой
В нижеследующей таблице 1 дана сводка всех событий, которые возникают при работе с рабочими книгами - объектами Workbook
, и которые могут быть обработаны объектом Application
.
Таблица 3.3. События, возникающие при работе с объектом WorkbookСобытие | Когда возникает | Параметры события |
---|
NewWorkbook(Wb As Workbook) | При создании новой книги. Единственное событие этой группы, которое может обработать только объект Application . | Обработчику события передается объект Wb , представляющий вновь созданную книгу. |
WorkbookActivate(Wb As Workbook) | Книга становится активной. | Вновь активированная книга передается обработчику события в качестве параметра. |
WorkbookAddinInstall(Wb As Workbook) | При установке рабочей книги в качестве AddIn. | Рабочая книга, представляющая AddIn. |
WorkbookAddinUninstall(Wb As Workbook) | Отменяется установка рабочей книги в качестве AddIn. Закрытие книги при этом не происходит. | Рабочая книга, представляющая AddIn. |
WorkbookBeforeClose(Wb As Workbook, Cancel As Boolean) | При попытке закрыть рабочую книгу, но до того, как она будет закрыта. | Параметр Wb задает закрываемую книгу. Параметр Cancel позволяет отменить закрытие, если в обработчике события его значение будет установлено как True . |
WorkbookBeforePrint(Wb As Workbook, Cancel As Boolean) | При попытке распечатать содержимое рабочей книги, но до того, как произойдет печать. | Параметр Wb задает печатаемую книгу. Параметр Cancel позволяет отменить печать, если в обработчике события его значение будет установлено как True . |
WorkbookBeforeSave(Wb As Workbook, SaveAsUI As Boolean, Cancel As Boolean) | При попытке сохранить содержимое рабочей книги, но до того, как произойдет сохранение. | Параметр Wb задает сохраняемую книгу. Параметр Cancel позволяет отменить сохранение, если в обработчике события его значение будет установлено как True . Параметр SaveAsUI показывает, как идет сохранение, его значение равно true , если при сохранении открывается диалоговое окно "Сохранить как ". |
WorkbookDeactivate(Wb As Workbook) | Книга перестает быть активной, поскольку активной становится другая книга. | Деактивированная книга передается обработчику события в качестве параметра. |
WorkbookNewSheet(Wb As Workbook, Sh As Object) | При добавлении новой страницы в рабочую книгу. | Объект Wb задает книгу, а Sh - страницу, добавленную в эту книгу. |
WorkbookOpen(Wb As Workbook) | При открытии уже существующей рабочей книги. | Обработчику события передается объект Wb , представляющий вновь открытую книгу. |
Практически все события, происходящие с объектом Workbook
, могут быть обработаны на двух уровнях - объектом Application
и самим объектом Workbook
. Разница лишь состоит в том, что если у объекта Application
есть, например, событие WorkbookOpen
, то у объекта Workbook
есть событие Open
. При возникновении данного события операционная система посылает соответствующее сообщение двум объектам - Application
и Workbook
. Обработчику сообщения WorkbookOpen
передается параметр Wb
, задающий открываемую книгу. Понятно, что при посылке аналогичного сообщения объекту Workbook
передавать этот параметр не имеет смысла, поскольку он и так знает сам себя, так что обработчик события Open
объекта Workbook
параметров не имеет.
Возникает естественный вопрос, в каких случаях следует вести обработку события, происходящего с объектом Workbook
, на уровне объекта Application
. Ответ понятен - в тех случаях, когда обработчик события выполняет действия, общие для всех рабочих книг. В тех же случаях, когда предполагается специфическая обработка события, характерная только для данной конкретной книги, обработчик события связывается с объектом Workbook
. Что происходит, если обработка одного и того же события предусмотрена на двух уровнях? В этом случае вначале выполнится обработчик события, связанный с объектом Workbook
, - он выполнит специфическую для данной книги обработку, а потом начнет работать обработчик этого же события, связанный с объектом Application
, выполняющий ту часть работы, которая является общей для всех рабочих книг.
Приведу пример, в котором предусмотрена общая для всех рабочих книг обработка события BeforeSave
:
Private Sub ExApp_WorkbookBeforeSave(ByVal Wb As Workbook, _
ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim YesNo As Variant
YesNo = MsgBox("Вы действительно хотите сохранить этот документ?", vbYesNo)
If YesNo = vbNo Then Cancel = True
End Sub
Предупреждающее сообщение будет появляться для всех рабочих книг. Рассмотрим теперь пример, когда обработка события BeforePrint
предусмотрена на двух уровнях:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
'Обработка события - печать содержимого книги.
MsgBox ("Эту книгу - " & ThisWorkbook.Name _
& " печатать запрещено!")
Cancel = True
End Sub
Private Sub ExApp_WorkbookBeforePrint(ByVal Wb As Workbook, Cancel As Boolean)
'Обработка события - печать содержимого книги.
If Wb.ActiveSheet.Name = "Лист1" Then
MsgBox ("Эту страницу книги - " & Wb.Name _
& " печатать запрещено!")
Cancel = True
End If
End Sub
Специальный обработчик события объекта Workbook
книги BookOne запрещает печать только этой книги, а общий для всех книг обработчик того же события, но находящийся в объекте Application
, запрещает печать только первого листа, но для всех рабочих книг. Вот как выглядит сообщение, выданное для книги BookOne общим обработчиком при попытке распечатать содержимое первого листа книги:
увеличить изображение: увеличить изображение,
Рис. 3.3. Сообщение, выданное обработчиком события WorkbookBeforePrint
События, связанные с объектом Sheet
Ряд событий, которые возникают в процессе работы со страницами той или иной рабочей книги, также могут быть обработаны на уровне объекта Application
. Естественно, что эти события могут быть обработаны и на более низких уровнях - как на уровне объекта Workbook
, так и на следующем уровне объектами, задающими саму страницу - Worksheet
и Chart
. Понятно, что на самом верхнем уровне задается обработка, общая для всех страниц всех книг, на следующем уровне обработка, общая для страниц конкретной книги, и на нижнем уровне - обработка, специфическая для данной страницы. В таблице 3.4 дана сводка событий, связанных с объектом Sheet
, обрабатываемых на уровне объекта Application
.
Таблица 3.4. События, возникающие при работе с объектом Sheet Событие | Когда возникает | Параметры события |
---|
SheetActivate(Sh As Object) | Страница становится активной. | Вновь активированная страница передается обработчику события в качестве параметра. |
SheetBeforeDoubleClick(Sh As Object, Target As Range, Cancel As Boolean) | При двойном щелчке левой клавиши мыши на рабочей странице, но до того, как выполнится макрос, задающий реакцию на щелчок. Событие не возникает на Chart-страницах. | Первый параметр передает обработчику события объект Sh , задающий рабочую страницу, на которой был произведен двойной щелчок. Второй параметр Target возвращает ячейку (объект Range ), ближайшую к указателю мыши в тот момент, когда был произведен щелчок. Если в обработчике события изменить значение параметра Cancel на True , то отменится выполнение макроса, задающего реакцию на двойной щелчок. |
SheetBeforeRightClick(Sh As Object, Target As Range, Cancel As Boolean) | Аналогично двойному щелчку, но при нажатии правой клавиши мыши. | Параметры сохраняют смысл, описанный для обработчика событий двойного щелчка. |
SheetCalculate(Sh As Object) | При перевычислениях рабочей страницы или при любых изменениях данных, отображаемых на диаграмме страницы диаграмм. | В зависимости от того, на странице какого типа произошло событие, параметр Sh представляет либо объект Workbook либо объект Chart . |
SheetChange(Sh As Object, Target As Range) | При изменениях в ячейках рабочей книги, инициированные пользователем или внешней ссылкой. Не возникает для Chart-страниц. | Параметр Sh задает объект WorkSheet - страницу, в ячейках которой произошли изменения. Параметр Target задает область изменения - объект Range . |
SheetDeactivate(Sh As Object) | Страница перестает быть активной, поскольку активной становится другая страница. | Деактивированная страница передается обработчику события в качестве параметра. |
SheetFollowHyperlink(Sh As Object, Target As Hyperlink) | При щелчке по гиперссылке на рабочей странице. Не возникает для Chart-страниц. | В качестве параметров обработчику события передаются два объекта, представляющие рабочую страницу и гиперссылку, задающую переход. |
SheetSelectionChange(Sh As Object, Target As Range) | При изменении области выделения рабочей страницы. Не возникает для Chart-страниц. | Параметр Sh задает объект WorkSheet -страницу, содержащую новую область выделения. Параметр Target задает новую область выделения - объект Range . |
Назад Оглавление Вперёд