
2 Курс Информатика VBA(ЗО) / Книги / В.Д.Хорев - Самоучитель программирования на VBA в Microsoft Office
.pdf
Выбор наименования из списка 51
Выбор наименования из списка
Итак, познакомимся с еще одним прайс-листом ООО “Универсал” — “PC-комплектующие” (рис. 2.1). Комплектующие персональных компьютеров здесь разбиты на разделы точно таким же образом, как это было сделано в прайс-листе “Расходные материалы” (см. предыдущую главу). Точно так же столбец A здесь содержит наименования товаров, а столбец B — соответствующие этим наименованиям цены. Это клиентский прайс-лист, который мог быть сгенерирован из внутрифирменного прайса таким же точно образом, как это было сделано в предыдущей главе.
Рис. 2.1. Прайс-лист “PC-комплектующие“
Таким образом, исходная ситуация ничем не отличается от прайс-листа “Расходные материалы”. Но автоматизация прайса примет теперь другое направление. Вначале, для того чтобы создать основу для автоматизации на уровне макросов VBA, потребуется выполнить несколько подготовительных операций.
Именованные диапазоны
В предыдущей главе ячейкам рабочего листа уже присваивались имена, но сейчас необходимо присвоить имя целому диапазону ячеек. Зачем в этом случае нужен именованный диапазон? Смысл имени заключается не только в том, что на него легче ссылаться, а назначение названного им диапазона становится понятным без дополнительных объяснений. Дело еще и в том, что при работе с диапазоном ячеек всегда может потребоваться удалить ставшие ненужными строки или же наоборот, вставить новые. Если при создании макроса привязаться к границам диапазона при помощи ссылок на ячейки (например, A5, B7), то при вставке или удалении строк (столбцов) границы диапазона изменятся, и ссылки станут неправильными.
Если же присвоить диапазону A5:B7 имя, а затем, например, вставим после 5-й строки еще одну строку, то все эти строки, включая строку 8 (бывшую 7), будут относиться к тому же именованному диапазону. Такой механизм позволяет, как угодно менять размеры какого-то раздела в прайс-листе, ничего не меняя в коде VBA, который этот прайс обрабатывает.

52 Глава 2. Excel: прайс-лист для автоматического составления заказа
Рис. 2.2. Создание именованного диапазона |
Рис. 2.3. Диапазону A5:B7 присваивается |
|
имя ПАМЯТЬ |
Итак, для начала присвоим имя ПАМЯТЬ диапазону ячеек A5:B7, который в прайсе представляет раздел оперативной памяти для компьютеров (область под заголовком “ПАМЯТЬ”).
Как создать именованный диапазон
1.Для присвоения имени диапазону выполните следующие действия.
2.Выделите требуемый диапазон ячеек (в данном случае это диапазон A5:B7), как показано на рис. 2.2.
3.Выполните команду Вставка | Имя | Присвоить. На экране появится диалоговое окно Ïðè-
своение имени (рис. 2.3).
4.В поле Èìÿ введите, например, строку “ПАМЯТЬ”.
5.Закройте диалоговое окно щелчком мыши на кнопке OK.
см. также в гл. 4 раздел “Подключение анализируемых прайс-листов”, где описан еще один метод создания именованного диапазона.
Диапазону ячеек A5:B7 будет присвоено имя ПАМЯТЬ. Теперь можно сослаться на ячейку A5, как на объект, например,
Range(“ПАМЯТЬ”).Cells(1,1)
Эта запись обозначает первую ячейка в первой строке именованного диапазона ПАМЯТЬ. Казалось бы, какая разница? Ведь с таким же успехом можно обратиться к этой ячейке напрямую:
Range(“A5”)
или
Cells(5,1)
Но разница все же есть. При работе с прайс-листом любой раздел может менять свои размеры при вставке или удалении строк в нем самом или сдвигаться при вставке или удалении в предыдущих разделах. Благодаря присвоенному имени не нужно обо всем этом беспокоиться — Range(“ПАМЯТЬ”).Cells(1,1) всегда будет указывать на первую ячейку данного раздела.
Действуя аналогичным образом, далее следует присвоить имена всем остальным разделам прайс-листа. Вот список разделов в учебно-тренировочном прайсе рассматриваемого примера, а в скобках приведены имена, которые можно присвоить соответствующим диапазонам:
ПАМЯТЬ (ПАМЯТЬ)
МАТЕРИНСКИЕ ПЛАТЫ (МАТЕРИНСКИЕ_ПЛАТЫ) ПРОЦЕССОРЫ (ПРОЦЕССОРЫ)

Построение бланка заказа 53
ЖЕСТКИЕ ДИСКИ (ЖЕСТКИЕ_ДИСКИ) ВИДЕОКАРТЫ (ВИДЕОКАРТЫ) ЗВУКОВЫЕ КАРТЫ (ЗВУКОВЫЕ_КАРТЫ) КОРПУСА (КОРПУСА)
МОНИТОРЫ (МОНИТОРЫ)
МЫШИ, КЛАВИАТУРЫ (МЫШИ_КЛАВИАТУРЫ)
ПРИМЕЧАНИЕ
Имена диапазонов не должны включать в себя пробелы или знаки пунктуации, поэтому соответствующие символы были заменены знаком подчеркивания. В результате все указанные имена должны присутствовать в окне Присвоение имени (рис. 2.4).
Рис. 2.4. Весь прайс-лист “покрыт“ именованными диапазонами
Построение бланка заказа
Далее нам необходимо создать бланк заказа, который основывался бы на прайс-листе “PCкомплектующие”, и позволял изменять конфигурацию компьютера, исходя из имеющихся в прайслисте компонентов. Лучше всего будет делать это на отдельном рабочем листе. Разумеется, речь должна идти о листе в той же самой рабочей книге.
Создадим вначале заголовок бланка — он может быть абсолютно произвольным. Допустим, в первых двух строках поместим наименование бланка и его подзаголовки с тем, чтобы начать построение собственно бланка с ячейки A3, как изображено на рис. 2.5.
Каждая строка заказа должна будет иметь довольно сложное устройство, поэтому наилучший способ построения заключается в том, чтобы полностью сформировать одну законченную и действующую строку, а затем размножить ее путем копирования и вставки. Скопированные строки все равно затем придется немного подкорректировать, но такой подход все же сэкономит много времени.
← см. в гл. 1 раздел “Как форматировать раздел при помощи команды Специальная вставка”.
Рис. 2.5. Построение бланка заказа
1. Итак, создадим первую строку. Пусть она будет соответствовать монитору, которым должен быть укомплектован персональный компьютер. Для этого нам потребуется ввести в

54 Глава 2. Excel: прайс-лист для автоматического составления заказа
некоторые ячейки формулы и поместить в одну из ячеек элемент управления “Поле со спи-
ском”. Еще его называют комбинированным полем.
2.Вначале введем в ячейку A3 строку “Монитор” — это просто обозначение компонента, за который отвечает данная строка.
3.Далее необходимо ввести в ячейку B3 формулу =ИНДЕКС(МОНИТОРЫ; D3; 1), как это показано на рис. 2.6 — смысл этой формулы станет ясен немного дальше.
Рис. 2.6. Ввод формулы в ячейку B3
4. В ячейку C3 следует ввести похожую формулу: =ИНДЕКС(МОНИТОРЫ; D3; 2). При этом ячейка B3 отобразит ошибку формулы (#ЗНАЧ!), не обращайте на это внимания (рис.
2.7).
Рис. 2.7. Ввод формулы в ячейку C3
5. Следующий шаг состоит в том, чтобы поместить в ячейку B3 элемент управления “Поле со списком” и настроить его свойства так, чтобы он правильно взаимодействовал с введенными формулами.
Как создать и настроить элемент управления Поле со списком
1. Если панель инструментов Формы не видна, выполните команду Вид | Панели инструмен-
тов | Формы.
Рис. 2.8. Панель Формы
2.Выберите щелчком мыши на панели Формы элемент управления Поле со списком (рис.2.8).
3.“Нарисуйте” указателем мыши местоположение поля в ячейке B3, как показано на рис.2.9.
Рис. 2.9. Создание Поле со списком

Построение бланка заказа 55
4.Щелкните на поле со списком правой кнопкой мыши и выберите в контекстном меню коман-
ду Формат объекта.
5.В диалоговому окне Форматирование объекта выберите вкладку Элемент управления и
введите в поле Формировать список по диапазону строку “МОНИТОРЫ”.
6.В поле Связь с ячейкой введите ссылку D3.
7.В поле Количество строк списка введите число, характеризующее максимальное количество
элементов в соответствующем разделе прайс-листа (в нашем случае использовано значение 100). Диалоговое окно Форматирование объекта с измененными параметрами изображено на рис. 2.10.
8.Закройте диалоговое окно щелчком мыши на кнопке OK.
Рис. 2.10. Форматирование элемента управления Поле со списком
Описание работы элемента управления Поле со списком
Первая строка готова к использованию. Поле со списком должно теперь отображать именованный диапазон МОНИТОРЫ, при этом порядковый номер выбранного монитора, совпадающий с номером строки диапазона, будет заноситься в ячейку D3 элементом управления Поле со списком. И наоборот, если ввести любым способом в ячейку D3 целое число, то поле со списком отобразит соответствующий пункт в столбце “Наименование” раздела “Мониторы”. Разумеется, введенное число не должно быть больше, чем количества наименований в данном разделе.
Первоначально в D3 ничего не содержится, поэтому никакой монитор в поле со списком не выбран. Чтобы убедиться в работоспособности строки, необходимо раскрыть список щелчком мыши на кнопке с треугольником в правой части элемента управления. В раскрывшемся списке будут отображены имеющиеся в разделе МОНИТОРЫ (и соответствующем ему диапазоне) наименования товара (рис. 2.11).
Рис. 2.11. Поле с раскрывающимся списком в действии

56 Глава 2. Excel: прайс-лист для автоматического составления заказа
Выбранное при помощи мыши наименование будет автоматически помещено в поле списка, а его порядковый номер — в ячейку D3. Кроме этого, в ячейке C3 появится соответствующая выбранному наименованию цена (рис. 2.12).
Рис. 2.12. Выбор модели монитора
Использование функции ИНДЕКС
В ячейку C3 была помещена формула =ИНДЕКС(МОНИТОРЫ; D3; 2). Что она означает? Функция ИНДЕКС выполняет выборку из диапазона МОНИТОРЫ по порядковому номеру строки, который она берет из ячейки D3. Известно, что число 3 в эту ячейку поместил элемент управления Поле со списком, поскольку в списке выбран третий по счету пункт. Цифра 2 указывает, что нужно отображать значение из второго столбца диапазона (у нас это столбец “Цена”).
Ячейка B3 содержит похожую формулу, единственное отличие которой заключается в последнем аргументе функции ИНДЕКС. Цифра 1 вместо 2 означает, что ячейка отображает значение из первого столбца диапазона МОНИТОРЫ (в нашем примере это столбец “Наименование”). Но ведь ячейка не видна, она заслонена элементом управления, который и без того отображает именно это значение! Какой смысл дважды отображать одно и то же наименование, одно поверх другого? Фактически, ячейка B3 с таким же успехом могла бы быть пустой. Но находящаяся в ней формула требуется нам для того, чтобы в дальнейшем можно было бы в программном коде VBA одинаковым образом обращаться ко всем ячейкам сформированного бланка заказа.
На следующем этапе построения бланка нужно “размножить” первую строку при помощи операций копирования и вставки. Покажем этот механизм на примере строки “Материнские платы”.
Необходимо выделить строку “Мониторы” щелчком мыши на расположенном слева номере строки — серой области с цифрой 3 и скопировать строку в буфер обмена командой Копировать из меню Правка. Затем аналогичным образом выделить следующую (4) строку и вставить содержимое буфера обмена командой Вставить из меню Правка. Полученная строка будет точной копией строки “Мониторы”, ее теперь необходимо отредактировать.
Вместо “Мониторы”, в ячейку A4 следует ввести: “Материнские платы”.
Формулу в ячейке B4 необходимо отредактировать — вместо =ИНДЕКС(МОНИТОРЫ; D3; 1) она должна иметь вид: =ИНДЕКС(МАТЕРИНСКИЕ_ПЛАТЫ; D4; 1). Обратите внимание на тот факт, что получить доступ к ячейке B4 при помощи мыши теперь затруднительно, поскольку она заслонена элементом управления. Щелчок мыши выделит Поле со списком, а не ячейку, которая находится под ним. Необходимо выделить ячейку слева или справа, а затем перейти к B4 при по-
мощи клавиш [→] или [←].
Аналогичным образом следует исправить формулу в ячейке C4:
=ИНДЕКС(МАТЕРИНСКИЕ_ПЛАТЫ; D4; 2).
Далее нужно щелкнуть правой кнопкой мыши на поле со списком в ячейке B4 и выбрать в контекстном меню команду Формат объекта. В полях на вкладке Элемент управления раскрывшегося диалогового окна необходимо изменить соответствующие значения (МАТЕРИНСКИЕ_ПЛАТЫ вместо МОНИТОРЫ, и D4 вместо D3).
В результате строка “Материнские платы” станет вторым действующим элементом создаваемого бланка заказа. Действуя аналогичным образом, можно создать все остальные строки: “Процессор”, “Память”, “Жесткий диск”, “Видеокарта”, “Звуковая карта” и “Корпус”. В итоге рабочий лист должен выглядеть подобно рис. 2.13.

Построение бланка заказа 57
Рис. 2.13. Все строки с раскрывающимися списками готовы к действию
Создание в бланке заказа “безвариантных” строк
Наконец, осталось добавить две “безвариантные” строки, относящиеся к клавиатуре и мыши. Безвариантные, поскольку раздел “МЫШИ, КЛАВИАТУРЫ” в прайс-листе содержит всего одну мышь и всего одну клавиатуру (предположим, что выбора клиенту в данном вопросе не предоставляется — бывают и такие ситуации). Как поступить в этом случае?
Можно просто ввести в соответствующие ячейки необходимые значения или же поместить туда ссылки на ячейки листа “PC-комплектующие”, где эти значения содержатся. Более корректный (и, заметим, более дальновидный) способ состоит в доступе к разделу прайс-листа посредством именованного диапазона и все той же функции ИНДЕКС. “Безвариантность” строки приведет лишь к тому, что вместо значения из ячейки столбца D, в качестве номера строки следует использовать просто соответствующее число. Для указания мыши следует ввести в ячейки B11 и C11 выраже-
ния =ИНДЕКС(МЫШИ_КЛАВИАТУРЫ; 1; 1) и =ИНДЕКС(МЫШИ_КЛАВИАТУРЫ; 1; 2) соот-
ветственно. Нетрудно догадаться, что для строки “Клавиатура” в ячейки B12 и C12 необходимо ввести =ИНДЕКС(МЫШИ_КЛАВИАТУРЫ; 2; 1) и =ИНДЕКС(МЫШИ_КЛАВИАТУРЫ; 2; 2).
Рис. 2.14. Бланк заказа дополнен итоговой строкой

58 Глава 2. Excel: прайс-лист для автоматического составления заказа
Подсчет суммы заказа
Наконец, добавим к бланку заказа итоговую строку, в которой подсчитывается цена всего компьютера в сборе. Вычисление значения суммы по всем компонентам обеспечивается формулой =СУММ(C3:C12), помещенной в ячейку C13 (рис. 2.14).
Нетрудно убедиться в том, что для внесения изменений в конфигурацию готовящегося к продаже компьютера теперь достаточно всего двух щелчков мыши. Один для того, чтобы развернуть соответствующий список и второй, чтобы выбрать в списке новый компонент. Цена изменившегося компонента и новая цена всего компьютера немедленно отобразятся в бланке заказа.
Решение проблемы совместимости выбираемых устройств компьютера
Любой человек, сталкивавшийся с проблемами комплектации персональных компьютеров, знает, что далеко не все компоненты представленные на мировом рынке совместимы между собой. Например, на конкретную материнскую плату можно установить отнюдь не всякий процессор. Кроме того, помимо чисто технических причин, могут иметь место и другие соображения, согласно которым определенные элементы из разных разделов прайса не должны использоваться вместе для комплектации ПК. Иными словами, бланк заказа должен проявлять некоторую разборчивость, анализировать содержащиеся в нем комбинации и не допускать появления запрещенных сочетаний компонентов.
Для дальнейшего продвижения вперед в решении задачи автоматизации работы необходимо воспользоваться услугами VBA.
Постановка задачи
И вновь в первую очередь требуется решить, — каким образом, и в какой момент времени должен запускаться макрос, который будет создан? Первый, приходящий на ум вариант — использовать специальный элемент управления, например, командную кнопку, при помощи которого пользователь мог бы инициировать процесс проверки выбранных вариантов на совместимость. Но в подобном решении скрываются две проблемы.
Первая из них состоит в том, что анализировать придется каждый раз полный набор всех возможных сочетаний. Даже при не слишком большом числе разделов в прайсе и содержащихся в них вариантов это может привести к почти астрономическому числу анализируемых комбинаций.
Вторая проблема носит интерфейсный характер. Пользователю придется выполнять проверку, то есть, приводить в действие командную кнопку, после каждого внесенного изменения. Хорошенькая автоматизация! Такой интерфейс трудно назвать дружелюбным.
Создание процедуры Раскрсписок2_Изменение()
Гораздо проще было бы анализировать только ту часть комбинаций, которая касается внесенного изменения. Поэтому выполнять анализ лучше у источника изменений — Поля со списком. Тем более, что данный элемент управления как раз поддерживает подходящее событие. При выборе в раскрывающемся списке нового элемента происходит событие Изменение. Например, если выбрать из раскрывающегося списка первого созданного на листе Поля со списком новое значение, то будет выполнена следующая процедура
Sub Раскрсписок1_Изменение()
Это позволяет, во-первых, автоматически проводить анализ комбинации именно в той части, которая подверглась изменению. И, во-вторых, при таком подходе нет нужды в глобальном рассмотрении всех комбинаций — достаточно определить несколько запретных вариантов в тех полях со списком, где такие варианты возможны.

Выпишите счет, пожалуйста… 59
Предположим, что речь идет о совместимости материнской платы и процессора. За материнскую плату у нас отвечает второе поле со списком. Второе, если до элемента управления из строки “Монитор” в данной рабочей книге поля со списком больше не использовались. Таким образом,
надо в процедуре Раскрсписок2_Изменение() предусмотреть проверку — соответствует ли выбранная в данный момент материнская плата ранее выбранному процессору.
Допустим, что первый пункт в разделе материнских плат совместим с первыми тремя пунктами в разделе процессоров, но не совместим с остальными тремя. Как предотвратить выбор пользователем запретной комбинации? И каким образом макрос вообще может определить, какой пункт списка выбрал пользователь? Очень просто — значения в ячейках столбца D содержат всю необходимую информацию.
Как создать процедуру обработки события для элемента управления на рабочем листе, уже было рассмотрено. Щелкнем правой кнопкой мыши на поле со списком в строке “Материнская плата” и выберем в открывшемся контекстном меню команду Назначить макрос. Диалоговое окно Назначить макрос объекту закроем щелчком на кнопке Создать. В результате перед нами появится заготовка процедуры Раскрсписок2_Изменение(), которую остается лишь наполнить необходимым кодом, приведенным на листинге 2.1.
ЛИСТИНГ 2.1
Sub Раскрсписок2_Изменение()
If Range("D4").Value = 1 Then If Range("D5").Value > 3 Then
Range("D4").Value = 2
MsgBox "Для выбранного процессора данная плата не подходит!" End If
End If
End Sub
Переведем исходный текст макроса на обычный язык: если в моем списке (то есть, списке материнских плат) выбран первый пункт, и если при этом в списке из строки “Процессор” выбран пункт с номером более 3, то выбрать в моем списке пункт 2 и выдать сообщение пользователю.
Вернувшись в окно Excel, легко проверить действие макроса: следует выбрать четвертый пункт в строке “Процессор” и первый — в строке “Материнская плата”. Вместо первого выбранным окажется второй, а на экране появится окно сообщения, которое следует закрыть щелчком мыши на кнопке OK (рис. 2.15).
Рис. 2.15. Макрос выдает сообщение пользователю
см. также в этой главе раздел “Создание диалогового окна при помощи функции MsgBox” и в приложении раздел “Вывод сообщений (функция MsgBox)”.
Выпишите счет, пожалуйста…
Но вот настал тот заветный миг, ради которого вообще создавался прайс-лист. Потенциальный клиент превратился во вполне реального покупателя, произнеся фразу “Выпишите счет, пожалуйста…”.

60 Глава 2. Excel: прайс-лист для автоматического составления заказа
Постановка задачи
Заполненный бланк заказа теперь должен превратиться в счет. Как это сделать? У нас есть таблица компонентов компьютера с указанием их цен, а также общая сумма. Чтобы превратить все это в законченный счет, необходимо добавить заголовок и несколько обязательных реквизитов. Можно было бы сделать это, скопировав бланк в какое-то место на заранее подготовленном рабочем листе с тем, чтобы после его распечатать. Это можно сделать как вручную, так и при помощи VBA. Собственно, даже не слишком подготовленный пользователь без большого труда найдет способ это сделать.
В учебно-тренировочных целях рассмотрим задачу формирования счета для клиента. Дело в том, что этот случай кажется автору подходящим для достижения сразу двух важных целей. Первая из них состоит в том, чтобы научить читателя создавать программы VBA без программирования на VBA, ведь несложные макросы в среде MS Office давным-давно можно было создавать без участия редактора Visual Basic. Это особенно важно потому, что создание макросов при помощи макрорекордера и чтение получившегося программного кода — самый легкий и доступный способ самостоятельного освоения языка VBA. Вторая цель — подготовить читателя к следующей главе, где макросы рабочих листов Excel будут работать с документами Word, а макросы документов Word — с листами Excel. Таким образом, создадим счет двумя способами. В первом случае используем макрорекордер Excel, который “сам напишет” для нас исходный текст макроса. Во втором варианте решения задачи наш макрос использует средства интеграции MS Office и создаст счет в виде документа Word.
Элемент управления Кнопка
Вначале, как обычно, позаботимся о способе запуска будущего макроса. Командная кнопка кажется в данном случае вполне уместным средством. Ее и используем. Необходимо выбрать на панели инструментов Формы элемент управления Кнопка и поместить его в нижней части бланка заказа (рис. 2.16).
Рис. 2.16. Бланк заказа снабжен командной кнопкой “Счет“
Создавать пустой макрос для новой кнопки необязательно. Достаточно снабдить ее надписью “Счет”. Наконец, чтобы полностью завершить подготовку бланка заказа к дальнейшим упражнениям, скроем столбец D, где содержится служебная информация — порядковые номера выбранных элементов списков: выделите столбец и выполните команду Формат | Столбец | Скрыть.
← см. также в этой главе раздел “Как поместить на лист элемент управления”.
Первый способ формирования счета (использование макрорекордера)
Создадим счет на отдельном листе в той же рабочей книге. Область таблицы с конфигурацией компьютера и столбиком “цена” каждый раз будет меняться, в то время как остальные элементы счета будут оставаться неизменными. Дату счета можно сформировать при помощи функции рабочего листа СЕГОДНЯ, а такой реквизит, как номер счета, придется вводить вручную.