Вычислительная техника и

advertisement
Глава 2. Объекты Microsoft Excel
До настоящего времени мы рассматривали возможности VBA без особой связи с
информацией на рабочем листе. В этой главе мы познакомимся с объектами,
которые позволяют работать с данными, расположенными в ячейках листов рабочих
книг Microsoft Excel. В последующих главах будут рассмотрены сложные
разработки, базирующие на основных конструкциях, которые мы здесь разберем.
Весь файл рабочей книги Excel представлен в объекте Workbook, который имеет
большое количество свойств и методов. Справочная информация по ним
присутствует как в электронной справке по VBA, так и в большом количестве
изданий по данной теме. Мы не будем углубляться в чисто справочную информацию
и во вводной части рассмотрим только те сведения, с которыми далее встретимся в
рассматриваемых примерах.
Так, свойство Worksheets объекта Workbook представляет семейство всех рабочих
листов книги. И для обращения к конкретному листу книги с помощью этого
свойства следует просто указать в качестве параметра номер листа, что выглядит так
— Worksheets(номер листа). Другой вариант заключает в указании в качестве
параметра названия листа — Worksheets(“Название листа”).
Одним из наиболее часто программируемых событий, связанных с книгой в целом,
является событие Open, которое происходит при открытии рабочей книги. Так, если
мы хотим, чтобы при открытии книги выполнялись определенные действия, то
следует расположить необходимый программной код внутри процедуры
Workbook_Open. В большинстве рассматриваемых далее примеров будет
рассматриваться программирование этого события.
Следующим объектом в порядке иерархии после Workbook является объект
Worksheet, представляющий рабочий лист. Из многообразия методов этого объекта
широко используется Activate, который существует и для семейства листов
Worksheets, о котором мы уже сказали выше. Например, если при работе на
первом листе книги требуется активизировать
третий лист, то синтаксис
программной строки в процедуре (скажем, выполняемой по щелчку по кнопке)
должен быть следующий:
Worksheets(3).Activate
Известно, что Microsoft Excel предлагает сервис, связанный с защитой рабочих книг
и составляющих ее листов. Так, в примерах мы будем использовать метод Protect
(семейства Worksheets), который защищает рабочий лист от внесения в него
изменений. Для программной установки защиты с паролем (пароль указывается в
параметре Password этого метода) третьего листа можно поступить следующим
образом:
Worksheets(3).Protect Password:="12345", DrawingObjects:=True, _
Contents:=True, Scenarios:=True
Существует и соответствующий метод Unprotect, позволяющий снять защиту с
листа. Для только что установленной защиты метод ее снятия:
Worksheets(3).Unprotect Password:="12345"
Любая практическая работа в Excel так или иначе касается информации в ячейках.
Для работы с ячейками в VBA существует объект Range (в переводе диапазон ячеек).
И использование этого объекта требует задания параметра — диапазона ячеек,
которые нас интересуют. Это может быть одна ячейка или группа ячеек. Так, если мы
напишем
Worksheets(3).Range (“А1”).Value = 5,
то это означает, что в ячейку А1 третьего листа мы программно записываем число 5.
Здесь используется основное свойство объекта Range — Value. Буквально оно
означает значение или содержимое ячейки (или группы ячеек).
В следующей конструкции в совокупность ячеек программно вводится буква А:
Worksheets(1).Range (“А1:C3”).Value = “A”.
Другой способ работы с ячейками реализуется с помощью объекта Cells, и
синтаксис его использования выглядит следующим образом:
Cells (номер строки, номер столбца).
Фактически с точки зрения их использования рассматриваемые объекты похожи.
Например, получить в переменной Z значение ячейки D5 можно двумя разными
способами:
Z = Range(“D5”).Value
или
Z = Cells(5,4).Value .
В качестве примера программной конструкции на тему этих обоих объектов можно
привести следующее присвоение:
Worksheets(2).Range(“C5”).Value = Worksheets(3).Cells(5, 1).Value
Автоматизированный бланк
Теперь после того, как мы познакомились с простыми конструкциями доступа из
процедур VBA к ячейкам Excel, пора перейти к более сложной задаче.
Будем считать, что нам необходимо разработать удобный бланк заказа при
обслуживании покупателей в компьютерном салоне. Наша задача — обеспечить
удобный подбор необходимой покупки из возможных вариантов по информации,
присутствующей в прайс-листе.
Будем считать, что комплектация состоит максимум из 3-х компонентов: ноутбука,
сумки к нему и модема. При этом различных моделей ноутбуков, сумок и модемов
достаточно много, и эта номенклатура отражается на втором листе книги.
Такой лист с названием Прайс представлен на рис.2.1. Понятно, что строк в прайслисте может быть достаточно много и при подборе заказа не очень удобно его
постоянно прокручивать.
Наша задача далее заключается в разработке удобного электронного бланка. Заметим
только, что в разрабатываемой книге предполагается, что прайс должен находиться
на втором рабочем листе в последовательности листов (в дальнейшем программном
коде используется номер листа в качестве параметра семейства Worksheets).
Рис.2.1.
На рис. 2.1 видно, что первая строка прайс-листа представляет собой совокупность
заголовков, а сами данные располагаются, начиная со второй строки. В столбцах А и
В содержится соответственно описание модели ноутбука и его стоимость.
Следующие два столбца — название модели сумки со стоимостью, и затем модем,
также с ценой.
Мы попробуем на первом рабочем листе создать удобный для пользователя
электронный бланк заказа, который будет использовать информацию из прайс-листа.
Интерфейс первого листа, который нам необходимо разработать, показан на рис. 2.2.
Разберем технические действия для его создания.
Во-первых, необходимо расширить столбцы A , B и C, а затем в ячейку В2 ввести
текст — Бланк заказа и отформатировать его соответствующим образом.
После этого разместим в ячейке В3 текст — Заказ №. Рядом с этим текстом на листе
разместим элемент Текстовое окно для набора с клавиатуры номера заказа. У
свойства Name этого элемента выберем значение — Nomer, добавим серый фон окна
(с помощью свойства BackColor), а для свойства AutoSize установим в качестве
значения True. В этом случае ширина текстового окна будет автоматически
увеличиваться при вводе символов.
Теперь следует заполнить текстом (рис. 2.2) содержимое ячеек B5, C5, A7, A8
, A9 , B11 и выполнить соответствующее форматирование.
После этого уберем с экрана сетку, а для прямоугольного диапазона A5–C14
установим внешние границы. Кроме этого можно также установить заливку для
диапазона A5–C14 (это выполняется с помощью несложных технических действий в
Microsoft Excel).
Рис.2.2.
Теперь следует разместить три элемента управления типа Поле со списком — с
ними мы уже работали в первой главе. Для того чтобы не было противоречий с
программным кодом, имена этих элементов выберем соответственно (сверху вниз)
— Spk1, Spk2 и Spk3.
Таким образом, мы создали интерфейс для нашей разработки. Далее наступает этап
программирования созданных элементов, поэтому перейдем в редактор для
написания программного кода.
Первая наша задача заключается в том, чтобы при открытии книги созданные три
списка на первом листе автоматически заполнялись информацией из прайс-листа. В
начале главы мы уже говорили о том, что при открытии книги автоматически
выполняется предопределенная процедура Workbook_Open(). Для того, чтобы
перейти к написанию этой процедуры, следует в редакторе кода в меню View
выбрать раздел Project Explorer, и в появившемся окне дважды щелкнуть по
пиктограмме с названием ЭтаКнига. Таким образом, мы получили доступ к методам
объекта Workbook.
Теперь наша задача правильно оформить процедуру Workbook_Open(),которая
обеспечивает заполнение списков моделями ноутбуков, сумок и модемов (листинг
2.1).
Листинг 2.1. Процедура, выполняемая при открытии книги
Private Sub Workbook_Open( )
' Очистка первого списка на первом листе книги
Worksheets(1).Spk1.Clear
' Подсчет в переменной N количества вариантов ноутбуков по прайсу
N = 0
While Worksheets(2).Cells(N + 2, 1).Value <> ""
N = N + 1
Wend
' Заполнение первого списка
For i = 2 To N + 2
Worksheets(1).Spk1.AddItem Worksheets(2).Cells(i, 1).Value
Next
' Очистка второго списка на первом листе книги
' Подсчет в переменной N количества моделей сумок
Worksheets(1).Spk2.Clear
N = 0
While Worksheets(2).Cells(N + 2, 3).Value <> ""
N = N + 1
Wend
' Заполнение второго списка
For i = 2 To N + 2
Worksheets(1).Spk2.AddItem Worksheets(2).Cells(i, 3).Value
Next
' Очистка третьего списка на первом листе нашей книги
' Подсчет в переменной N количества моделей модемов
Worksheets(1).Spk3.Clear
N = 0
While Worksheets(2).Cells(N + 2, 5).Value <> ""
N = N + 1
Wend
' Заполнение третьего списка
For i = 2 To N + 2
Worksheets(1).Spk3.AddItem Worksheets(2).Cells(i, 5).Value
Next
'Установка начальных параметров
Worksheets(1).Spk1.ListIndex = -1
Worksheets(1).Spk2.ListIndex = -1
Worksheets(1).Spk3.ListIndex = -1
Worksheets(1).Nomer.Text = ""
Worksheets(1).Range("C7:C9").Value = ""
End Sub
Прокомментируем еще несколько программных конструкций этой процедуры. Так, в
записи
While Worksheets(2).Cells(N + 2, 1).Value <> ""
извлекается содержимое ячейки из первого столбца с информацией об очередной
модели ноутбука со второго листа. Конструкция <> обозначает “Не равно”, а "" —
это две двойных кавычки, между которыми ничего нет. В совокупности эта запись
обозначает выполнение цикла, пока значение в очередной ячейке списка системных
блоков на втором листе не окажется пустым. Пустая ячейка — это индикатор того,
что данных в этом столбце больше нет. Таким образом, чтобы избежать при
заполнении списков потери информации следует не допускать разрывов в данных на
втором листе.
В процедуре на листинге 2.1 после подсчета количества ноутбуков используется
метод AddItem, который добавляет в объект Поле со списком новый элемент
(новую строку). Так, в конструкции
Worksheets(1).Spk1.AddItem Worksheets(2).Cells(i, 1).Value
через пробел записывается содержимое ячейки, которое добавляется в список Spk1.
В данном случае это ячейка Cells(i,1) второго листа. Заполнение других списков
аналогично и отличается только номерами столбцов.
Таким образом, мы создали процедуру Workbook_Open(), которая обеспечивает
заполнение списков данными со второго листа (из прайс-листа) при открытии книги.
Теперь, для того чтобы все то, что мы создали, работало, необходимо книгу закрыть
и заново ее открыть.
Однако пока выбор в списках той или иной модели не приводит к заполнению
информации о ее цене. Нашу разработку следует продолжить, поэтому мы заново
вернемся в окно написания программного кода.
Для автоматической подстановки цены модели необходимо написать процедуры,
выполняемые по щелчкам по спискам. На листинге 2.2 приведена процедура, которая
выполняется при щелчке по первому списку (списку, включающему модели
ноутбуков).
Листинг 2.2. Обработка щелчка по списку, включающему модели ноутбуков
Private Sub Spk1_Click()
Range("c7").Value = _
Worksheets(2). Cells(Spk1.ListIndex + 2, 2). Value
End Sub
В этой процедуре ячейка С7 заполняется ценой ноутбука из прайса. Если посмотреть
на бланк заказа, то именно ячейка С7 на этом листе отводится для цены ноутбука.
Здесь же в этой конструкции Spk1.ListIndex — индекс выделенного элемента в
первом списке. Двойка добавляется к этому значению потому, что индексация
элементов списка начинается с нуля, а данные о моделях ноутбуков на втором листе
располагаются со второй строки. Здесь также учитывается, что цены ноутбуков
указаны во второй колонке. Таким образом, в этой строке мы извлекаем информацию
о цене ноутбука. Может возникнуть вопрос — почему в правой части программной
строки мы указали номер листа (2), а в левой нет? Это связано с тем, что объект с
именем Spk1, событие которого мы обрабатываем, находится на первом листе,
который и предполагается листом по умолчанию.
Щелчки по двум другим спискам приводят к аналогичным действиям (к заполнению
цен сумки и модема), и на листинге 2.3 приведены процедуры, реализующие этот
эффект.
Листинг 2.3. Процедуры выбора цен сумки и модема
Private Sub Spk2_Click()
Range("c8").Value =
_
Worksheets(2).Cells(Spk2.ListIndex + 2, 4).Value
End Sub
Private Sub Spk3_Click()
Range("c9").Value =
_
Worksheets(2).Cells(Spk3.ListIndex + 2, 6).Value
End Sub
В результате мы получили автоматизированное заполнение бланка заказа (выбор в
списках названий позиций товаров и автоматическая подстановка цены). Для
калькуляции суммы заказа осталось только в ячейку С12 поставить формулу для
вычисления суммы:
=СУММ(C7:C9).
Заметим, что это обыкновенная формула в ячейке первого листа Microsoft Excel.
Следующий этап автоматизации заключается в создании печатной формы этого
бланка.
Сначала создадим на первом листе кнопку Печать (рис.2.3), а затем для нее напишем
необходимую процедуру.
Таким образом, теперь мы должны на 3-м листе книги создать печатную
(автоматически заполняемую по щелчку по кнопке) форму.
Рис.2.3.
Первая задача на этом пути, как и прежде, чисто техническая — обеспечить
форматирование третьего листа книги подобно тому, как показано на рис.2.4
(никаких элементов управления здесь нет).
На рис.2.4 используется — добавление фона к ячейкам, создание внешних и
внутренних границ, подбор размера шрифта, выравнивание содержимого ячейки по
горизонтали. Также здесь мы убрали отображение сетки. В дальнейшем в ячейку C2
будет подставляться номер заказа с первого листа (точнее из соответствующего
текстового поля), а содержимое таблицы также будет автоматически заполняться
информацией о заказанных позициях и их ценах.
При желании на печатную форму можно добавить логотип организации и внести
дополнительную текстовую информацию. В этом случае третий лист нашей книги
станет больше похож на печатную форму документа.
Фактически мы разработали заготовку, в которую по щелчку по кнопке Печать
будет заноситься информация о текущем заказе с первого листа.
Перейдем в режим конструктора и далее в редактор написания программного кода.
Это выполняется, как мы знаем, двойным щелчком по кнопке Печать. В этом
случае, вы автоматически попадаете в процедуру, которая обрабатывает щелчок по
рассматриваемой кнопке. На листинге 2.4 приводится текст этой процедуры.
Рис.2.4
Листинг 2.4. Обработка щелчка по кнопке Печать
Private Sub Prn_Click()
Очистка печатного бланка
Worksheets(3).Range("A10:C15").Value = ""
Nom = 1
' Внесение в печатную форму информации о ноутбуке
If Spk1.Text <> "" Then
Worksheets(3).Cells(9 + Nom, 1).Value = Nom
Worksheets(3).Cells(9 + Nom, 2).Value = _
Worksheets(1).Cells(7, 1).Value + "
" + Spk1.Text
Worksheets(3).Cells(9 + Nom, 3).Value = _
Worksheets(2).Cells(Spk1.ListIndex + 2, 2).Value
Nom = Nom + 1
End If
' Внесение в печатную форму информации о сумке к ноутбуку
If Spk2.Text <> "" Then
Worksheets(3).Cells(Nom + 9, 1).Value = Nom
Worksheets(3).Cells(Nom + 9, 2).Value = _
Worksheets(1).Cells(8, 1).Value + "
" + Spk2.Text
Worksheets(3).Cells(Nom + 9, 3).Value = _
Worksheets(2).Cells(Spk2.ListIndex + 2, 4).Value
Nom = Nom + 1
End If
' Внесение в печатную форму информации о модеме
If Spk3.Text <> "" Then
Worksheets(3).Cells(Nom + 9, 1).Value = Nom
Worksheets(3).Cells(Nom + 9, 2).Value = _
Worksheets(1).Cells(9, 1).Value + "
" + Spk3.Text
Worksheets(3).Cells(Nom + 9, 3).Value = _
Worksheets(2).Cells(Spk3.ListIndex + 2, 6).Value
End If
' Автоматическая установка номера заказа
Worksheets(3).Range("c2").Value = Nomer.Text
Worksheets(3).Range("b15").Value = "Итого"
Worksheets(3).Range("c15").Value = Range("c11").Value
Worksheets(3).Activate
End Sub
Теперь автоматизированная книга готова и вы можете попробовать оформить с
помощью созданной разработки несколько гипотетических заказов.
Модернизация бланка заказа
В предыдущем разделе мы рассмотрели вариант формирования бланка заказа.
Понятно, что в различных ситуациях требуются различные бланки. Рассмотрим
разработку автоматизированного бланка вида показанного на рис.2.5. В этом случае
прайс формируется из товаров общей категории (рис.2.6), и при открытии книги все
списки первого листа книги заполняются одинаковым набором товаров. В отличие от
предыдущего бланка в книгу добавлена дополнительная функциональность —
колонка для указания количества единиц выбранного товара. В колонке Е
подсчитывается сумма по каждому товару указанному в списке — это обычная
формула в ячейке (произведение стоимости единицы товара на количество). Такая
организация бланка позволяет получить в заказе несколько однотипных товаров
(например, несколько сумок).
На листинге 2.5 представлена процедура выполняемая при открытии книги. Строки
программы не требуют дополнительного комментария. Заметим, только что имена
списков выбраны – Spk1, Spk2, Spk3, Spk4, Spk5. В отличие от предыдущей
разработки в этом случае списки заполняются одинаково — всеми элементами,
которые имеются в прайсе.
Рис.2.5.
Рис. 2.6.
Листинг 2.5. Процедура, выполняемая при открытии
Private Sub Workbook_Open()
' Очистка списков на первом листе книги
Worksheets(1).Spk1.Clear
Worksheets(1).Spk2.Clear
Worksheets(1).Spk3.Clear
Worksheets(1).Spk3.Clear
Worksheets(1).Spk5.Clear
' Подсчет в переменной N количества товаров по прайсу
N = 0
While Worksheets(2).Cells(N + 2, 1).Value <> ""
N = N + 1
Wend
' Заполнение списков
For i = 2 To N + 1
Worksheets(1).Spk1.AddItem Worksheets(2).Cells(i, 1).Value
Worksheets(1).Spk2.AddItem Worksheets(2).Cells(i, 1).Value
Worksheets(1).Spk3.AddItem Worksheets(2).Cells(i, 1).Value
Worksheets(1).Spk4.AddItem Worksheets(2).Cells(i, 1).Value
Worksheets(1).Spk5.AddItem Worksheets(2).Cells(i, 1).Value
Next
'Установка начальных параметров
Worksheets(1).Spk1.ListIndex = -1
Worksheets(1).Spk2.ListIndex = -1
Worksheets(1).Spk3.ListIndex = -1
Worksheets(1).Spk4.ListIndex = -1
Worksheets(1).Spk5.ListIndex = -1
Worksheets(1).Nomer.Text = ""
Worksheets(1).Range("A7:A11").Value = ""
Worksheets(1).Range("C7:e11").Value = ""
End Sub
После открытия книги ее функциональность обеспечивается процедурами,
выполняемыми по щелчкам по спискам — кода мы выбираем конкретный товар. На
листинге 2.6 представлена процедура выполняемая при щелчке по первому списку
(самому верхнему). Здесь первая строка обеспечивает выбор цены из прайса для
соответствующего товара. Следующие строки обеспечивают установку единицы в
качестве номера и единицы в качестве количества единиц выбранной номенклатуры.
Для автоматического вычисления суммы в ячейку Е7 установим формулу =C7*D7. В
реальной работе часто требуется отменять принятое решение – отменить выбор
номенклатуры. В этом случае мы используем процедуру Spk1_Change, которая
автоматически выполняется при изменениях в списке. На рис.2.7 текст данной
процедуры приведен, который обеспечивает при удалении информации из поля
списка сброс значений в ячейках a7, c7, d7.
Листинг 2.6. Процедура, выполняемая по щелчку по верхнему списку
Private Sub Spk1_Click()
Range("c7").Value = _
Worksheets(2).Cells(Spk1.ListIndex + 2, 2).Value
Range("a7").Value = 1
Range("d7").Value = 1
End Sub
Листинг 2.7. Процедура, выполняемая при изменениях в верхнем списке
Private Sub Spk1_Change()
If Spk1.Text = "" Then
Range("a7").Value = ""
Range("c7").Value = ""
Range("d7").Value = ""
End If
Таким образом, процедуры, приведенные на листингах 2.6 и 2.7, обеспечивают
работу пользователя с первой строкой бланка заказа. На листингах 2.8 и 2.9
приведены аналогичные дисциплины для второй строки бланка.
Листинг 2.8. Процедура, выполняемая по щелчку по второму списку
Private Sub Spk2_Click()
Range("c8").Value = _
Worksheets(2).Cells(Spk2.ListIndex + 2, 2).Value
Range("a8").Value = 2
Range("d8").Value = 1
End Sub
Листинг 2.9. Процедура, выполняемая при изменениях во втором списке
Private Sub Spk2_Change()
If Spk2.Text = "" Then
Range("a8").Value = ""
Range("c8").Value = ""
Range("d8").Value = ""
End If
End Sub
Для остальных списков процедуры мы приводим – при необходимости читатели
могут посмотреть их на компакт-диске прилагаемом к книге.
Осталось обеспечить печать бланка (рис.2.7). На листинге 2.10 приведена процедура,
которая обеспечивает заполнение печатной формы.
Рис.2.7.
Листинг 2.10. Процедура печати
Private Sub Prn_Click()
Worksheets(3).Range("A11:E16").Value = ""
For i = 1 To 5
Worksheets(3).Cells(i + 10, 1).Value = Cells(6 + i, 1).Value
Worksheets(3).Cells(i + 10, 3).Value = Cells(6 + i, 3).Value
Worksheets(3).Cells(i + 10, 4).Value = Cells(6 + i, 4).Value
Worksheets(3).Cells(i + 10, 5).Value = Cells(6 + i, 5).Value
Next
Worksheets(3).Cells(11, 2).Value = Spk1.Text
Worksheets(3).Cells(12, 2).Value = Spk2.Text
Worksheets(3).Cells(13, 2).Value = Spk3.Text
Worksheets(3).Cells(14, 2).Value = Spk4.Text
Worksheets(3).Cells(14, 2).Value = Spk5.Text
Worksheets(3).Range("d2").Value = Nomer.Text
Worksheets(3).Range("d16").Value = "Итого"
Worksheets(3).Range("e16").Value = Range("e12").Value
Worksheets(3).Activate
End Sub
Бланк заказа на офисные товары
Рассмотрим еще одну подобную задачу.
Наша цель — разработать удобное приложение для составления заявки на
канцелярские товары для офиса. Начнем с того, что создадим новую рабочую книгу
Excel и на втором листе сформируем список товаров с их ценами (рис. 2.8). Этот
список организован достаточно просто — название и рядом его цена.
Теперь на первом рабочем листе создадим удобную форму для ввода информации о
заказе (рис.2.9).
Рассмотрим сначала технические действия по оформлению первого листа.
Во-первых, уберем сетку с экрана (это действие уже встречалось выше). После этого
оформим столбцы A, B , C и D следующим образом: установим внешние границы,
поставим внутренние границы, введем подписи столбцов в ячейки A3, B3, C3 и D3.
Теперь перейдем к расположению элементов управление на листе.
Самый правый элемент на этом рисунке — Поле со списком. Имя этого объекта нам
далее потребуется, и поэтому для его свойства Name установим “наше” значение —
Spk.
Кроме поля со списком на листе располагается надпись выше которой в ячейке
рабочего листа располагается слово Итог. Сама надпись используется для подсчета
суммы. Ее имя будет использоваться в дальнейших процедурах, и поэтому установим
Symma в качестве значения ее свойства Name.
Рис.2.8.
В верхней части экрана располагаются еще три кнопки — Очистить, Пересчет и
Печать. Их имена выберем соответственно Clr, Calc и Prn.
Рис.2.9.
На этом дизайн интерфейса завершен, и нам можно перейти к программированию.
Во-первых, необходимо сделать так, чтобы список Spk автоматически заполнялся
при открытии книги. Поэтому оформим процедуру, выполняемую при открытии
книги, следующим образом (листинг 2.10).
Листинг 2.10. Процедура Workbook_Open
Private Sub Workbook_Open()
‘ Очистка списка
Worksheets(1).Spk.Clear
‘ Подсчет количества записей в прайсе на втором листе
N = 0
While Worksheets(2).Cells(N + 1, 1).Value <> ""
N = N + 1
Wend
‘ Заполнение списка
For i = 1 To N
a = Worksheets(2).Cells(i, 1).Value & "
" & _
Worksheets(2).Cells(i, 2).Value & " руб."
Worksheets(1).Spk.AddItem a
Next
‘ Установка нуля в поле для суммы
Worksheets(1).Lbl.Caption = "0"
‘ Начальная установка списка
Worksheets(1).Spk.ListIndex = -1
End Sub
Следующая задача в рамках данной разработки заключается в том, чтобы при щелчке
по элементу списка информация фиксировалась в очередной строке первого рабочего
листа. Таким способом мы включаем в заявку очередную строку с помощью
следующей процедуры (листинг 2.11).
Листинг 2.11. Процедура, выполняемая по щелчку по списку
Private Sub Spk_Click()
‘ Подсчет в переменной N количества уже заполненных строк бланка заказа
N = 0
While Cells(N + 4, 1).Value <> ""
N = N + 1
Wend
‘ Записываем название очередной позиции в заявку
Cells(N + 4, 1) = Worksheets(2).Cells(Spk.ListIndex + 2, 1).Value ‘
Записываем цену очередной позиции из прайса
Cells(N + 4, 2) = Worksheets(2).Cells(Spk.ListIndex + 2, 2).Value
‘ Используем стандартную функцию InputBox для ввода количества
‘
товаров с клавиатуры
qw = InputBox("Введите количество", "Ввод числа единиц товара", 1)
Cells(N + 4, 3).Value = qw
‘ Вычисление суммы по позиции товара
Cells(N + 4, 4).Value = qw * Cells(N + 4, 2).Value
‘ Подсчет итоговой суммы
Symma.Caption = Str(Val(Symma.Caption) + Cells(N + 4, 4))
End Sub
Здесь используются стандартные функции Visual Basic: Val (для перевода из
тестового вида в числовой) и Str (для перевода информации из числового вида в
текстовый). На рис.2.10 показан результат работы книги в результате проделанных
действий.
Рис.2.10.
Обработку щелчков по кнопкам Пересчет и Очистить мы рассмотрим чуть позже, а
пока займемся третьим листом, который показан на рис. 2.11. Здесь никаких
элементов управления нет — только текст и форматирование ячеек. До десятой
строки третьего листа текст фиксированный – результат ввода и последующего
форматирования данных. Начиная с 11-й строки информация является следствием
выполнения процедуры, которая выполняется по щелчку по кнопке Печать.
Теперь после того как заготовка печатной формы создана, можно перейти к
разработке процедуры, выполняемой по кнопке Печать,
текст которой с
необходимыми пояснениями приводится на листинге 2.7.
Рис.2.11.
Листинг 2.7. Обработка щелчка по кнопке Печать
Private Sub Prn_Click()
Dim Symma As Integer
' Подсчет числа строк с товарами на 3-м листе
N = 0
While Worksheets(3).Cells(N + 11, 1).Value <> ""
N = N + 1
Wend
' Очистка информации с удалением границ
For i = 1 To N
For j = 1 To 5
Worksheets(3).Cells(10 + i, j).Value = ""
Worksheets(3).Cells(10 + i, j).Borders.LineStyle = xlNone
Next
Next
' Очистка итоговой информации
Worksheets(3).Cells(10 + N + 2, 4).Value = ""
Worksheets(3).Cells(10 + N + 2, 5).Value = ""
' Подсчет числа строк с товарами на 1-м листе
N1 = 0
While Cells(N1 + 4, 1).Value <> ""
N1 = N1 + 1
Wend
‘ Переменная Symma для итоговой информации
Symma = 0
‘ Цикл для заполнения 3-го листа
For i = 1 To N1
Worksheets(3).Cells(10 + i, 1).Value = i
Worksheets(3).Cells(10 + i, 2).Value = Cells(i + 3, 1)
Worksheets(3).Cells(10 + i, 3).Value = Cells(i + 3, 2)
Worksheets(3).Cells(10 + i, 4).Value = Cells(i + 3, 3)
Worksheets(3).Cells(10 + i, 5).Value = Cells(i + 3, 4)
Symma = Symma + Cells(i + 3, 4)
‘ Оформление ячейки рамкой
For j = 1 To 5
Worksheets(3).Cells(10 + i, j).Borders.LineStyle = xlContinuous
Next
Next
Worksheets(3).Cells(10 + N1 + 2, 4).Value = "Итого"
Worksheets(3).Cells(10 + N1 + 2, 5).Value = Symma
End Sub
В начале процедуры мы ввели переменную, в которой будем подсчитывать сумму.
Так при выводе нового бланка следуе акуатно удалить имеющуюся информацию.
Ранее мы сказали, что две процедуры (одна по кнопке Очистить, а другая по кнопке
Пересчет), мы оформим позднее.
И вот теперь мы напишем процедуру,
выполняемую по кнопке Очистить (листинг 2.8).
Листинг 2.8. Процедура, выполняемая по кнопке Очистить
Private Sub Clr_Click()
' Подсчет числа заполненных строк на первом листе
N = 0
While Cells(N + 4, 1).Value <> ""
N = N + 1
Wend
Range(Cells(4, 1), Cells(N + 3, 4)).Value = ""
' Сброс суммы
Symma.Caption = "0"
End Sub
Последняя нерассмотренная процедура связана с кнопкой Пересчет (листинг 2.9).
Смысл ее в том, что если мы в бланке заказа произведем изменения (удалим строку
или изменим количество товара), то необходимо пересчитать и итоги.
Листинг 2.9. Процедура, выполняемая по кнопке Пересчет
Private Sub Пересчет_Click()
‘ Подсчет заполненных строк в бланке заказа
N = 0
While Worksheets(1).Cells(N + 3, 1).Value <> ""
N = N + 1
Wend
‘ Пересчет суммы
symma = 0
For i = 3 To N + 2
a = Worksheets(1).Cells(i, 3).Value
Worksheets(1).Cells(i,4).Value = Worksheets(1).Cells(i, 2).Value * a
symma = symma + Worksheets(1).Cells(i, 4).Value
Next
‘ Занесение подсчитанной суммы в надпись
Lbl.Caption = Str(symma)
End Sub
Рабочая книга фактически готова, но мы попробуем ее немного улучшить. Ранее мы
создали необходимую обработку, выполняющуюся при открытии книги — в
процедуре Workbook_Open(). Однако некоторые неудобства связаны с тем, что при
внесении изменений в номенклатуру товаров, они отражаются в элементах Поле со
списком на первом листе только после закрытия и последующего открытия книги.
Чтобы эти изменения сразу же отражались в уже открытой книге, необходимо
оформить соответствующим образом процедуру Worksheet_Activate()—
процедуру, которая выполняется при активизации листа (листинг 2.10).
Листинг 2.10. Процедура, выполняемая при активизации первого листа
Private Sub Worksheet_Activate()
‘ Очистка первого списка
Worksheets(1).Spk.Clear
‘ Подсчет количества записей в прайсе на втором листе
N = 0
While Worksheets(2).Cells(N + 1, 1).Value <> ""
N = N + 1
Wend
‘ Заполнение списка
For i = 1 To N
a = Worksheets(2).Cells(i, 1).Value & "
" & _
Worksheets(2).Cells(i, 2).Value & " руб."
Worksheets(1).Spk.AddItem a
Next
‘ Установка нуля в поле для суммы
Worksheets(1).Lbl.Caption = "0"
End Sub
На рис.2.9 и рис.2.10, соответственно, приведены один из вариантов заполнения
бланка и его печатная форма.
Электронная анкета
Разберем решение еще одной практической ситуации — заполнение электронного
бланка анкеты. Сам разрабатываемый лист будет достаточно насыщен элементами
управления, поэтому здесь мы рассмотрим оформление листа последовательно.
Начнем разработку (рис.2.12) с небольших деталей. Так, заполним три ячейки в
столбце B поясняющей информацией, а для трех ячеек в столбце C необходимо
лишь подобрать соответствующее форматирование — заливку и размер шрифта. В
дальнейшем в процессе работы с этим бланком пользователь будет вносить в ячейку
C2 фамилию, в C4 — имя, а в C6 — отчество. Теперь, как и ранее, уберем сетку с
рабочего листа.
Рис.2.12.
На рис.2.12 в правой части расположена группа элементов управления. Здесь
появился новый элемент — Переключатель, который позволяет обеспечить два
состояния — “Включено” и “Выключено”. Идея использования двух подобных
элементов на нашем листе достаточно простая. А именно, человек, который
заполняет бланк, указывает (щелчком по одному из переключателей) один из двух
вариантов:
 Н. Новгород;
 Другой город.
В случае выбора варианта Другой город следует указать, какой именно. Понятно,
что рассматривается ситуация, когда большинство людей, заполняющих бланк,
проживает в Нижнем Новгороде.
Зададим значения свойства Name элементов на рис.2.12 следующим образом:
 Opt1 (переключатель Н.Новгород);
 Opt2 (переключатель Другой город);
 City (текстовое окно для ввода названия города).
В начальном варианте (при открытии книги для заполнения анкеты) по умолчанию
установлен вариант — Н.Новгород (это выполним далее с помощью программной
установки для свойства Value значения True). При этом текстовое окно для выбора
города невидимо. Для этого у свойства видимости Visible объекта City
необходимо установить значение False (далее это мы также сделаем программно).
При щелчке на переключателе Другой город текстовое окно City становится
видимым, а при щелчке по переключателю с подписью Н.Новгород, опять
пропадает. Сами тексты процедур обработки щелчков по переключателям
приведены на листинге 2.11.
Листинг 2.11. Процедуры обработки щелчков по переключателям для выбора города
Private Sub Opt1_Click()
City.Visible = False
End Sub
Private Sub Opt2_Click()
City.Visible = True
End Sub
Подчеркнем один важный технический момент. Мы расположили два
переключателя, которые связаны друг с другом. При щелчке на одном из них,
значение свойства Value другого автоматически становится False. Далее на нашем
рабочем листе мы расположим еще одну группу переключателей, которая фиксирует
категорию анкетируемого (учащийся или специалист). Для того чтобы эти группы
переключателей правильно работали, необходимо подчеркнуть, какие из них к какой
группе относятся. Для этого необходимо значение свойства
GroupName для
переключателей, связанных с городами, сделать одинаковым (например, можно
выбрать Op_city). Для других переключателей значение данного свойства должно
быть другим.
Теперь можно выйти из режима конструктора, проверить работу написанных
процедур, а затем продолжить создание рассматриваемой разработки. На рис.2.13
показана следующая группа элементов, которые нам необходимо добавить на том
же рабочем листе.
Рис.2.13.
В верхней левой части на рис.2.13 сосредоточены элементы, которые заполняются
при условии, если анкетируемый является студентом. Соответственно правая часть –
для лиц уже имеющих диплом. При этом фрагменты Место учебы, Курс, Место
работы и Примечание являются просто надписями. Они введены для пояснения
содержимого соседних (справа относительно них) текстовых окон. Т.к. они
программно они не используются, то имена этих объектов мы не приводим.
Два переключателя Студент (Name — St) и Специалист (Name — Sp) относятся к
общей группе переключателей, отличной от группы переключателей используемых
для выбора городов. Теперь поясним, как они будут использоваться.
Так при выборе категории Студент, видимыми становятся текстовые окна для
заполнения полей анкеты Место учебы (Name — Place) и Курс (Name — Kyrs), а
текстовые окна для заполнения полей Место работы (Name — Work) и Примечание
(Name — Prim) становятся невидимыми. Соответственно, при выборе категории
Специалист, все наоборот — видимыми становятся текстовые окна, которые
должен заполнить специалист.
В нижней части листа на рис.2.12 располагаются три флажка (на панели
инструментов Элементы управления пиктограмма подобного элемента управления
четвертая слева). Имена этих объектов выберем соответственно (сверху вниз) Eng,
Auto и Info. Основное используемое свойство флажка — Value, которое принимает
два возможных значения False и True.
Таким образом, мы рассмотрели функциональное назначение элементов на листе
электронной анкеты. Теперь перейдем к процедурам. Как уже говорилось при
открытии книги по умолчанию необходимо сделать выбор на Н.Новгород и на
заполнение анкеты студентом. Это лучше реализовать в процедуре Workbook_Open
(листинг. 2.12).
Листинг 2.12. Процедура, выполняемая при открытии книги
Private Sub Workbook_Open()
Worksheets(1).Opt1.Value = True
Worksheets(1).Opt2.Value = False
Worksheets(1).City.Visible = False
Worksheets(1).St.Value = True
Worksheets(1).Place.Visible = True
Worksheets(1).Place.Text = " "
Worksheets(1).Kyrs.Visible = True
‘ По умолчанию рассматривается студент первого курса
Worksheets(1).Kyrs.Text = "1 "
Worksheets(1).Work.Visible = False
Worksheets(1).Work.Text = " "
Worksheets(1).Prim.Visible = False
Worksheets(1).Prim.Text = " "
Worksheets(1).Eng.Value = False
Worksheets(1).Auto.Value = False
Worksheets(1).Info.Value = False
End Sub
В результате мы обеспечили автоматическую установку начальных значений при
открытии книги. Словами действие переключателей
St и Sp мы уже
прокомментировали, а теперь необходимо привести программные процедуры
обработки щелчков по ним.
Листинг 2.13. Процедуры, выполняемые по щелчкам по переключателям Sp и St
Private Sub St_Click()
Place.Visible = True
Kyrs.Visible = True
Work.Visible = False
Prim.Visible = False
End Sub
Private Sub Sp_Click()
Place.Visible = False
Kyrs.Visible = False
Work.Visible = True
Prim.Visible = True
End Sub
Таким образом, мы обеспечили необходимый интерфейс ввода информации на
первый рабочий лист.
Рис.2.14.
Далее будем считать, что информацию с первого листа следует записать в базу
данных — на второй лист (рис.2.13). Здесь для данных по каждому анкетируемому
отводится по одной строке. И по щелчку по кнопке Записать на 2-й лист
информация анкеты переписывается в очередную свободную строку второго листа.
На листинге 2.13, приводится текст данной процедуры. Как вы уже заметили, из
названия процедуры следует, что для свойства Name кнопки установлено значение
WriteList2.
Рис.2.13.
Листинг 2.14. Процедура, выполняемая по щелчку по кнопке Записать на 2-й лист
Private Sub WriteList2_Click()
‘ Подсчет количества имеющихся записей на втором листе
N = 0
While Worksheets(2).Cells(N + 2, 1).Value <> ""
N = N + 1
Wend
‘ Запись порядкового номера в первый столбец
Worksheets(2).Cells(N + 2, 1).Value = N + 1
‘ Копирование фамилии, имени и отчества
Worksheets(2).Cells(N + 2, 2).Value = Range("c2")
Worksheets(2).Cells(N + 2, 3).Value = Range("c4")
Worksheets(2).Cells(N + 2, 4).Value = Range("c6")
‘ Название города располагается в пятой колонке на втором листе
If Opt1.Value = True Then
Worksheets(2).Cells(N + 2, 5).Value = "Н.Новгород"
Else
Worksheets(2).Cells(N + 2, 5).Value = City.Text
End If
‘ Статус в шестой колонке, место работы или
‘
учебы в седьмой, а
примечание в восьмой колонке.
If St.Value = True Then
Worksheets(2).Cells(N + 2, 6).Value = "студент"
Worksheets(2).Cells(N + 2, 7).Value = Place.Text + _
",
курс - " + Kyrs.Text
Else
Worksheets(2).Cells(N + 2, 6).Value = "спец. с в/о"
Worksheets(2).Cells(N + 2, 7).Value = Work.Text
Worksheets(2).Cells(N + 2, 8).Value = Prim.Text
End If
‘ Характеристики, определяемые флагами
If Eng.Value = True Then
Worksheets(2).Cells(N + 2, 9).Value = "Да"
Else
Worksheets(2).Cells(N + 2, 9).Value = "Нет"
End If
If Auto.Value = True Then
Worksheets(2).Cells(N + 2, 10).Value = "Да"
Else
Worksheets(2).Cells(N + 2, 10).Value = "Нет"
End If
If Info.Value = True Then
Worksheets(2).Cells(N + 2, 11).Value = "Да"
Else
Worksheets(2).Cells(N + 2, 11).Value = "Нет"
End If
End Sub
Теперь все процедуры готовы,
анкетой.
и
можно поработать с созданной электронной
Понятно, что данная разработка не включает многие детали, которые в каждой
практической ситуации накладывают свои требования. Однако в этой главе и не
ставилась цель создать что-то универсальное. Гораздо важнее на рассмотренных
примерах получить навыки, необходимые
для выполнения самостоятельных
разработок.
В следующей главе для того, чтобы познакомиться с конструкциями самого языка
программирования, мы разберем примеры, которые отличаются большей
алгоритмизацией по сравнению разработками первой и второй глав.
Download