Введение в программирование на примере VBA
Часть III. Создание объекта на основе класса
Занятие 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. Поэтому объект таймера будет чисто программным и к форме (и визуальному проектированию) не будет иметь отношения. Создадим визуальную часть приложения – и на этом закончим первый «виток» разработки. РеализацияПерейдем к визуальному построению будущего приложения.
В составе проекта появится объект UserForm1 – Пользовательская Форма 1.
Появится окно визуального редактирования формы и окно Toolbox, содержащее набор стандартных элементов управления VBA. Не откладывая в долгий ящик, следует присвоить полученным объектам имена.
В этом окне появятся свойства выбранного объекта. Для проекта VBA доступно лишь одно свойство – имя.
О правилах именования объектов VBA было сказано раньше.
Содержимое окна Properties изменится, теперь это окно отображает свойства формы:
Строка со словом (Name) обозначает имя формы.
Если помните, это – frmMain.
Заметьте, что в окне Project Explorer произойдут соответствующие изменения. Сохраните книгу Excel, содержащую наш проект.
Появится диалоговое окно с предложением выбрать каталог для сохранения файла. Здесь же вы можете назначить имя файлу.
Займемся визуальным редактированием приложения.
Должен появиться элемент управления Image:
Форма должна приобрести такой вид:
Для изменения размеров:
Для перемещения контрола следует:
В дальнейшем не будет напоминаний о том, что следует сохранить проект. Помните об этом сами, выполняйте сохранение каждый раз после внесения в проект каких-то значимых изменений. Следующим этапом будет присвоение контролам имен – определенных нам на этапе проектирования визуального интерфейса. Для этого следует:
Присвойте имена:
У вас не должно вызывать удивления то, что после изменения имени не изменяется надпись на заготовках объектов в окне визуального редактирования. Вспомните, что надписи соответствуют свойствам Caption и подобным, но не Name. Работа с нестандартными контролами Следующее, что мы сделаем – добавим в состав проекта элемент управления, не входящий в стандартный набор VBA.
Появится контекстное меню:
Нас интересует пункт Дополнительные Контролы. –
Появится окно, отображающее список всех элементов управления, установленных на вашем компьютере и доступных к применению в проектах VBA. Конечно, список, появившийся у вас, может отличаться от приведенного на рисунке:
В списке вы видите перечень контролов вашего компьютера. В левой части списка – «флажки», устанавливая которые, вы даете указание VBA включить контрол в проект. Ниже, под списком, вы видите название контрола и указание его расположения в вашей системе. Флажок Только Выбранные Сущности – преобразует список так, что будут видны только объекты, уже отмеченные, то есть – включенные в состав проекта. Это удобно тогда, когда вы хотите удалить контрол из состава проекта. –
Вот как это может выглядеть:
В данном случае на компьютере установлены версия компонента: .Результаты поиска в вашем случае могут немного отличаться.
Обратите внимание, что можно выбрать сразу несколько элементов управления для добавления в проект, устанавливая соответствующие флажки. Окно выбора контролов исчезнет. Взгляните на окно Toolbox:
В нем появился новый компонент. Добавим этот контрол в форму. Действия по добавлению «невидимого» элемента совершенно аналогичны действиям, которые вы производили при работе с «обычными» контролами, с одним отличием – не имеет значения, где именно на форме вы поместите элемент управления, и нет надобности обращать внимание на его размеры. Давайте сделаем это.
Вы можете разместить «невидимый» контрол даже поверх другого, «видимого». На внешнем виде программы это никак не отразится. Обратите внимание, что ваши попытки изменить размеры контрола окажутся безуспешны. Это характерно для «невидимых» контролов. Сразу остановимся на действии, обратном добавлению компонента. Попробуем удалить контрол ImageList из состава проекта.
Подсказка. Здесь может оказаться полезным установка флажка . Попробуйте установить этот флажок, обратите внимание на то, как изменится список компонентов.
Это может выглядеть так:
Не забудьте, что надпись в вашем случае может немного отличаться от приведенной – все зависит от того, какие именно компоненты входят в состав вашей системы.
Как видите, после закрытия окна Additional Controls с панели Toolbox исчез значок дополнительного компонента. Но на форме добавленный элемент остался. Поэтому для полной «очистки» проекта следует удалить добавленные компоненты с форм, входящих в состав приложения. Для этого перенесите фокус на нужный контрол (например, щелкните на нем) и нажмите [Del]. Язык VB, в отличие от VBA, не позволяет исключить добавленный контрол из окна Additional Controls до тех пор, пока элемент не будет удален со всех форм проекта (то есть, куда он был помещен). Возможно, некоторые версии VBA будут вести себя так же, имейте это в виду. Страницы свойств Вернемся к нашему проекту.
Как мы определили ранее, имя – imglistMain. Изменять имена компонентов вы уже умеете. Обратите внимание, что в окне Properties над строкой со свойством Name появились две строки – About (О [компоненте]) и Custom – Настройка:
В вашем конкретном случае строки About может и не быть.
Кнопка на строке About выведет окошко, коротко описывающее компонент. Это имеет лишь информационное значение и нам не нужно. Мы будем работать с диалоговым окном, появляющимся при нажатии кнопки на строке Custom.
Возникнет диалоговое окно:
В вашем случае оно может выглядеть немного иначе, сохраняя свои функции. Заголовок окна – PropertyPages – Страницы Свойств. Подобные окна дополняют некоторые элементы управления, предоставляя широкие возможности для настройки. Как вы увидите, выполнить аналогичные действия при помощи окна Properties было бы затруднительно. В нашем случае окно Property Pages имеет три вкладки – – Общие, – Образы и . На вкладке обычно располагаются некие свойства, характеризующие элемент управления в общем. Для компонента ImageList «общими» свойствами являются размеры картинок, которые будут храниться в компоненте. Для задания размеров используется переключатель, предоставляющий на выбор размеры (все размеры – в пикселях, то есть элементарных «точках» экрана), , и – Пользовательский. Для задания пользовательского размера на вкладке имеются два текстовых поля, обозначенных – Высота и – Ширина. Начальные значения размеров нулевые. Вы можете задать любые, помните лишь, что размер должен быть целым числом. Как это будет выглядеть, вы можете определить путем экспериментов. Следует запомнить, что задать размеры вы сможете только до добавления картинок в этот компонент. Если понадобится изменить размеры – придется удалить все картинки, изменить размер и вновь добавить все картинки. Поэтому следует заранее определять нужные размеры. Флажок Использовать Цвет Маски – позволяет использовать маску. В нашем случае это значит, что участки картинки, имеющие цвет, совпадающий с цветом маски, будут прозрачны. Цвет маски можно задать в окне Properties. –К сожалению, кнопка Property Pages в общем случае работать не будет, для этого потребуется установка библиотеки MSDN, распространяемой за плату фирмой Microsoft. на окне
Здесь представлены инструменты для добавления набора картинок.
Появится диалоговое окно для выбора файла картинки из имеющихся на вашем компьютере.
Если у вас нет заранее подготовленных рисунков, не беда. В системном каталоге операционной системы – Windows или Winnt, – обычно есть несколько картинок, предназначенных для украшения рабочего стола.
В вашем случае внешний вид диалогового окна выбора файла картинки, надписи и имена файлов могут отличаться. Следует помнить, что в окне выбора видимы только файлы, допустимые для добавления.
Окно Property Pages изменит вид:
В текстовом поле Индекс, – появилась цифра 1. Это – порядковый номер картинки в наборе. Нумерация начинается с единицы. –Сделались доступны поля для ввода значений Ключ и – Тэг. Обычно свойство используется для дополнительных манипуляций набором картинок. В свойстве , как правило, сохраняются какие-то дополнительные сведения («примечания») к текущему элементу набора. –Сделалась доступна кнопка Удалить Картинку. –В поле Число Образов, – вы видите общее число картинок в наборе. –
Третья вкладка – , – не имеет значения применительно к элементу управления, не отображающемуся при работе приложения. На этой вкладке можно задать цвет контрола.
Визуальный интерфейс готов. Сейчас мы займемся создание кода приложения. Подцикл 2. Создание процедуры вывода картинкиПерейдем к созданию кода приложения. Объединим этот подцикл с тестированием правильности создания визуального интерфейса – напишем код для вывода картинки в элемент управления, что одновременно будет служить проверкой настройки контролов. ПроектированиеДавайте будем выводить картинку по нажатию кнопки cmdStart – тем более что, пока что нет кода, «привязанного» к этому компоненту. Не забудьте, что этот вывод происходит в тестовых целях, в дальнейшем не забудьте изменить код! Реализация
Изучение объекта Image Так как картинка будет выводиться компонентом imgMain, уже помещенном на форму, предположительно, для этого потребуется манипуляция какими-то свойствами компонента imgMain. Начнем с исследования свойств этого контрола. Откроем Object Browser.
Не забудьте, что наш проект называется Multy.
В правой части окна появится список атрибутов выбранного объекта, то есть формы.
Как видите, в нижней части окна Object Browser появилось краткое описание свойства imgMain – не удивляйтесь, для формы frmMain этот компонент является свойством. А именно, мы видим строку объявления: WithEvents imgMain As Image Квалификатор WithEvents (С_Событиями) мы рассмотрим позже. Сейчас же нас интересует тип этого свойства – Image. Это слово на панели Object Browser обозначено гиперссылкой – подчеркнуто, а курсор мыши при перемещении на это слово изменяет форму.
Содержимое Object Browser изменится:
В левом списке появится содержимое какой-то объектной библиотеки, содержащей объект Image (судя по надписи в верхнем списке, это – библиотека MSForms), а на правой панели вы увидите список атрибутов этого объекта. Подобный способ поиска поможет вам найти сведения об объекте даже тогда, если вы не знаете, в какой объектной библиотеке надо его искать. Изучим список атрибутов объекта. В нем легко найти атрибут, отвечающий целям поиска, а именно – свойство Picture – Рисунок:
Далее в списке еще несколько свойств, судя по названию, определяющих способы отображения рисунка. Так как больше ничего подходящего в списке нет, примем найденное свойство за нужное нам. Иногда трудно найти очевидно подходящий атрибут по его названию. Тогда вам придется изучать справку по данному объекту – или экспериментировать. Поиск источника картинки Теперь определим источник данных – а именно, какой атрибут контрола imglistMain будет предоставлять картинку для отображения.
Как видите, список небольшой и в нем нет свойства Picture. Однако мы находим свойство ListImages – СписокОбразов. Это – единственное свойство, наименование которого написано во множественном числе, а мы уже узнали раньше, что множественное число обычно соответствует набору. Компонент ImageList предназначен для хранения набора картинок, более того, при назначении файлов картинок контролу вы видели, что каждому рисунку назначался индекс, являющийся характерным признаком набора. Предположим, что свойство ListImages содержит набор картинок – как это и следует из названия свойства.
Как видите, по сути дела ListImages – обычная коллекция, и работа с этим набором будет происходить аналогично работе с наборами, к примеру, объектов Word. РеализацияДальнейшее изучение этого набора проведем по мере набора кода.
Private Sub cmdStart_Click() Конструирование кода Но такой код еще не будет работать – можете убедиться в этом сами. Дело в том, что в добавленном коде мы пытаемся свойству Picture объекта imgMain присвоить наборListImages. А нам-то надо присвоить тоже объект Picture! Как мы уже предположительно узнали, нужные нам объекты находятся в наборе ListImages. Как мы изучали ранее, синтаксис набора включает индекс, согласно которому происходит обращение к отдельному элементу набора. Попробуем модифицировать код, добавив индекс к объекту ListImages.
Как мы и предполагали, объект ListImages – набор, содержащий объекты типа ListImage (что видно из возникшей подсказки). И для обращения к члену набора следует добавить индекс.
Private Sub
cmdStart_Click() Но и это еще не все. Как вы видели на возникшей подсказке, объект ListImage имеет одноименный тип. А тип свойства Picture другой – можете проверить в Object Browser. Что же делать? Быть может, нужный нам объект выступает свойством объекта ListImage?
Как видите, наши догадки были верны. Действительно, объект ListImage имеет ряд атрибутов, среди которых и нужное нам свойство Picture!
Private Sub
cmdStart_Click() Теперь можно сделать пробный запуск.
Должна появиться картинка:
Код составлен правильно. Обратите внимание, что во время написания кода, использующего незнакомые нам объекты, мы ни разу не обращались к справочной системе – и, тем не менее, хорошо справились с задачей. У вас может возникнуть вопрос – почему мы не воспользовались строкой Picture в окне Properties? Да, в этом окне есть строка, отвечающая за то же свойство Picture объекта Image. Но особенность окна Properties – в нем нельзя программно присвоить значение, как это сделали мы. Назначения в окне Properties производятся привязанно к файлам, а не к контролам. Иными словами, используя окно Properties, вы сможете назначить элементу Image одну картинку, а назначение нескольких рисунков возможно лишь с применением дополнительного контрола – и вспомогательного кода. Теперь самостоятельно продолжите изучение объекта imgMain.
Обратите внимание на строки свойств PictureAlignment – ВыравниваниеРисунка, PictureSizeMode – СпособРазмераРисунка и PictureTiling – МозаичностьРисунков.
Подцикл 3. Циклический вывод картинокСледующий шаг разработки – усложнение созданного кода. Это можно было бы выполнить и на предыдущем шаге, но так будет проще. Помните, что постепенность и простота должны стать вашими принципами. Воспользуемся кодом, который мы написали, и попробуем сделать так, чтобы при очередном нажатии кнопки cmdStart отображалась очередная картинка из набора, а по достижению конца набора отображение начиналось сначала. ПроектированиеСледует сделать единственное исправление в требованиях – исключить упоминание контрола cmdStart. Почему – поймете далее. Мы уже можем строить схему последовательности действий.
Не правда ли, эта конструкция напоминает «развернутый» цикл с индексом, причем по достижении индексом определенной величины отсчет начинается с начала. Только в данном случае цикл производится не автоматически, а «по указанию» извне. Реализация
‘перед началом работы по выводу картинок, Как видите, код почти готов. Следует лишь определиться с <концом набора>. У наборов-коллекций VBA есть свойство, в котором можно прочитать число элементов набора. Это свойство Count – Число, Счет (у массивов такого свойства нет, да массивы обычно и не считаются объектами). Поэтому число элементов набора будет определяться строкой: imglistMain.ListImages.Count
index = 1 Теперь обратите внимание на то, что индекс обнуляется тогда, когда он становится равен числу элементов набора. Иначе говоря, последний элемент набора НЕ БУДЕТ ОТОБРАЖАТЬСЯ!
If index =
imglistMain.ListImages.Count + 1 Then Вариант формулировки условия может быть такой: If index > imglistMain.ListImages.Count Then Выбор за вами, принципиальной разницы нет. Быть может, второй вариант будет чуточку быстрее работать, но первый способ нагляднее. То есть обнуление произойдет тогда, когда будет обработан последний элемент набора и счетчик увеличится, указывая на несуществующий элемент, расположенный «после последнего» члена набора. Еще замечание. В данном приложении не требуется большая производительность, но в общем случае рекомендуется кэшировать строку imglistMain.ListImages.Count + 1 в специальной переменной. Действительно, при работе приложения это значение меняться не будет (мы не предусматриваем случай, когда будут добавляться или удаляться картинки при работающей программе), а VBA будет вычислять это значение каждый раз, когда встретит строку.
index = 1 Код готов. Теперь обратите внимание на то, что данный код, хотя и расположен нами в обработчике события нажатия на кнопку cmdStart, никак не связан с этой кнопкой. Не следует перегружать излишним кодом обработчики событий. Данную последовательность действий можно производить в обработчике любого события. Для этого следует вынести код в процедуру. Во-первых, это сделает программу более структурированной и понятной, а, во-вторых, облегчит нашу дальнейшую работу. Так как в процедуре происходит обращение к элементам управления, код следует поместить в модуле, к которому относятся эти элементы – то есть в коде формы frmMain. Видимость этой процедуры извне формы не нужна, поэтому можно сделать ее Private.
Dim index As Integer
На окне приложения должны циклически выводиться добавленные вами в набор картинки. Настройка IDE VBA Пришла пора обратить внимание на встроенное в VBA средство дополнительной проверки правильности кода.
Появится окно настроек VBA:
Это окно имеет несколько вкладок, на которых вы можете сделать некоторые изменения внешнего вида и поведения IDE VBA. Нас интересует первая вкладка Редактор. –
При этом VBA не перестанет проверять допустимость кода, но вы избавитесь от надоедливых окошек, возникающих каждый раз при ошибке ввода.
С остальными вкладками этого окна вы сможете разобраться самостоятельно. Теперь каждый вновь создаваемый модуль VBA будет иметь в самом начале строку Option Explicit Помещение этой строки в начале модуля заставляет VBA требовать объявления каждой переменной. Но мы и так объявляли все переменные? Да, но, чтобы не смущать незрелые умы, мы умолчали о том, что VBA может работать и с необъявленными заранее (при помощи Dim) переменными. В таком случае переменные будут иметь особый «универсальный» тип Variant (подробнее – в справке VBA). Основной недостаток подобного поведения VBA в том, что программист может ошибиться при вводе имени переменной – а VBA не сообщит об ошибке, но будет считать, что это – новая переменная. При обязательном объявлении переменных такого не произойдет, VBA укажет на ошибку использования необъявленной переменной. Но в уже существующих модулях добавления строки не произойдет, вам придется сделать это самостоятельно.
Теперь при попытке запуска неверного кода вы получите сообщение об ошибке, и IDE VBA укажет вам на неверное слово.
Итак, у нас готова тестовая платформа для создания компонента-таймера, ради которого все и затевалось. Итог занятияСамое важное, что вы получили из пройденного занятия – практическая иллюстрация работы с дополнительными, не входящими в состав VBA компонентами. Подобным способом вы можете «подключать» к своим проектам самые разные контролы и объектные библиотеки. Обратите внимание на важность Property Pages – дополнительного средства управления свойствами компонента во время создания программы. К сожалению, вы столкнулись с проблемой, возникшей из-за недостаточной поставки дополнительных компонентов. Имеется в виду отсутствие справочной системы, охватывающей все дополнительные компоненты. Как вы, возможно, заметили, материал учебника составлен таким способом, чтобы научить вас получать нужную информацию, как можно меньше обращаясь к справке. Экспериментируйте, и вы узнаете даже много такого, что не описано в книгах… Интересный и сложный момент в проектировании приложения в том, что мы отказались от применения объекта интервал, заменив его объектом таймер, хотя именно объект интервал органично выделялся при анализе требований. Дело в том, что из требований можно вывести характеристики предполагаемого объекта интервал, а именно, интервалов будет много – неопределенное количество, и все интервалы для приложения совершенно одинаковы. Нельзя сказать, что какой-то из них – первый, а какой-то – десятый, для работы приложения такая характеристика совершенно не нужна. Значит, важнейший атрибут объекта – имя-идентификатор интервалу не присущ, уникальность интервалу не нужна. Далее, у интервала есть лишь одно свойство – длительность, причем у одного и того же интервала это свойство меняться не может – иначе это будет уже другой интервал. Кроме того, деятельный атрибут наступление интервала невозможно классифицировать ни как метод, ни как событие. Действительно, если наступление интервала есть событие (для интервала!), то он должен как-то реагировать, что абсурдно. Если наступление интервала – метод, то что же этот метод делает? Ведь интервал-то уже наступил! Путаница, не правда ли? Но если заменить этот неудачный псевдообъект на объект таймер – все становится на свои места, можете проанализировать сами. Это – пример сложности, которая может возникнуть при проектировании объектной сферы приложения. При затруднениях анализируйте, подходит ли выделенная сущность под определение объекта, примерно так, как сделано выше. Особое внимание уделяйте множественным сущностям, возникающим и исчезающим в большом количестве в процессе работы приложения, как видите, объект-генератор подобных сущностей снимает проблемы и упрощает программу. Еще и еще раз просмотрите последовательность составления строки по выводу картинки: imgMain.Picture = imglistMain.ListImages(index).Picture Как вы можете убедиться, Object Browser не всегда отображает полный список атрибутов объекта, иногда приходится прибегать к «детективному расследованию» для нахождения искомого. К сожалению, это – недостаток справочной системы IDE VBA, и от него никуда не деться. Правильное проектирование тестовой вначале процедуры вывода картинки по нажатию кнопки позволяет без каких-либо модификаций кода использовать эту процедуру далее, когда вместо управляющей кнопки будет использоваться дополнительный компонент-таймер. Для этого при проектировании вместо упоминания о кнопке как источнике события применяется абстракция. В очередной раз напомним: не стремитесь к излишней конкретизации во время проектирования. Конкретике место во время реализации! Далее, важный шаг – настройка IDE VBA для автоматического создания строки Option Explicit. Почему-то ни одна из версий VB и VBA не использует этой возможности по-умолчанию. приходится включать ее вручную. Совет – всегда пользоваться этой опцией, тогда вскоре вы убедитесь, что, взамен на явное объявление переменных – что делается быстро и легко, вы избавляетесь от неприятной и частой категории ошибок, связанных с опечатками при наборе кода. |