В начало
Статьи
Библиотека
Разное

Вот здесь - новый сайт, заходите немедленно!

kift - Коллекция Интересных Фактов и Теорий

А тут можно поболтать и побухтеть, милости просим:

kift - неизданное

Введение в программирование на примере VBA

Часть III. Создание объекта на основе класса

Аннотация
Предисловие
Часть I. Макрос Word
     1. Проектирование и запись макроса
     2. Разбор макроса
     3. Внесение исправлений
     Итоги
Часть II. Макрос-приложение
     4. Проектирование
     5. Визуальное редактирование
     6. Запуск и остановка
     7. Вывод данных
     8. Выбор ответа
     9. Перемещение по списку
     10. Обратное перемещение
     11. Новая версия
     12. Реализация новой версии
     13. Завершение работы
     Итоги
Часть III. Объект на основе класса
    14. "Основное" приложение
     15. Компонент-таймер
     Итоги
Послесловие

Занятие 14. Строительство «основного» приложения

В ходе этого занятия мы поставим перед собою цель, спроектируем и реализуем приложение, работающего «в паре» с другим компонентом, который создадим позднее.

Цикл 1

Итак, начнем.

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

Постановка задачи

Предположим, что для украшения приложения нам понадобилось разместить на нем мультипликационную заставку.

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

Сформулируем требования.

Требования

Приложение должно выводить мультипликацию.

Немного поясним термин. Мультипликация подразумевает вывод изменяющегося изображения. Не будем заниматься показом готовых видеофайлов, предположим, что изменяющееся изображение на деле есть набор «кадров» – как в обычном кинофильме. Тогда изменение картинки будет представлено выводом очередного кадра по прошествии некоторого интервала времени.

Перефразируем требования.

Приложение должно отображать очередной кадр из набора изображений, делая это по прошествии некоторого временнóго интервала.

Условимся, что слова «кадр», «картинка», «изображение» – равнозначны.

Анализ

Можно приступать к анализу требований.

Выделим объекты и виды деятельности из требований. Вспомните, как это мы делали раньше – существительные обозначают объекты, а глаголы – деятельность.

Объекты:

  • кадр
  • набор изображений
  • временной интервал

Деятельность:

  • вывод изображения

Объект, нужный для работы приложения, но не указанный явно –

  • просмотрщик

Действительно, для того, чтобы увидеть некое изображение, недостаточно иметь файл с этим кадром, нужен какой-то просмотрщик.

Не указанная явно, но важная деятельность –

  • отслеживание временнóго интервала.

И еще один подчиненный вид деятельности, подразумеваемый требованиями –

  • выбор очередного кадра для отображения.

Мы имеем начальный набор объектов, который будет использоваться в приложении и первичный список видов деятельности, которые приложение будет выполнять.

  • Составим схематические изображения.

Так может выглядеть совокупность объектов будущего приложения:

А вот и схема видов деятельности:

Схема видов деятельности также допускает указание зависимостей.

Схема зависимости объектов

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

Для схемы объектов допускается использование «стрелок», иллюстрирующих связи объектов (но не взаимодействие, для этого надо использовать другой вид схемы).

Если вы еще не заметили подвоха – подсказка.

Объекты «приложение», «просмотрщик», «кадр» могут иметь вполне очевидные соответствия в будущей программе.

Объект «набор кадров» также очевиден. С наборами в программировании вы уже знакомы.

Но объект «интервал времени» отнюдь не ясен. VBA не сможет использовать подобный объект. Следует перефразировать схемы так, чтобы эта сущность стала ближе к реалиям языка.

Введение объекта-таймера

Для этого следует ввести понятие объекта, отслеживающего время и оповещающего приложение о наступлении заданного момента. Подобные объекты называются таймерами.

  • Измените схемы, заменив сущность «интервал времени» на объект «таймер».
  • Набор объектов вы сможете изменить сами, это просто.

Приведем для большей ясности измененную схему взаимосвязи объектов:

Казалось бы, незначительное, но, тем не менее, очень важное изменение касается связи объектов «приложение» и «таймер». Как видите, не «приложение» отслеживает время – что тоже возможно, но при этом будет зря использоваться уйма ресурсов компьютера, ваше приложение не сможет сделать больше ничего полезного, – а объект «таймер» выполняет свою функцию и оповещает «приложение» о наступлении нужного момента.

Подобное изменение делает будущую программу соответствующей объектной парадигме. Тем самым «приложение» освобождается от ненужных ему функций. На самом деле, если вы потом захотите, чтобы кадры менялись в зависимости не от времени, а, предположим, от прохождения какого-то процесса (подобное вы могли видеть при установке различных программ), то приспособить программу для этой задачи будет гораздо проще, достаточно будет заменить таймер на другой вид оповещателя.

Проектирование

Перейдем к построению приложения.

Подцикл 1. Создание визуального интерфейса

Начнем работу с создания визуального интерфейса приложения.

Определение субстрата для приложения

Определимся с субстратом. Скажем сразу, что не имеет значения, в каком приложении MS Office вы будете создавать программу, она не будет использовать какие-то специфические особенности компонентов MS Office. Давайте работать в Excel – хотя вы можете применить любое другое приложение MS Office, больших отличий не будет.

Следует определиться с используемыми компонентами.

Очевидно, объект «приложение» будет представлен компонентом UserFormПользовательскойФормой. VBA не дает нам выбора в данном случае.

Объект «просмотрщик» имеется в наборе компонентов VBA. Вспомните краткий обзор, приведенный в предыдущей части книги. Встроенный набор контролов имеет в своем составе элемент управления ImageОбраз, как раз и предназначенный для вывода изображений.

С объектом «набор кадров» сложнее. VBA не содержит такого элемента в базовом наборе. Можно создавать набор изображений программно, это будет работать быстро и даст вам большие возможности манипуляции данными. Но в нашем случае подобные широкие возможности не нужны, а большую производительность VBA не дает в принципе, в связи со своими особенностями.

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

Подскажем сразу, что в поставке дополнительных компонентов есть элемент управления ImageListСписокОбразов, который предназначен для хранения и управления произвольным набором изображений. Как раз то, что нам надо.

Объект «кадр» как таковой реализовать не нужно. Вы увидите, что ImageList прекрасно обходится без этого, непосредственно работая с просмотрщиком- Image.

А вот компонента-таймера нет ни среди стандартных контролов VBA, ни среди дополнительных элементов в обычной поставке MS Office (хотя VB имеет в своем составе таймер). И это хорошо. В учебных целях, конечно.

Мы создадим собственный таймер, попутно ознакомившись с некоторыми важными концепциями.

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

Обычно, если не требуется задание каких-то параметров, для этого используются кнопки- CommandButton.

Проектирование визуального интерфейса

Займемся проектированием визуального интерфейса будущего приложения.

  • Например, так:

  • Теперь на схеме обозначьте виды объектов, используемых приложением, и назначьте имена. Вспомните, как мы делали это раньше.

Имена frmMain и imgMain имеют в составе слово MainГлавный. Рекомендуется так называть главные – или, как здесь, единственные объекты.

Мы не поместили на схему ImageList и таймер. У этих компонентов нет визуального представления, то есть при работе программы они будут невидимы. Управление ими будет производиться программно.

  • Но имена этим объектам все же следует назначить сразу. Поместим их на схему, но немного по-другому:

Такое положение на схеме объекта «набор кадров» напоминает, что используется элемент управления, пусть и невидимый, который при создании приложения будет размещен на форме. Но таймер не будет являться элементом управления. К сожалению, VBA не позволяет создавать новые контролы – для этого следует использовать VB. Поэтому объект таймера будет чисто программным и к форме (и визуальному проектированию) не будет иметь отношения.

Создадим визуальную часть приложения – и на этом закончим первый «виток» разработки.

Реализация

Перейдем к визуальному построению будущего приложения.

  • Запустите Excel.
  • Перейдите в IDE VBA – нажатием [Alt]+[F11].
  • Найдите окно Project Explorer.
  • Если его почему-то нет в IDE – выполните команду меню IDE VBA ViewProject Explorer (ВидНавигатор проекта):

  • В этом окне выполните правый щелчок мышью.
  • В появившемся контекстном меню выберите команду InsertUserForm (ВставитьПользовательскую форму):

В составе проекта появится объект UserForm1Пользовательская Форма 1.

  • Вызовите окно визуального редактирования для новой формы.
  • Проще всего выполнить двойной щелчок на соответствующем пункте в окне Project Explorer.

Появится окно визуального редактирования формы и окно Toolbox, содержащее набор стандартных элементов управления VBA.

Не откладывая в долгий ящик, следует присвоить полученным объектам имена.

  • Перейдите опять в окно Project Explorer.
  • Убедитесь, что в IDE видимо окно Properties. Если нет – выполните команду меню IDE ViewPropertiesWindow (ВидОкно Свойств).
  • Щелкните один раз на строке с именем проекта в окне Project Explorer (сразу после создания VBA назначит проекту имя VBAProject):

  • Перейдите в окно Properties:

В этом окне появятся свойства выбранного объекта. Для проекта VBA доступно лишь одно свойство – имя.

  • Выполните двойной щелчок на слове VBAProject в окне Properties.
  • Введите новое имя, которое далее будет обозначать наш проект. Например, Multy (Мульти[пликация]):

О правилах именования объектов VBA было сказано раньше.

  • Подобным образом переименуйте созданную форму.
  • Щелкните на соответствующей строке в окне Project Explorer, или – выполните щелчок на заготовке формы в окне визуального редактирования.

Содержимое окна Properties изменится, теперь это окно отображает свойства формы:

Строка со словом (Name) обозначает имя формы.

  • Назначьте вместо имени UserForm1 имя, определенное нами ранее, при проектировании визуального интерфейса.

Если помните, это – frmMain.

Заметьте, что в окне Project Explorer произойдут соответствующие изменения.

Сохраните книгу Excel, содержащую наш проект.

  • Выполните команду меню IDE FileSave Книга1 или щелкните на кнопке с изображением дискеты на панели кнопок IDE:

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

  • Сохраните книгу Excel в своем рабочем каталоге (там, где вы легко сможете ее найти). При этом назначьте файлу имя multy.xls.

Займемся визуальным редактированием приложения.

  • Если окно Toolbox перестало быть видимым, щелкните один раз на заготовке формы в окне визуального редактирования.
  • Если не получается – выполните команду меню IDE ViewToolBox.
  • Найдите в окне Toolbox заготовку контрола Image:

  • Щелкните на нем один раз.
  • Не производя щелчков, переместите курсор мыши на заготовку формы.
  • В том месте заготовки формы, где предполагается размещение, к примеру, верхнего левого угла контрола Image, нажмите левую кнопку мыши – и не отпускайте!
  • Переместите курсор в предполагаемое место расположения нижнего правого угла контрола.
  • Отпустите левую кнопку мыши.

Должен появиться элемент управления Image:

  • Таким же способом поместите внизу формы два элемента CommandButton.

Форма должна приобрести такой вид:

  • Если хотите, откорректируйте размеры и положение контролов.

Для изменения размеров:

  • щелкните один раз на элементе управления, вокруг него появятся белые «квадратики»-маркеры – как на правой кнопке на рисунке.
  • поместите курсор мыши на один из маркеров, курсор изменит вид на «двунаправленную» стрелку.
  • нажмите и не отпускайте левую кнопку мыши.
  • переместите курсор в желаемое положение.
  • отпустите левую кнопку мыши.

Для перемещения контрола следует:

  • щелкнуть на нем для появления маркеров.
  • поместить курсор где-нибудь на контроле – не на маркере.
  • перетащить элемент управления при помощи левой кнопки мыши так же, как мы перетаскивали маркер при изменении размеров элемента управления.
  • Сохраните проект.

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

Следующим этапом будет присвоение контролам имен – определенных нам на этапе проектирования визуального интерфейса.

Для этого следует:

  • один раз щелкнуть на контроле – это действие называется «переместить фокус на контрол».
  • в окне Properties изменить строку (Name).

Присвойте имена:

  • элементу ImageimgMain,
  • левой кнопке – cmdStart,
  • правой кнопке – cmdStop.

У вас не должно вызывать удивления то, что после изменения имени не изменяется надпись на заготовках объектов в окне визуального редактирования. Вспомните, что надписи соответствуют свойствам Caption и подобным, но не Name.

Работа с нестандартными контролами

Следующее, что мы сделаем – добавим в состав проекта элемент управления, не входящий в стандартный набор VBA.

  • Чтобы увидеть список контролов, доступных вам, выполните «правый» щелчок на окне Toolbox.

Появится контекстное меню:

Нас интересует пункт Additional Controls... – Дополнительные Контролы.

  • Выберите этот пункт меню.

Появится окно, отображающее список всех элементов управления, установленных на вашем компьютере и доступных к применению в проектах VBA.

Конечно, список, появившийся у вас, может отличаться от приведенного на рисунке:

В списке вы видите перечень контролов вашего компьютера. В левой части списка – «флажки», устанавливая которые, вы даете указание VBA включить контрол в проект. Ниже, под списком, вы видите название контрола и указание его расположения в вашей системе. Флажок Selected Items OnlyТолько Выбранные Сущности – преобразует список так, что будут видны только объекты, уже отмеченные, то есть – включенные в состав проекта. Это удобно тогда, когда вы хотите удалить контрол из состава проекта.

  • Пролистайте список и найдите строку с надписью ImageList.

Вот как это может выглядеть:

В данном случае на компьютере установлены версия компонента: Microsoft ImageList Control 6.0.

Результаты поиска в вашем случае могут немного отличаться.

  • Установите флажок в списке в строке с найденным контролом:

  • Теперь щелкните кнопку OK.

Обратите внимание, что можно выбрать сразу несколько элементов управления для добавления в проект, устанавливая соответствующие флажки.

Окно выбора контролов исчезнет.

Взгляните на окно Toolbox:

В нем появился новый компонент.

Добавим этот контрол в форму.

Действия по добавлению «невидимого» элемента совершенно аналогичны действиям, которые вы производили при работе с «обычными» контролами, с одним отличием – не имеет значения, где именно на форме вы поместите элемент управления, и нет надобности обращать внимание на его размеры.

Давайте сделаем это.

  • Щелкните один раз на значке контрола ImageList, добавленном вами к панели Toolbox.
  • Переместите курсор мыши на заготовку формы (не имеет значения, куда именно).
  • Нажмите левую кнопку мыши и не отпускайте.
  • Переместите курсор (немного, до прорисовки небольшого «квадратика»).
  • Отпустите левую кнопку мыши.

Вы можете разместить «невидимый» контрол даже поверх другого, «видимого». На внешнем виде программы это никак не отразится.

Обратите внимание, что ваши попытки изменить размеры контрола окажутся безуспешны. Это характерно для «невидимых» контролов.

Сразу остановимся на действии, обратном добавлению компонента. Попробуем удалить контрол ImageList из состава проекта.

  • Выполните «правый» щелчок на панели Toolbox и в контекстном меню выберите пункт Additional Controls… (так же, как вы делали раньше при добавлении компонента).
  • Найдите строку, соответствующую контролу ImageList.

Подсказка. Здесь может оказаться полезным установка флажка Selected Items Only. Попробуйте установить этот флажок, обратите внимание на то, как изменится список компонентов.

  • «Снимите» флажок слева от названия компонента.

Это может выглядеть так:

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

  • Щелкните OK.

Как видите, после закрытия окна Additional Controls с панели Toolbox исчез значок дополнительного компонента. Но на форме добавленный элемент остался. Поэтому для полной «очистки» проекта следует удалить добавленные компоненты с форм, входящих в состав приложения. Для этого перенесите фокус на нужный контрол (например, щелкните на нем) и нажмите [Del].

Язык VB, в отличие от VBA, не позволяет исключить добавленный контрол из окна Additional Controls до тех пор, пока элемент не будет удален со всех форм проекта (то есть, куда он был помещен). Возможно, некоторые версии VBA будут вести себя так же, имейте это в виду.

Страницы свойств

Вернемся к нашему проекту.

  • Назначьте имя добавленному компоненту.

Как мы определили ранее, имя – imglistMain.

Изменять имена компонентов вы уже умеете.

Обратите внимание, что в окне Properties над строкой со свойством Name появились две строки – About (О [компоненте]) и CustomНастройка:

В вашем конкретном случае строки About может и не быть.

  • При переходе на соответствующую строку окна Properties в правой части строки появляется «кнопка». Нажмите на нее.

Кнопка на строке About выведет окошко, коротко описывающее компонент. Это имеет лишь информационное значение и нам не нужно.

Мы будем работать с диалоговым окном, появляющимся при нажатии кнопки на строке Custom.

  • Перейдите в окно Properties.
  • Убедитесь, что вы работаете с компонентом ImageList.
  • В окне Properties перейдите на строку Custom.
  • Щелкните на кнопке, появившейся на этой строке.

Возникнет диалоговое окно:

В вашем случае оно может выглядеть немного иначе, сохраняя свои функции.

Заголовок окна – PropertyPagesСтраницы Свойств. Подобные окна дополняют некоторые элементы управления, предоставляя широкие возможности для настройки. Как вы увидите, выполнить аналогичные действия при помощи окна Properties было бы затруднительно.

В нашем случае окно Property Pages имеет три вкладки – GeneralОбщие, ImagesОбразы и Цвет. На вкладке General обычно располагаются некие свойства, характеризующие элемент управления в общем.

Для компонента ImageList «общими» свойствами являются размеры картинок, которые будут храниться в компоненте. Для задания размеров используется переключатель, предоставляющий на выбор размеры 16x16 (все размеры – в пикселях, то есть элементарных «точках» экрана), 32x32, 48x48 и CustomПользовательский. Для задания пользовательского размера на вкладке имеются два текстовых поля, обозначенных HeightВысота и WidthШирина. Начальные значения размеров нулевые. Вы можете задать любые, помните лишь, что размер должен быть целым числом. Как это будет выглядеть, вы можете определить путем экспериментов.

Следует запомнить, что задать размеры вы сможете только до добавления картинок в этот компонент. Если понадобится изменить размеры – придется удалить все картинки, изменить размер и вновь добавить все картинки. Поэтому следует заранее определять нужные размеры.

Флажок Use Mask ColorИспользовать Цвет Маски – позволяет использовать маску. В нашем случае это значит, что участки картинки, имеющие цвет, совпадающий с цветом маски, будут прозрачны. Цвет маски можно задать в окне Properties.

К сожалению, кнопка Справка на окне Property Pages в общем случае работать не будет, для этого потребуется установка библиотеки MSDN, распространяемой за плату фирмой Microsoft.

  • Перейдем на вкладку Images:

Здесь представлены инструменты для добавления набора картинок.

  • Нажмите кнопку Insert Picture…Вставить Картинку.

Появится диалоговое окно для выбора файла картинки из имеющихся на вашем компьютере.

  • Обычной навигацией по файловой системе найдите какой-нибудь подходящий файл.

Если у вас нет заранее подготовленных рисунков, не беда. В системном каталоге операционной системы – Windows или Winnt, – обычно есть несколько картинок, предназначенных для украшения рабочего стола.

  • Найдите один из подходящих файлов, например, так:

В вашем случае внешний вид диалогового окна выбора файла картинки, надписи и имена файлов могут отличаться. Следует помнить, что в окне выбора видимы только файлы, допустимые для добавления.

  • Подтвердите выбор.

Окно Property Pages изменит вид:

В текстовом поле IndexИндекс, – появилась цифра 1. Это – порядковый номер картинки в наборе. Нумерация начинается с единицы.

Сделались доступны поля для ввода значений KeyКлюч и TagТэг. Обычно свойство Key используется для дополнительных манипуляций набором картинок. В свойстве Tag, как правило, сохраняются какие-то дополнительные сведения («примечания») к текущему элементу набора.

Сделалась доступна кнопка Remove PictureУдалить Картинку.

В поле Image CountЧисло Образов, – вы видите общее число картинок в наборе.

  • Добавьте в набор еще две картинки по вашему выбору, хотя, как вы убедитесь, правильное проектирование позволит работать с наборами любой величины.

Третья вкладка – Цвет, – не имеет значения применительно к элементу управления, не отображающемуся при работе приложения. На этой вкладке можно задать цвет контрола.

  • Нажмите кнопку OK на окне Property Pages.

Визуальный интерфейс готов. Сейчас мы займемся создание кода приложения.

Подцикл 2. Создание процедуры вывода картинки

Перейдем к созданию кода приложения. Объединим этот подцикл с тестированием правильности создания визуального интерфейса – напишем код для вывода картинки в элемент управления, что одновременно будет служить проверкой настройки контролов.

Проектирование

Давайте будем выводить картинку по нажатию кнопки cmdStart – тем более что, пока что нет кода, «привязанного» к этому компоненту. Не забудьте, что этот вывод происходит в тестовых целях, в дальнейшем не забудьте изменить код!

Реализация
  • Перейдите в окно кода формы frmMain.
  • Создайте обработчик события cmdStart_Click.

Изучение объекта Image

Так как картинка будет выводиться компонентом imgMain, уже помещенном на форму, предположительно, для этого потребуется манипуляция какими-то свойствами компонента imgMain. Начнем с исследования свойств этого контрола.

Откроем Object Browser.

  • Нажмите [F2].
  • В верхнем списке выберите строку с названием текущего проекта, примерно так:

Не забудьте, что наш проект называется Multy.

  • Щелкните на строке, соответствующей форме frmMain:

В правой части окна появится список атрибутов выбранного объекта, то есть формы.

  • Найдите в этом списке нужный компонент – imgMain:

Как видите, в нижней части окна Object Browser появилось краткое описание свойства imgMain – не удивляйтесь, для формы frmMain этот компонент является свойством.

А именно, мы видим строку объявления:

WithEvents imgMain As Image

Квалификатор WithEvents (С_Событиями) мы рассмотрим позже. Сейчас же нас интересует тип этого свойства – Image. Это слово на панели Object Browser обозначено гиперссылкой – подчеркнуто, а курсор мыши при перемещении на это слово изменяет форму.

  • Щелкните на слове Image на нижней панели окна Object Browser:

Содержимое Object Browser изменится:

В левом списке появится содержимое какой-то объектной библиотеки, содержащей объект Image (судя по надписи в верхнем списке, это – библиотека MSForms), а на правой панели вы увидите список атрибутов этого объекта.

Подобный способ поиска поможет вам найти сведения об объекте даже тогда, если вы не знаете, в какой объектной библиотеке надо его искать.

Изучим список атрибутов объекта. В нем легко найти атрибут, отвечающий целям поиска, а именно – свойство PictureРисунок:

Далее в списке еще несколько свойств, судя по названию, определяющих способы отображения рисунка.

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

Иногда трудно найти очевидно подходящий атрибут по его названию. Тогда вам придется изучать справку по данному объекту – или экспериментировать.

Поиск источника картинки

Теперь определим источник данных – а именно, какой атрибут контрола imglistMain будет предоставлять картинку для отображения.

  • Выполните аналогичные действия для поиска объекта ImageList и получения списка атрибутов:

Как видите, список небольшой и в нем нет свойства Picture. Однако мы находим свойство ListImagesСписокОбразов. Это – единственное свойство, наименование которого написано во множественном числе, а мы уже узнали раньше, что множественное число обычно соответствует набору.

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

Предположим, что свойство ListImages содержит набор картинок – как это и следует из названия свойства.

  • Щелкнув на гиперссылке ListImages в нижней панели Object Browser, мы увидим атрибуты свойства ListImages:

Как видите, по сути дела ListImages – обычная коллекция, и работа с этим набором будет происходить аналогично работе с наборами, к примеру, объектов Word.

Реализация

Дальнейшее изучение этого набора проведем по мере набора кода.

  • В созданную заготовку обработчика события cmdStart_Click внесите код:

Private Sub cmdStart_Click()

imgMain.Picture = imglistMain.ListImages

End Sub

Конструирование кода

Но такой код еще не будет работать – можете убедиться в этом сами. Дело в том, что в добавленном коде мы пытаемся свойству Picture объекта imgMain присвоить наборListImages. А нам-то надо присвоить тоже объект Picture! Как мы уже предположительно узнали, нужные нам объекты находятся в наборе ListImages.

Как мы изучали ранее, синтаксис набора включает индекс, согласно которому происходит обращение к отдельному элементу набора. Попробуем модифицировать код, добавив индекс к объекту ListImages.

  • К введенной строке добавьте открывающую скобку:

Как мы и предполагали, объект ListImages – набор, содержащий объекты типа ListImage (что видно из возникшей подсказки). И для обращения к члену набора следует добавить индекс.

  • Внесите индекс “1” – если помните, при добавлении картинок к контролу нумерация начиналась с единицы.
  • Закройте скобки:

Private Sub cmdStart_Click()

imgMain.Picture = imglistMain.ListImages(1)

End Sub

Но и это еще не все. Как вы видели на возникшей подсказке, объект ListImage имеет одноименный тип. А тип свойства Picture другой – можете проверить в Object Browser. Что же делать?

Быть может, нужный нам объект выступает свойством объекта ListImage?

  • Для проверки вспомните синтаксис обращения к свойству. Да, к коду следует добавить точку:

Как видите, наши догадки были верны. Действительно, объект ListImage  имеет ряд атрибутов, среди которых и нужное нам свойство Picture!

  • Дополните код:

Private Sub cmdStart_Click()

imgMain.Picture = imglistMain.ListImages(1).Picture

End Sub

Теперь можно сделать пробный запуск.

  • Выполните запуск созданного приложения.
  • Щелкните по кнопке cmdStart.

Должна появиться картинка:

Код составлен правильно.

Обратите внимание, что во время написания кода, использующего незнакомые нам объекты, мы ни разу не обращались к справочной системе – и, тем не менее, хорошо справились с задачей.

У вас может возникнуть вопрос – почему мы не воспользовались строкой Picture в окне Properties?

Да, в этом окне есть строка, отвечающая за то же свойство Picture объекта Image. Но особенность окна Properties – в нем нельзя программно присвоить значение, как это сделали мы. Назначения в окне Properties производятся привязанно к файлам, а не к контролам. Иными словами, используя окно Properties, вы сможете назначить элементу Image одну картинку, а назначение нескольких рисунков возможно лишь с применением дополнительного контрола – и вспомогательного кода.

Теперь самостоятельно продолжите изучение объекта imgMain.

  • Перейдите в окно визуального редактирования формы frmMain.
  • Перенесите фокус на контрол imgMain – можно один раз щелкнуть на нем.
  • Перейдите в окно Properties.

Обратите внимание на строки свойств PictureAlignmentВыравниваниеРисунка, PictureSizeModeСпособРазмераРисунка и PictureTilingМозаичностьРисунков.

  • Изменяйте эти свойства путем выбора значений в списках, появляющихся в правой части окна Properties, после чего производите запуск программы и наблюдайте результат.
  • Следующее свойство SpecialEffectСпециальныйЭффект – относится к самому контролу, изменяя его внешний вид. Поэкспериментируйте и с этим свойством.
  • Приведите вид приложения к желательному для вас – но не забывайте об удобстве пользователя.

Подцикл 3. Циклический вывод картинок

Следующий шаг разработки – усложнение созданного кода. Это можно было бы выполнить и на предыдущем шаге, но так будет проще. Помните, что постепенность и простота должны стать вашими принципами.

Воспользуемся кодом, который мы написали, и попробуем сделать так, чтобы при очередном нажатии кнопки cmdStart отображалась очередная картинка из набора, а по достижению конца набора отображение начиналось сначала.

Проектирование

Следует сделать единственное исправление в требованиях – исключить упоминание контрола cmdStart. Почему – поймете далее.

Мы уже можем строить схему последовательности действий.

  • Эта схема будет выглядеть примерно так:

Не правда ли, эта конструкция напоминает «развернутый» цикл с индексом, причем по достижении индексом определенной величины отсчет начинается с начала. Только в данном случае цикл производится не автоматически, а «по указанию» извне.

Реализация
  • Запишем эту схему в псевдокоде:

‘перед началом работы по выводу картинок,
‘к примеру, при запуске программы
index = 1

cmdStart_Click() ‘при нажатии кнопки «Старт»

‘отображение картинки с номером index:
imgMain.Picture = imglistMain.ListImages(index).Picture

‘увеличение счетчика
index = index + 1

‘проверка достижения конца набора
If index = <конец набора> Then
     ‘сброс счетчика
     index = 1
End If

Как видите, код почти готов. Следует лишь определиться с <концом набора>.

У наборов-коллекций VBA есть свойство, в котором можно прочитать число элементов набора. Это свойство CountЧисло, Счет (у массивов такого свойства нет, да массивы обычно и не считаются объектами).

Поэтому число элементов набора будет определяться строкой:

imglistMain.ListImages.Count

  • Мы вправе изменить код:

index = 1

cmdStart_Click()

imgMain.Picture = imglistMain.ListImages(index).Picture

index = index + 1

If index = imglistMain.ListImages.Count Then
     index = 1
End If

Теперь обратите внимание на то, что индекс обнуляется тогда, когда он становится равен числу элементов набора.

Иначе говоря, последний элемент набора НЕ БУДЕТ ОТОБРАЖАТЬСЯ!

  • Для исправления этой ошибки следует сделать так:

If index = imglistMain.ListImages.Count + 1 Then
     index = 1
End If

Вариант формулировки условия может быть такой:

If index > imglistMain.ListImages.Count Then

Выбор за вами, принципиальной разницы нет. Быть может, второй вариант будет чуточку быстрее работать, но первый способ нагляднее.

То есть обнуление произойдет тогда, когда будет обработан последний элемент набора и счетчик увеличится, указывая на несуществующий элемент, расположенный  «после последнего» члена набора.

Еще замечание. В данном приложении не требуется большая производительность, но в общем случае рекомендуется кэшировать строку

imglistMain.ListImages.Count + 1

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

  • Имеет смысл сделать так:

index = 1
intPicturesCount = imglistMain.ListImages.Count + 1

cmdStart_Click()

imgMain.Picture = imglistMain.ListImages(index).Picture

index = index + 1

If index = intPicturesCount Then
     index = 1
End If

Код готов.

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

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

Так как в процедуре происходит обращение к элементам управления, код следует поместить в модуле, к которому относятся эти элементы – то есть в коде формы frmMain. Видимость этой процедуры извне формы не нужна, поэтому можно сделать ее Private.

  • Изменим код формы так:

Dim index As Integer
Dim intPicturesCount As Integer

Private Sub cmdStart_Click()
DisplayPicture
End Sub

Private Sub UserForm_Initialize()
index = 1
intPicturesCount = imglistMain.ListImages.Count + 1
End Sub

Private Sub DisplayPicture()
imgMain.Picture = imglistMain.ListImages(index).Picture

index = index + 1

If index = intPicturesCount Then
index = 1
End If

End Sub

  • Сделайте пробный запуск, нажмите несколько раз на кнопку cmdStart.

На окне приложения должны циклически выводиться добавленные вами в набор картинки.

Настройка IDE VBA

Пришла пора обратить внимание на встроенное в VBA средство дополнительной проверки правильности кода.

  • Выполните команду меню IDE VBA ToolsOptions… (ИнструментыНастройки…).

Появится окно настроек VBA:

Это окно имеет несколько вкладок, на которых вы можете сделать некоторые изменения внешнего вида и поведения IDE VBA.

Нас интересует первая вкладка EditorРедактор.

  • Раз уж мы заглянули сюда – сбросьте флажок Auto Syntax CheckАвтоПроверка Синтаксиса.

При этом VBA не перестанет проверять допустимость кода, но вы избавитесь от надоедливых окошек, возникающих каждый раз при ошибке ввода.

  • Установите флажок Require Variable DeclarationТребовать Объявления Переменных.

  • Щелкните OK.

С остальными вкладками этого окна вы сможете разобраться самостоятельно.

Теперь каждый вновь создаваемый модуль VBA будет иметь в самом начале строку

Option Explicit

Помещение этой строки в начале модуля заставляет VBA требовать объявления каждой переменной.

Но мы и так объявляли все переменные? Да, но, чтобы не смущать незрелые умы, мы умолчали о том, что VBA может работать и с необъявленными заранее (при помощи Dim) переменными. В таком случае переменные будут иметь особый «универсальный» тип Variant (подробнее – в справке VBA).

Основной недостаток подобного поведения VBA в том, что программист может ошибиться при вводе имени переменной – а VBA не сообщит об ошибке, но будет считать, что это – новая переменная. При обязательном объявлении переменных такого не произойдет, VBA укажет на ошибку использования необъявленной переменной.

Но в уже существующих модулях добавления строки не произойдет, вам придется сделать это самостоятельно.

  • Перейдите в самое начало кода формы и добавьте приведенную выше строку:

Теперь при попытке запуска неверного кода вы получите сообщение об ошибке, и IDE VBA укажет вам на неверное слово.

  • Внесите комментарии в созданный код.
  • Не забудьте, что обработчик события нажатия на кнопки cmdStart – пока что «тестовый», мы будем его коренным образом менять. Можно отметить это в комментариях.

Итак, у нас готова тестовая платформа для создания компонента-таймера, ради которого все и затевалось.

Итог занятия

Самое важное, что вы получили из пройденного занятия – практическая иллюстрация работы с дополнительными, не входящими в состав VBA компонентами. Подобным способом вы можете «подключать» к своим проектам самые разные контролы и объектные библиотеки.

Обратите внимание на важность Property Pages – дополнительного средства управления свойствами компонента во время создания программы.

К сожалению, вы столкнулись с проблемой, возникшей из-за недостаточной поставки дополнительных компонентов. Имеется в виду отсутствие справочной системы, охватывающей все дополнительные компоненты. Как вы, возможно, заметили, материал учебника составлен таким способом, чтобы научить вас получать нужную информацию, как можно меньше обращаясь к справке. Экспериментируйте, и вы узнаете даже много такого, что не описано в книгах…

Интересный и сложный момент в проектировании приложения в том, что мы отказались от применения объекта интервал, заменив его объектом таймер, хотя именно объект интервал органично выделялся при анализе требований.

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

Далее, у интервала есть лишь одно свойство – длительность, причем у одного и того же интервала это свойство меняться не может – иначе это будет уже другой интервал. Кроме того, деятельный атрибут наступление интервала невозможно классифицировать ни как метод, ни как событие. Действительно, если наступление интервала есть событие (для интервала!), то он должен как-то реагировать, что абсурдно. Если наступление интервала – метод, то что же этот метод делает? Ведь интервал-то уже наступил!

Путаница, не правда ли? Но если заменить этот неудачный псевдообъект на объект таймер – все становится на свои места, можете проанализировать сами.

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

Еще и еще раз просмотрите последовательность составления строки по выводу картинки:

imgMain.Picture = imglistMain.ListImages(index).Picture

Как вы можете убедиться, Object Browser не всегда отображает полный список атрибутов объекта, иногда приходится прибегать к «детективному расследованию» для нахождения искомого. К сожалению, это – недостаток справочной системы IDE VBA, и от него никуда не деться.

Правильное проектирование тестовой вначале процедуры вывода картинки по нажатию кнопки позволяет без каких-либо модификаций кода использовать эту процедуру далее, когда вместо управляющей кнопки будет использоваться дополнительный компонент-таймер. Для этого при проектировании вместо упоминания о кнопке как источнике события применяется абстракция.

В очередной раз напомним: не стремитесь к излишней конкретизации во время проектирования. Конкретике место во время реализации!

Далее, важный шаг – настройка IDE VBA для автоматического создания строки Option Explicit. Почему-то ни одна из версий VB и VBA не использует этой возможности по-умолчанию. приходится включать ее вручную. Совет – всегда пользоваться этой опцией, тогда вскоре вы убедитесь, что, взамен на явное объявление переменных – что делается быстро и легко, вы избавляетесь от неприятной и частой категории ошибок, связанных с опечатками при наборе кода.

Hosted by uCoz