Автоматизация создания панельных диаграмм в Excel

Панельные диаграммы идеально подходят для раздельного отображения сразу нескольких рядов данных. Ниже показан линейный график, явно перегруженный линиями, а справа – его аналог в виде панельной диаграммы, на которой ряды данных располагаются отдельно.

Рис. 1. Линейный график и панельная диаграмма; чтобы увеличить изображение кликните на нем правой кнопкой мыши и выберите Открыть картинку в новой вкладке

Скачать заметку в формате Word или pdf, примеры в архиве (внутри файл Excel с поддержкой макросов; политика провайдера не позволяет напрямую загружать такие файлы)

Запись макроса

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

Давайте начнем с записи макроса, чтобы подсмотреть манипуляции с объектами. Определите максимальное значение в диапазоне В1:I14. Оно нам понадобится, чтобы установить шкалу ординат. МАКС(B2:I14)=6420. На вкладке Разработчик нажмите на кнопку Запись макроса и в открывшемся диалоговом окне нажмите Ok. Выделите диапазон A1:B14 на рабочем листе. На вкладке Вставка нажмите Рекомендуемые диаграммы и выберите вариант График. Удалите горизонтальные линии сетки. Выделите вертикальную ось, задайте максимальное значение 7000 и оформите ее, как показано на рис. 2. Измените размер диаграммы. Переместите диаграмму. Не важно, куда – нам лишь нужно получить соответствующий код. Оформите горизонтальную ось. На вкладке Разработчик нажмите Остановить запись. В результате мы получим код макроса, показанный ниже. Чтобы посмотреть его, перейдите на вкладку Разработчик и нажмите на кнопку Visual Basic:

Рис. 2. Запись макроса

При записи макроса Excel записывает строки кода для всех действий. Так, первая строка создана в ответ на выделение диапазона ячеек, вторая – на создание диаграммы и т.д. Запись макросов полезно использовать для изучения объектов модели Excel и синтаксиса выражений. В данном случае вы видите, что нам придется поработать с объектами и методами AddChart2, SetSourceData, ActiveChart и ChartObjects. Не беспокойтесь, если не понимаете сгенерированный код, мы будем использовать его лишь как образец. И повторно запустить этот макрос у вас не получится, так как Excel создаст новую диаграмму с названием отличным от «Диаграмма 22».

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

Создание графика

Ниже кода макроса введите Sub MakeSinglePane и нажмите Enter. VBA автоматически добавит скобки к названию подпрограммы и завершит ее инструкцией End Sub. Ключевые слова Sub и End Sub ограничивают начало и окончание вашей программы. Создадим переменную, в которой будем хранить диаграмму. Вместо использования объекта ActiveChart мы присвоим созданный график переменной и будем манипулировать с ней. Введите следующий код между ключевыми словами Sub и End Sub:

При помощи ключевого слова Dim мы создаем переменную типа график, а выражение Set позволяет присвоить ей конкретный тип графика. Константа xlLine гарантирует скрытие маркеров на графике. Параметр 227 задает стиль диаграммы. Если вы запустите этот макрос, то получите пустую диаграмму на рабочем листе.

Рис. 3. Пустая диаграмма

Нам же необходимо манипулировать переменной cht для добавления элементов на график.

График с данными

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

Если запустить этот код, мы получим график с данными:

Рис. 4. Диаграмма с исходными данными

Форматирование графика

Отформатируем ось ординат, ось абсцисс, удалим горизонтальные линии сетки:

Рис. 5. Отформатированы оси

Позиционирование графика

Изменим размер графика и переместим его в нужное место. Автоматически записанный макрос оперирует для этого объектом Shape с использованием свойств и методов для изменения масштаба объекта и перемещения относительно текущей позиции. Я не знаю, почему Excel делает именно так, но для манипуляций есть более простой способ. До этого мы манипулировали объектом Chart, у которого есть родительский объект ChartObject. И у этого родительского объекта присутствуют свойства вроде Top и Height, позволяющие устанавливать координаты элемента напрямую. В следующем фрагменте кода мы добавим еще один блок With и используем свойство Parent нашего графика, чтобы изменить размеры и положение нашего объекта:

Рис. 6. Маленькая диаграмма, как элемент панельной инфографики

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

Создание панели из восьми графиков

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

При создании первого макроса вручную VBA автоматически добавлял скобки после названия подпрограммы. Внутри этих скобок вы можете задавать аргументы, которые будут поступать на вход макроса. Аргументы внутри макроса работают как обычные переменные, за исключением того, что их значения не задаются в макросе, а поступают извне при вызове подпрограммы. В данном случае мы добавили аргумент типа Range, с помощью которого будем задавать исходный диапазон для графика, а также четыре аргумента типа Double, которые помогут нам позиционировать диаграмму. Вы можете вызвать подпрограмму MakeSinglePanel2 из другого макроса, передав ей на вход необходимые аргументы. Например:

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

 

Рис. 7. Панель из 8 графиков

Организация цикла

Возможно, вы заметили закономерности в переданных макросу MakeSinglePanel2 аргументах. Всегда, когда вы замечаете определенные шаблоны в коде, у вас должно возникать желание реализовать выполнение операции в цикле, чтобы добавить макросу гибкости. Давайте создадим новую подпрограмму MakeAllPanels2(), в которой создание и размещение наших диаграмм на панели будет выполняться в цикле. Это позволит в будущем легко менять размеры элементов и их расположение. В новом макросе для разнообразия разместим диаграммы сначала слева направо, а затем сверху вниз:

Вся основная работа в этом макросе выполняется внутри двух вложенных циклов For. В первом определяется высота панели, а во втором – ширина. Поскольку мы используем один диапазон A1:A14 для оси абсцисс, мы заранее сохранили его в переменной. Затем мы использовали выражение Union для объединения этого диапазона с нужной нам колонкой со значениями по оси ординат.

Верхнюю левую координату графиков мы отсчитываем от значений 10 и 460. Каждый раз при запуске итерации внешнего цикла мы добавляем к предыдущей координате по вертикали высоту элемента, чтобы новый график разместился точно под предыдущим. То же самое происходит с горизонтальным смещением во внутреннем цикле. Если вы захотите разместить диаграммы в формате 4*2, то можете просто объявить внешний цикл как For i = 1 to 2, а внутренний – как For j = 1 to 4.

Оформление панели, как единого целого

Наличие горизонтальной оси на всех графиках не является обязательным. Оставим подписи только на двух нижних графиках. Проблема с удалением некоторых подписей состоит в том, что размер диаграмм с удаленной осью автоматически увеличится, что нарушит наши пропорции. Чтобы это обойти, мы можем зафиксировать значение свойства PlotArea.InsideHeight для всех графиков. Если устанавливать свойство PlotArea.InsideHeight напрямую, все ваши графики будут масштабированы одинаково, но значение свойства ChartArea.Height не изменится, и в местах, где были оси, останется пустое пространство.

Напишем новый макрос MakeSinglePanel3. На этот раз это будет не подпрограмма, а функция. Функция отличается от подпрограммы тем, что может возвращать значение или объект в вызывающий блок кода. Наша функция будет возвращать созданный график, в котором свойство PlotArea.InsideHeight можно будет установить позже. Функция также содержит два новых аргумента: dInsideHeight и bHideAxis:

Аргумент bHideAxis отвечает за то, будет ли скрыта ось на графике. Если он равен True, основная ось будет скрыта. В противном случае мы имеем дело с диаграммой в нижнем ряду панели, и высота будет увеличиваться, пока область построения не сравняется по размерам с другими графиками. В заключительной строке созданный график возвращается в вызывающий код путем присваивания его имени функции.

Вызывающую подпрограмму также потребуется изменить. Нам придется определять, находится ли график на нижнем ряду панели, чтобы правильно устанавливать значение аргумента bHideAxis.

Эта подпрограмма содержит две новые переменные для хранения высоты области построения и объекта с графиком, возвращаемого функцией. Также мы объявили две константы с высотой и шириной панели. Вместо того чтобы вставлять значения непосредственно в циклы For Next, вы можете объявить константы в самом начале процедуры и использовать их при необходимости. Таким образом, если вы захотите изменить ориентацию панели, вам необходимо будет обновить значения констант и все.

Здесь мы вызываем не подпрограмму для создания графиков, а функцию, возвращающую объект диаграммы, который мы присваиваем переменной cht. При таком вызове функции все аргументы должны быть заключены в круглые скобки. После вызова функции мы сохраняем значение свойства PlotArea.InsideHeight первого созданного графика, чтобы при достижении нижнего ряда функция знала, какой высоты создавать диаграммы. Итоговая панельная диаграмма:

Рис. 8. Инфографика на основе панельной диаграммы

[1] Это немного переработанный фрагмент книги: Дик Куслейка. Визуализация данных при помощи дашбордов и отчетов в Excel.

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

Ваш адрес email не будет опубликован.