
2 семестр / vba_2002
.pdf
If UserRow < 2 Or IsEmpty(Cells(UserRow, 1)) Then
MsgEox "Переместите курсор к ячейке с данными диапазона.
Exit Sub
End If
CreateChart (UserRowJ
UserForml.Show
End Sub
Рис. 18.13. Диаграмма в этом пользовательском диалоговом окне создается "на лету" наосноведанныхактивнойстроки
Так как диаграмма основана на данных строки активной ячейки, процедура отображает предупреждение, если курсор оказывается в неправильной строке. Если активная строка выбрана правильно, то процедура ShowChart вызывает процедуру C r e a t e C h a r t для создания необходимой диаграммы. После этого отображается пользовательское диалоговое окно.
Процедура C r e a t e C h a r t , представленная в листинге 18.3, принимает один аргумент, который отображает строку активной ячейки. Эта процедура получена на основе макроса, который записан при создании диаграммы и подкорректирован для приведения к более универсальному виду.
Листинг 18.3. Автоматическая генерация диаграммы
Sub CreateChart(r)
Dim TempChart As Chart
Dim CatTitles As Range
Dim SrcRange As Range, SourceData As Range
Application.Screenupdating = False
Set CatTitles = ActiveSheet.Range Г'А2:F2")
ЧастьV.Совершенныеметодыпрограммирования |
47В |

Set SrcRange = ActiveSheet.Range(Cells{r, 1), Cells(r, 6))
Set SourceData = UnionfCatTitles, SrcRange)
1Добавление диаграммы
Set TempChart = Charts.Add
'Настройка диаграммы
With TempChart
.ChartType = xlColumnClustered
.SetSourceData Source:=SourceData, PlotBy:=xlRows
.HasLegend = False
-ApplyDataLabels Type:=xlDataLabelsShowValue, LegendKey:=False
.ChartTitle.Font.Size = 14 -ChartTitle.Font.Bold = True
.Axes(xlValue) .MaximumScale = 0.6
.Axes(xlCategory).TickLabels.Font.Size = 10 -Axes(xlCategory).TickLabels.Orientation = xlHorizontal
.Location Where:=xlLocationAsObject, Name:="Лист1" End With
'Задание размера диаграммы
With ActiveSheet.ChartObjects(1)
.Width =3 00
•Height = 150
End With
End Sub
После завершения работы процедуры CreateChart рабочий лист будет содержать объект ChartObj ect с диаграммой данных на основе строки активной ячейки. Но объект ChartObject остается невидимым так как свойство ScreenUpdating объекта Application отключено.
Последний оператор в процедуре ShowChart загружает диалоговое окно UserForm. Ниже приведен листинг процедуры UserForm_Initialize. Эта процедура сохраняет диаграмму в виде файла GIF, удаляет объект ChartObj ect и загружает файл GIF в элемент управления Image.
Private Sub UserForm_Initialize()
Dim CurrentChart As Chart Dim Fname As String
Set CurrentChart = ActiveSheet.ChartObjects(1).Chart
'Сохранение диаграммы в виде файла GIF
Fname = ThisWorkbook.Path & Application.PathSeparator & "temp.gif"
CurrentChart.Export FileName:=Fname, FilterName:="GIF"
ActiveSheet.ChartObjGets(1).Delete
1Отображение диаграммы Imagel.Picture = LoadPicture(Fname)
Application.ScreenUpdating = True
Kill ThisWorkbook.Path & Application.PathSeparator & "temp.gif"
End Sub
Данная рабочая книга доступна на Web-узле издательства.
480 |
Глава 18. Управление диаграммами |

События диаграмм
Программа Excel поддерживает несколько событий, связанных с диаграммами. Например, когда диаграмма активизируется, то генерируется событие A c t i v a t e . Событие C a l c u l a t e возникает после того, как диаграмма получает новые или изменившиеся данные, Можно создать код VBA, который будет выполняться при возникновении определенного события.
Обратитесь к главе 19 для получения дополнительной информации о событиях.
В табл. 18.1 отображен список событий диаграммы, которые поддерживаются в Excel 97 и более поздних версиях программы.
i Таблица 18.1. События, которые распознаютсяобъектами диаграммы
Событие |
|
Действие, которое приводит к возникновению события |
Activate |
|
Активизирован лист диаграммы или встроенная диаграмма |
B e f o r e D o u b i e c i i c k |
На встроенной диаграмме выполнен двойной щелчок. Это событие происходит |
|
|
|
перед реакцией на двойной щелчок, принятой по умолчанию |
B e f o r e R i g h t c i i c k |
На встроенной диаграмме выполнен щелчок правой кнопкой мыши. Это собы- |
|
|
|
тие происходит перед реакцией на щелчок правой кнопкой мыши, принятой по |
|
|
умолчанию |
calculate |
На диаграмме отображаются новые или обновленные данные |
|
D e a c t i v a t e |
|
Диаграмма деактивиэируется |
DragOver |
|
Диапазон ячеек перетаскивается над диаграммой |
D r a g p i o t |
|
Диапазон ячеек перетаскивается и отпускается на диаграмму |
MouseDown |
|
Кнопка мыши нажата, а указатель находится над диаграммой |
MouseMove |
|
Расположение указателя мыши изменяется, пока он находится над диаграммой |
Mouseup |
|
Кнопка мыши отпущена, пока указатель находится над диаграммой |
R e s i z e |
|
Изменение размера диаграммы |
S e l e c t |
|
Выделение одного из элементов диаграммы |
SeriesChange |
|
Изменяется значение точки данных на диаграмме |
Пример использования событий объекта Chart
Для того чтобы создать процедуру обработки события, которое происходит на листе диаграммы, код VBA должен быть сохранен в модуле кода объекта C h a r t . Чтобы активизировать этот модуль кода, дважды щелкните на элементе C h a r t в окне проектов. После этого в модуле кода выберите C h a r t из выпадающего списка Object в левой части экрана и укажите событие в выпадающем списке Procedure, находящемся в правой части экрана (рис. 18.14).
Так как для встроенных диаграмм модуль кода не представлен, процедура, описанная в этом разделе, применяется только по отношению к листам диаграмм. Конечно, события можно обрабатывать и для встроенных диаграмм, но для этого необходимо выполнить кропотливую работу, связанную с созданием модуля класса. Такая процедура рассматривается далее в разделе "Поддержка событий встроенных диаграмм".
ЧастьV.Совершенныеметодыпрограммирования |
481 |

/'ис. V3,/4. Выборсобытия вмодуле кода для объекта диаграммы
Пример, представленный ниже, отображает сообщение в следующих случаях: когда пользователь активизирует лист диаграммы, деактквширует диет диаграммы и выделяет один из элементов диаграммы. Мною создана рабочая кннга с листом диаграммы, а также три процедуры обработки событий.
•Chart_Activate — выполняется, когда лист диаграммы активизируется.
•Chart_Deactivate — выполняется, когда лист диаграммы деактивизируется.
•Chart_Select — выполняется, когда выделен элемент листа диаграммы. Ниже приведен код процедуры Chart_Activate.
Private Sub Chart__Activate() Dim msg As String
msg = "Привет, " & Application.UserName & vbCrLf & vbCrLf msg = msg &. "Вы просматриваете отчет по объемам продаж " msg = msg & "за 6 месяцев для 3 товаров." & vbCrLf & vbCrLf
msg = msg & "Щелкните на элементе диаграммы для его идентификации." MsgBox msg, vblnformation, ActiveWorkbooK.Name
End Sub
Эта процедура отображает сообщение при активизации диаграммы (рис. 18.15). Процедура Chart_Deactivate. которая представлена ниже, также отображает окно со-
общения, однако лишь в том случае, когда диаграмма деактивизируется. Private Sub Chart_Activate{)
Dim msg As String msg = "Привет! "
msg = msg & "Вы просматриваете отчет по объемам продаж " msg = msg & "за 6 месяцев для 3 товаров." & vbCrLf & vbCrLf
msg = msg & "Щелкните на элементе диаграьшы для-его идентификации." MsgBox msg, vblnformation, ActiveWorkbook.Name
End Sub
Процедура Chart_Select, приведенная ниже, выполняется каждый раз, когда пользователь выделяет один из элементов диаграммы.
Private Sub Chart_Select(ByVal ElementID As Long, _ ByVal Argl As Long, ByVal Arg2 As Long)
Dim Id As String Select Case ElementID
Case xlChartArea: Id = "Область диаграммы" Case xlChartTitle: Id = "Заголовок диаграммы"
482 |
Глава 18. Управлениедиаграммами |

Case xlPlotArea: Id = "Область построения" Case xlLegend: Id = "Легенда"
Case xlFloor: Id = "Основание" Case xlWalls.- Id = "Стенки" Case xlCorners: Id = "Углы"
Case xlDataTable: Id = "Таблица данных" Case xlSeries: Id = "Последовательности" Case xlDataLabel: Id = "Подпись данных" Case xlTrendline: Id = "Тенденция"
Case xlErrorBars: Id = "Погрешность"
Case xlXErrorBars: Id = "Горизонтальная погрешность" Case xlYErrorBars: Id = "Вертикальная погрешность" Case xlLegendEntry: Id = "Запись легенды"
Case xlLegendKey: Id = "Ключ легенды" Case xlAxis: Id = "Оси"
Case xlMajorGridlines: Id = "Базовые линии сетки"
Case xlMinorGridlines: Id = "Вспомогательные линии сетки" Case xlAxisTitle: Id = "Названия осей"
Case xlShape: Id = "Фигура" Case xlNothing: Id = "Ничего"
Case Else: Id = "Нечто неизвестное" End Select
MsgBox "Выделено: " & Id End Sub
Рис. 18.15. Активизация диагралшы приводит к отображению окна сообщения с помощью процедуры Chart_Activate
Эта процедура отображает сообщение, в котором находится описание выделенного элемента. При возникновении события S e l e c t аргумент Elementl D содержит целое число, которое соответствует выделенному элементу. Аргументы Arg l и Arg2 предоставляют дополнительную информацию о выделенном элементе (информацию о значениях этих аргументов можно получить в интерактивном справочном руководстве). Структура S e l e c t Case преобразует встроенные константы в описательные строки.
ЧастьV.Совершенныеметодыпрограммирования |
483 |
Поддержка событий для встроенных диаграмм
Как отмечалось в предыдущем разделе, события объекта Chart автоматически реализованы для листов диаграмм, но отключены для диаграмм, встроенных в рабочий лист. Для того чтобы использовать события, связанные со встроенной диаграммой, необходимо выполнить следующие инструкции.
Создайте модуль класса
В VBE выберите проект в окне Project si выполните команду Insert^Class Module. Это приведет к добавлению пустого модуля класса в проект. Если возникнет желание, можно назначить модулю класса более описательное имя в окне Properties.
Объявите глобальный объект Chart
Следующим шагом является создание глобальной переменной, которая используется в качестве имени класса. Переменная должна иметь тип Chart и объявляться в модуле класса с ключевым словом WithEvents. Если опустить ключевое слово withEvents, то объект не будет реагировать на события. Ниже приведен пример соответствующего объявления:
Public WithEvents myChartClass As Chart
Свяжите объявленный объект с диаграммой
Перед тем, как будут запущены процедуры обработки событий, необходимо связать объявленный объект в модуле класса со встроенной диаграммой. Для этого следует объявить объект типа Classl (в данном случае используется имя модуля класса). Это должна быть переменная уровня модуля, которая объявлена в обычном модуле VBA (а не в модуле класса). Например:
Dim MyChart As New MyChartClass
Затем введите код, который фактически создаст экземпляр объекта. Воспользуйтесь представленным нижеоператором:
Set myChart.myChartClass = ActiveSheet-ChartObjects(1).Chart
После выполнения предыдущего оператора объект myChartClass в модуле класса будет указывать на первую встроенную диаграмму активного листа. Следовательно, процедуры обработки событий в модуле класса будут выполняться при возникновении соответствующих событий.
Создайте процедуры обработки событий для класса диаграммы
В этом разделе речь пойдет о том, как создавать процедуры обработки событий в модуле класса. Помните, что модуль класса должен содержать следующее объявление:
Public WithEvents myChartClass As Chart
После объявления с помощью ключевого слова WithEvents новый объект отображается в выпадающем списке Object в модуле класса. При выборе нового объекта в поле Object действительные события этого объекта будут перечислены в выпадающем списке Procedure в правой части окна (рис. 18.16).
Приведенный далее пример является простой процедурой обработки события, которая выполняется при активизации встроенной диаграммы. Эта процедура создает окно сообщения, которое содержит имя "родителя" объекта Chart (в его роли выступает объект ChartObject).
484 |
Глава 18. Управление диаграммами |

Puc.18.16.СписокProcedureотображаетдействительныесобытиядляновогообъектаCharC
На Web-узле издательства расположен файл рабочей книги, которая демонстрирует концепции, описанные в этом разделе.
Пример использования событий объекта Chart во встроенной диаграмме
Пример, приводимый в этом разделе, призван закрепить материал, приведенный выше. На рис. 18.17 отображена встроенная диаграмма, которая работает подобно карте изображения. На ее областях можно щелкать для получения разных результатов. Щелчок на одном из столбцов диаграммы приводит к активизации того рабочего листа, на котором содержатся подробные данные об этой области диаграммы.
Рис. IS.17. Данная диаграмма служит в качестве карты изображения,наобластяхкоторойможнощелкатьдляотображениядетальныхсведений
ЧастьV.Совершенныеметодыпрограммирования |
485 |
Рабочая книга состоит из четырех листов. Лист Общие содержит встроенную диаграмму. Другие листы называются Север, Юг и Запад. Формулы в диапазоне Bl i B4 суммируют данные в соответствующих листах, а итоговые данные отображаются на диаграмме. Щелчок на столбце диаграммы приводит к возникновению события, а процедура обработки этого события активизирует соответствующий лист, чтобы пользователь мог просмотреть подробные сведения выбранного диапазона.
В рабочей книге расположен модуль класса, который называется EmbChartClass, a также обычный модуль VBA — Modulel. В демонстрационных целях рабочий лист Общие содержит две кнопки: одна выполняет процедуру EnableChartEvents, а вторая— процедуру DiaableChartEvents (обе расположены в модуле Modulel). Кроме того, на каждом рабочем листе находится кнопка, с помощью которой запускается процедура ReturntoMain, возвращающая пользователя на лист Общие.
Полный листинг модуля Modulel приведен ниже. Dim SummaryChart As New EmbchartCILass
Sub |
EnableChartEvents{) |
|
1 |
Вызывается кнопкой на рабочем листе |
|
|
Range("Al").Select |
|
|
Set SummaryChart.myChartClass |
= _ |
|
Worksheets(1).ChartObjectsU).Chart |
|
End Sub |
|
|
Sub |
DisableChartEvents О |
|
1 |
Вызывается кнопкой на рабочем листе |
|
|
Set SurranaryChart.myChartClass |
= Nothing |
|
Range("Al").Select |
|
End Sub |
|
|
Sub ReturnToMain() |
|
|
1 |
Вызывается кнопкой на рабочем листе |
|
|
Sheets("Общие").Activate |
|
End Sub |
|
Первая инструкция объявляет новый объект SummaryChart типа EmbChartClass (это имя модуля класса). Когда пользователь щелкает на кнопке Подключение событий, встроенная диаграмма присваивается объекту SummaryChart, который, в свою очередь, поддерживает обработку событий диаграммы. В листинге 18.4 представлен код модуля класса EmbChartClass.
Щелчок на диаграмме приводит к генерации события MouseDown, которое вызывает выполнение процедуры myChartClass_JtfouseDown. Эта процедура использует метод GetChartElement для получения информации об элементе, на котором щелкнул пользователь. Метод GetChartElement возвращает информацию об элементе, которому принадлежит точка с координатами X и Y указателя во время щелчка (информация о координатах отображается в виде аргументов процедуры myChartclass_MouseDown).
Листинг18.4.Реакциянащелчокнастолбце
Public WithEventa myChartClass As Chart
Private Sub myChartClass_MouseDown{ByVal Button As Long, _
ByVal Shift As Long, ByVal X As Long, ByVal У As Long)
Dim IDnum As Long
486 |
Глава 18. Управление диаграммами |

Dim a As Long, b As Long
'Следующий оператор возвращает значения
1 |
IDNum, а и b |
|
myChartClass.GetChartElement X, Y, IDnum, a, b |
1Щелчок на последовательности? If IDnum s xlSeriea Then
Select Case b Case 1
Sheets("Север").Activate
Case 2
Sheets("Юг").Activate
Case 3
Sheets ("Запад") -Activate
End Select
End If
Range("Al").Select
End Sub
Эта рабочая книга доступна на Web-узле издательства.
Хитрости создания диаграмм
В завершение предлагаем информацию, касающуюся тонкостей создания диаграмм. Некоторые из предложенных методов могут эффективно применяться в конечных приложениях. Их изучение предоставит дополнительную информацию об объектной модели диаграмм.
Печать встроенных диаграмм на всю страницу
При выделений встроенной диаграммы можно распечатать диаграмму с помощью команды ФайлоПечать. Встроенная диаграмма будет распечатана на всю страницу (как будто она находится на листе диаграммы), но при этом будет оставаться встроенной. Следующий макрос печатает все встроенные диаграммы на активном листе, причем каждая диаграмма печатается на всю страницу.
Sub PrintEinbeddedCharts ()
For Each chtObj In AcCiveSheet.ChartObjects chtObj.Chart.Print
Next chtObj End Sub
Создание "мертвой" диаграммы
Как правило, диаграмма Excel использует данные, которые хранятся в диапазоне. Изменение данных в диапазоне приводит к автоматическому обновлению содержимого диаграммы. В некоторых случаях возникает необходимость "отсоединить" диаграмму от ее диапазона данных и создать "мертвую" диаграмму (чтобы она никогда не изменялась). Например, если данные диаграммы создаются рядом сценариев "что-если", то может возникнуть необходимость сохранения базовой диаграммы, которая сравнивается с результатами выполнения других сценариев.
ЧастьV.Совершенныеметодыпрограммирования |
487 |

Для создания такой диаграммы существует два метода.
•Вставить в виде изображения. Активизируйте диаграмму и выберите Правка^Копировать. После этого нажмите клавишу <Shift> и выполните команду Правка^Вставить рисунок (команда Вставить рисунок доступна только в том случае, если при открытии меню Правка удерживать нажатой клавишу <Shift>). В результате будет получено изображение скопированной диаграммы.
•Преобразовать ссылки на диапазоны в массивы значений. Щелкните на последовательности в диаграмме, а затем — в строке формул. Нажмите клавишу <F9>, чтобы преобразовать диапазон в массив. Повторите эту операцию для остальных последовательностей диаграммы.
Файл x l 8 g a l r y . x l s отображает последнюю методику. Данный файл является специальной рабочей книгой, которая используется Excel для хранения пользовательских форматов диаграмм. Если открыть эту рабочую книгу, то можно найти 20 листов диаграмм. Каждый лист диаграммы содержит "макеты" диаграмм, в которых вместо диапазонов в качестве источников используются массивы.
Еще одним методом создания "мертвых" диаграмм является написание кода VBA, который присваивает свойствам Values или xvalues объекта Series массивы.
Управление последовательностями методом скрытия данных
На рис. 18.18 показана диаграмма, которая отображает данные для каждого из 365 дней в году. Итак, вам необходимо отобразить лишь данные для февраля. Вы можете, конечно, переопределить диапазон данных диаграммы Существует и другой путь— воспользоваться командой Excel Автофильтр.
fuc. /S./A Воспользуйтесь средством Автофильтр для отображения толькоподмножестваданных
488 |
Глава 18. Управлениедиаграммами |