Введение в программирование на примере VBA
Часть II. Создание макроса-приложения
Занятие 9. Перемещение по списку вопросовЦель занятия – продолжить «наполнение» приложения кодом для придания требуемой функциональности. Подцикл 5. Переход на следующий вопрос в списке вопросовЗадача этого подцикла – обеспечение перехода на следующий вопрос в списке вопросов. Эта задача очевидно сочетается с обновлением как выводимых вопросов, так и наборов ответов на них. Кроме того, следует предусмотреть случай, когда делается попытка перейти на «следующий» вопрос, находясь на последнем вопросе в наборе. Коррекция кода процедур чтения данных и стартовойРанее мы уже занимались чтением данных, относящихся к первому вопросу. Чтение любого вопроса будет происходить аналогично. Вспомним код, созданный для того, чтобы прочитать первый вопрос: Public Sub
RecordRead() Взгляните на то, как производится адресация ячеек таблицы Excel, к примеру, как мы находим текст вопроса: shtCurrent.Cells(1, 1).Text Синтаксис адреса ячеек, как говорилось выше: Cells(<ряд>, <колонка>) Значение <колонка> в нашем примере фиксировано, изменяться от вопроса к вопросу будет значение <ряд>. Самое место применить переменную для хранения значения <ряд>, назовем ее rw (от row – Ряд). Изменив код таким образом: .txtQuestion.Text =
shtCurrent.Cells(rw, 1).Text мы сможем прочитать данные любого вопроса, номер вопроса должен быть в переменной rw (пока – такое кодовое обозначение). Как же передать значение переменной в процедуру? А очень просто, мы уже разбирали, что для этого используются параметры.
Public Sub RecordRead (intRow As
Integer) Здесь параметр intRow будет передавать в процедуру номер вопроса, который следует прочитать и предоставить пользователю. Как хорошо, что мы выделили это действие в отдельную процедуру! Оказывается, вызывать ее придется не только при запуске приложения, но и при переходе на другой вопрос. Тем самым экономится код и упрощается работа. Но не все так просто, как кажется. Решив одну задачу, мы сталкиваемся с двумя дополнительными – к счастью, они легко решаемы. Во-первых, не забудьте изменить код запуска приложения так, чтобы происходило считывание первого вопроса.
Public Sub StartTest() Эта строка в листинге выделена.
IDE VBA тут же предоставит подсказку о требуемых параметрах этой процедуры:
Как видите, IDE VBA уже восприняло сделанные вами изменения кода. Следует передать значение аргумента процедуре.
Public Sub
StartTest() Да, мы всего лишь добавили единицу после слова RecordRead – но ведь и требуется чтение данных первого вопроса, не так ли?
Не должно быть отличий от предыдущих запусков.
Со второй проблемой мы столкнемся позже, она связана с ошибкой проектирования, которую мы допустили ранее (в учебных целях). Теперь реализуем переход на следующий вопрос по нажатию кнопки cmdNext. Уже формулировка задачи отсылает нас к обработчику события Click для этой кнопки. Уточним задание: при нажатии этой кнопки должен происходить переход на следующий вопрос и обновление списка ответов. Иными словами, мы будем производить вызов процедуры RecordRead с другим значением параметра. А именно – значение будет на 1 больше, чем в предыдущий раз. Не правда ли, мы пришли к потребности ввести хранилище для номера текущего вопроса, причем это хранилище должно сохранять свое содержимое все время работы приложения. Для этого используем переменную. Так как она должна существовать долго, объявим ее там же, где мы объявляли переменную для хранения ссылки на лист Excel.
Public intCurrentRecord As Integer Переменная объявлена как Public потому, что будет производиться обращение к ней из обработчика события нажатия кнопки. А обработчики событий находятся в коде формы, но не модуля, поэтому для возможности доступа к переменной в модуле она и объявлена публичной. Также возможно использование свойства, но особой надобности в этом здесь нет. Выбор за вами, в учебнике мы будем использовать переменную. Для начала использования переменной следует присвоить начальное значение, по всей видимости, это будет значение «1». Если вы хотите всегда начинать тест с другого вопроса – это возможно, и вы уже знаете, как это сделать. Момент, когда следует впервые назначать значения общим переменным, мы уже находили.
Public Sub StartTest() В листинге выделены измененные строки кода. Как видите, в начале процедуры мы назначаем переменной значение. А первый вызов процедуры RecordRead происходит не с явным указанием номера вопроса, а с использованием переменной. Хотя можно оставить и как было: RecordRead 1 Тогда вы создадите себе лишний повод для путаницы – если переменная intCurrentRecord предназначена для хранения номера записи, но она не передается RecordRead, то для чего же она? Такое затруднение обязательно будет возникать. Поэтому давайте делать все строго и последовательно. Уже можно приступать к обработчику события щелчка на кнопку.
Private Sub
cmdNext_Click() Да-да, мы недавно работали с этим обработчиком, проверяя работу переключателей.
Private Sub cmdNext_Click() Как видите, добавлены две строки. Сначала мы увеличиваем значение счетчика записей на единицу, а затем вызываем процедуру чтения данных.
Сперва появится окошко сообщения (если вы не выбрали переключатель, на нем будет 0), а затем – список ответов изменится, а текст вопроса вообще исчезнет. Отладка. Пересчет номера вопроса в номер строкиИ вот – вторая проблема, о которой вы были предупреждены недавно. Мы с вами допустили ошибку, предположив, что достаточно будет перейти в хранилище данных на одну строку, тогда как надо перейти на один вопрос. Если взглянуть на структуру данных таблицы Excel, будет понятно, что переход на один вопрос равносилен переходу на 3 строки. Именно для того, чтобы научить вас справляться с такими ситуациями, структура данных была оставлена как есть. Проще разместить все данные в одну строку – тогда данной проблемы не было бы, но вы не получили бы урок. Методически верным будет создать некую сущность, обозначающую число строк в одном вопросе и использовать ее. Действительно, во-первых, переход, возможно, будет производиться где-то еще, и применение этой сущности облегчит задачу. Во-вторых, правильно именованная сущность вносит ясность в код, и вам не надо будет ломать голову – откуда же взялась эта тройка? В-третьих, предположим, что вы когда-нибудь переделаете программу так, чтобы обрабатывались не три, а, предположим, пять ответов. Одно дело, когда вам придется просматривать весь код и менять тройки на пятерки, а другое дело, когда достаточно будет одного изменения. Применим константу. Константа – именованное хранилище информации, содержимое которого можно считывать при выполнении программы. Изменять значение константы во время выполнения программы нельзя – этого не позволит сам язык VBA. Значение константе присваивается при создании программы. Синтаксис объявления константы схож с объявлением переменной: Const <имя_константы> [As <тип_константы>] = <значение> Квадратные скобки здесь обозначают необязательность указания типа. Если тип не указан, VBA сам решит, какой тип наиболее подходит для этого <значения> – а мы уже знаем, что его догадки не всегда хороши. К константе также можно применять квалификаторы Public- Private. Если квалификатор не указан, то константа приватная.
Public Const LineCount = 3 Как видите, префикс int мы не использовали. Пусть это отличает константу от переменной. Еще раз напомним, что имена для объектов VBA выбираются произвольно, лишь бы они отвечали общим правилам именования. Посмотрите, как это будет выглядеть:
Public Const LineCount As Integer = 3
В ней как параметр мы принимаем номер ряда, но передаем-то номер записи!
Public Sub RecordRead(intRec As Integer) Строку расчета значения переменной intRow проанализируйте сами. Порядок выполнения подобных сложных формул – такой же, как в обычной алгебре, подробнее – в справке VBA.
Должно появиться окошко сообщения.
Если все сделано верно – вы увидите, что текст вопроса изменился. Другим стал и список ответов.
Отладка. Достижение конца набора вопросовВсе происходит хорошо, пока мы движемся по списку вопросов. Но когда текущим является последний – у нас четвертый, – вопрос, и мы переходим по нажатию cmdNext, то переход происходит «в никуда». Вывод – следует определять, не дошли ли мы до последнего вопроса, и, если так, – предотвращать переход «в никуда». Но для нашего набора вопросов не существует индикатора конца списка. Вообще, таблицы Excel такого не предоставляют. Эту задачу придется решать самостоятельно. Один из способов – задать заранее количество вопросов в списке и заложить эту величину в программу как константу. Недостаток этого способа очевиден – изменение содержимого теста будет затруднительно. Другой способ – определять число вопросов теста в процессе работы приложения – а именно, при запуске. Этот способ придаст приложению гибкость, а реализация этого способа не намного сложнее предыдущего. Определить число вопросов не так уж сложно. Для этого следует определить общее число строк в таблице Excel, а затем разделить это число на количество строк в одном вопросе. А количество строк в вопросе уже задано в программе. Определение числа строк таблицы Excel Проблема сводится к определению числа значимых строк в таблице Excel. Уже упоминалось, что нет какого-то указателя конца таблицы. Поищем ответ в справке VBA. Для перехода в нужный раздел справки можно применить такой прием.
Откроется справка, относящаяся к программированию на VBA. Если вы заметили, нажатие [F1] тогда, когда вы работаете с Excel, приводит к открытию совершенно другого раздела, относящегося к Excel, но не VBA. Как помните, объект, обозначающий ячейки, ряды и колонки – Range.
Напомним, что вверху страницы справки есть гиперссылки, вызывающие окна для перехода к справке, относящейся к атрибутам объекта. Подробнее это описывалось в первой части учебника. Как видите, у объекта Range есть свойство Rows – Ряды.
Это свойство представляет ряды у «родительского» объекта, но имеет значение Range. Иными словами, Rows – набор, один член которого – не Row, как можно было подумать, а Range. С подобным мы уже сталкивались раньше. Подсказка – наборы VBA, как правило, сами являются объектами типа Collection – Коллекция. А эти объекты имеют, помимо всего прочего, свойство Count – Количество, Счет, – хранящее число членов набора. У нас уже вырисовывается конструкция: ...Rows.Count Какой объект Range возьмем за основу для вычисления числа рядов? Напрашивается, что этот Range должен как-то относиться к текущему листу Excel. В нашем приложении он уже назначен переменной shtCurrent. Далее подскажем решение. Оно не вполне очевидно. У объекта Range, оказывается, есть свойство CurrentRegion(ТекущийРегион), обозначающее «объект Range, ограниченный любой комбинацией пустых рядов и колонок» (перевод справки). Тип этого свойства – все тот же Range. То, что надо. Итак, свойство CurrentRange определит регион, ограниченный пустыми рядами и колонками. Нам следует сначала «оказаться» в этом регионе. Для этого принудительно сделаем переход в верхнюю левую ячейку листа – а там у нас есть данные, текст первого вопроса. Свойство CurrentRange будет «расширяться» до тех пор, пока не обнаружит, что данных вокруг больше нет. Это будет выглядеть так: shtCurrent.Range(“A1”).CurrentRegion.Rows.Count Обратите внимание на адресацию левой верхней ячейки. Это – один из существующих в Excel способов адресации, состоящий в указании индекса колонки и ряда. Эта конструкция неочевидна. Поиск решения подобных задач может занять много времени – таков, к сожалению, недостаток справочной системы продуктов Microsoft. Здесь нельзя применить цикл Do...Loop – действия производятся не самостоятельно, а в ответ на нажатие кнопки cmdNext. Поэтому стратегия проверки наступления условия будет другой. Для этого используем концепцию флага. Флаг здесь – это переменная, обычно логического типа, значение которой меняется при наступлении какого-то условия. А в начале процедуры происходит проверка значения флага. Давайте сформулируем более подробно. Конструкция будет выглядеть примерно так (здесь fl – флаг). Если fl = True, То Разберем этот шаблон подробно. Сначала проверяем флаг fl. Если fl = True (иначе говоря, если флаг установлен), то выполняем <действия_1>, предназначенные для исполнения по достижении конца набора, а затем – выходим из процедуры. Дальнейшие действия не выполняем. Если флаг fl = False (то есть, если флаг сброшен), проделываем <действия_2>, предназначенные для обычного случая, затем проверяем достижение конца набора, и, если находимся на последнем элементе набора, то устанавливаем флаг fl (делаем флаг равным True). Значение флага будет проверяться при следующем выполнении этого блока. Запишем этот блок «псевдокодом», похожим на VBA: If fl = True Then Обратите внимание на громоздкую конструкцию shtCurrent.Range(“A1”).CurrentRegion.Rows.Count / LineCount Делимое здесь – общее число строк в таблице Excel, делитель – число строк, относящихся к одному вопросу. Результат вычисления – общее число вопросов. Если подразумевать, что таблица данных не будет изменяться во время выполнения программы, то это вычисление можно делать один раз – при запуске приложения. Для хранения результата следует ввести переменную. В глобальном разделе помещаем объявление: Public intQuestions As Integer В процедуре StartTest вычисляем: intQuestions = shtCurrent.Range(“A1”).CurrentRegion.Rows.Count / LineCount А в блоке проверки помещаем результат: If fl = True Then RecordRead intCurrentRecord Заметьте, что в данном случае можно было бы обойтись и без флага, делая проверку непосредственно: If intCurrentRecord
= intQuestions Then При этом блок заметно упрощается. Но во многих других случаях такая непосредственная проверка невозможна или чрезвычайно затруднительна, и следует применить флаг. Поэтому воспользуемся «флаговым» вариантом – в учебных целях. Кроме того, вспомните, что впереди – обработка обратного движения по набору вопросов (кнопка cmdPrev), где флаг может понадобиться. Проектирование деятельности, выполняемой при достижении конца набора вопросовДавайте определимся с <действием_1>, производимым в конце набора вопросов, то есть, по сути дела, в конце теста. Очевидно, что переход на следующую запись не нужен – некуда переходить. Здесь целесообразно выполнить обработку результатов теста, показать их пользователю, и, или предложить повторное тестирование, – или завершить работу. Обработку результатов теста выполним в виде упрощенной процедуры, примерно так: Sub Summary () Вы уже должны понимать, что произойдет при выполнении этой процедуры. Для чего вызов окошечка сообщения выведен в отдельный блок? Очень просто. В дальнейшем вы легко и быстро измените одну эту процедуру и получите осмысленный обработчик результата, не изменяя основной код. Реализация обработчика достижения конца набора вопросовОформим код: If fl = True Then В принципе, можно приступать к реализации. Но мы почти забыли одно упущение, сделанное нами (специально, конечно) гораздо раньше, при визуальном конструировании приложения. А именно – мы еще не определились с надписью на кнопке cmdNext. При достижении конца набора желательно менять надпись, для того, чтобы пользователь был оповещен о достижении конца теста. Проще всего сделать это простым присвоением строки свойству Caption – Заголовок, например: cmdNext.Caption = “Конец теста” Но мы сделаем немного по-другому. Этот способ на первый взгляд более трудоемок, но вы почувствуете его преимущества, если потребуется быстро изменить надписи в приложении – к примеру, перевести приложение на английский. Мы воспользуемся константами, содержащими строки-надписи. В области глобальных определений модуля создадим несколько констант, содержащих нужные надписи. А именно: основная надпись на cmdNext, дополнительная надпись на кнопке cmdNext и надпись на кнопке cmdPrev. Это будет выглядеть так: Public Const captNext As String = “ >>” Как видите, тип константы – String. Этот тип может содержать текстовые строки. За более подробной информацией обращайтесь к справке VBA. Теперь давайте реализуем все, о чем говорилось выше.
Public intQuestions
As Integer Как видите, флаг мы переименовали в fEnd – от слова End – Конец. Пусть имена будут значимыми. Процедура StartTest приобретет вид: Public Sub StartTest() Процедуру Summary можно поместить в basShell, а можно специально для нее создать новый модуль. Это следует сделать, если ожидается объемная и сложная обработка результатов, или если предполагается использовать эту процедуру в других проектах. Также рекомендуется вынести обработку результатов в отдельный модуль, если обработчик «не уместится» в одной процедуре, и придется создавать вспомогательные подпрограммы. В общем случае обработчик надо вынести в отдельный модуль. Создание модуля для обработчика результатов теста Добавим к проекту модуль:
Должно открыться пустое окно кода нового модуля.
Public Sub Summary()
Private Sub cmdNext_Click() Теперь следует позаботиться о первоначальном назначении надписей кнопкам. Первичное назначение надписей кнопкам Назначать надписи на компонентах обычно следует тогда, когда форма уже загружена, но еще не выведена на экран. При работе в VBA следует стремиться все действия связывать с событиями компонентов. Поищем подходящее событие для формы в справке. В справке VBA написано, что событие Initialize – Инициализация – происходит после загрузки формы, но до ее вывода на экран. Это – самый подходящий момент для назначения надписей.
Автоматически возникнет заготовка обработчика события Click – она нам не нужна.
Должна появиться заготовка обработчика этого события.
Private Sub UserForm_Initialize()
Как видите, перемещение происходит нормально, но надпись на кнопке не меняется и окончания теста не происходит. Где-то ошибка. Эта ошибка была допущена намеренно, чтобы продемонстрировать методику отслеживания и устранения неполадок программ. Отладка Появление в создаваемой программе ошибок – нормальное явление, человек не может не ошибаться, как бы этого ни хотелось. VBA имеет некоторые средства для облегчения поиска и исправления ошибок в тексте приложения. Процесс поиска и исправления ошибок называется отладкой. Как вы уже знаете, VBA допускает работу IDE VBA в режиме создания программы, когда вы пишете код или конструируете визуальную часть (design-time, время создания) и в режиме работы создаваемого приложения (run-time, время исполнения). Оказывается, у IDE VBA имеется еще один режим работы, применяемый для «пошагового» выполнения кода. Именно этот режим используется при отладке. Перейти в пошаговый режим можно по-разному. Во-первых, можно заставить программу остановиться в нужный момент, а затем продолжить ее работу пошагово. Во-вторых, можно сразу запустить программу таким образом.
Не забудьте поместить текстовый курсор в код процедуры StartTest – с этой процедуры начинается работа приложения. Вы увидите, что первая строка кода изменит цвет, а на вертикальной полоске слева появится значок:
Это – обозначение строки кода, которая будет выполнена в следующий раз.
Значок-стрелка перейдет на следующую строку и цветовая «подсветка» – также. Таким образом вы можете «прошагать» всю программу, хотя это может оказаться очень долго. Остановка пошагового режима – по нажатию кнопки с «квадратиком», как и для обычного выполнения. Из пошагового режима вы можете в любой момент перейти в режим обычного выполнения, для этого в очередной раз нажмите не [F8], а [F5]. Ввиду того, что пошаговый проход приложения может быть очень трудоемким, применяются так называемые точки останова. Точка останова (BreakPoint) – особого рода метка, создаваемая IDE VBA в коде. При выполнении программы в обычном режиме, по достижении точки останова происходит приостановка программы. Дальнейшее продолжение выполнения возможно как в обычном, так и в пошаговом режиме. Какой же смысл в пошаговом проходе? Дело в том, что IDE VBA предоставляет некоторые интересные и полезные возможности именно для отладки приложений. Давайте попробуем. Начните пошаговый проход процедуры StartTest, если вы еще не сделали этого.
Должна выделиться строка-заголовок процедуры: Public Sub StartTest()
Выделение перейдет на следующую строку: Set shtCurrent = ActiveWorkbook.Worksheets("Лист1")
Появится подсказка:
Вы видите очень любопытный текст: shtCurrent = Nothing Слово Nothing – Ничто, – в VBA обозначает, что объектной переменной не назначено значение. Иными словами, всплывающая подсказка в таком режиме отображает значения переменных!
Подсветка перейдет на следующую строку. Теперь подсказка над словом shtCurrent не появится вовсе. Действительно, значение объектной переменной слишком сложно для отображения в маленькой табличке. Но вы можете проследить изменение значений других переменных по мере перемещения «подсветки». Теперь вернемся к отладке приложения. Давайте вспомним изменения, произведенные нами на последнем этапе. Какой код может внушать опасения своей правильности? На проверку напрашивается конструкция shtCurrent.Range("A1").CurrentRegion.Rows.Count Эта строка неочевидна, создание ее было сопряжено с интуитивными догадками, и справочная система VBA не дала внятной информации на эту тему… Давайте проверим именно этот код. Создадим на этой строке точку останова. Создание точки останова Для этого:
На полосе слева должен появиться «кружочек», а строка изменит цвет. Повторный щелчок здесь же вернет все к прежнему виду, точка останова будет удалена. Так создается точка останова. Программа будет выполняться ДО этой точки, после чего произойдет переход в пошаговый режим. Строка, на которой создана точка останова, не выполнится. Теперь давайте запустим приложение.
Программа запустится, дойдет до нужной строки и остановится. Строка с точкой останова изменит цвет. Давайте проверим значение конструкции shtCurrent.Range("A1").CurrentRegion.Rows.Count
А вот это интересно. VBA определил, что число заполненных рядов в таблице Excel равно 1.
Изменений не произошло. Видимо, мы нашли ошибку.
Ошибка в структуре данных Давайте проанализируем возможную причину ошибки. Строка кода составлена по всем правилам, скажем заранее – здесь ошибок нет.
Третья колонка, в которой мы собирались помещать значения выбранных ответов, пуста! А объект CurrentRegion, как мы разбирали, ограничивает найденную область пустыми рядами и ячейками. Получается, что данная строка кода обрабатывает не всю таблицу данных, а только небольшой ее участок:
И этот участок действительно содержит только один ряд, как нам это продемонстрировала подсказка пошагового режима. Подобные ошибки, выявленные при создании больших и сложных программ, могут дорого стоить. Избежать их можно – внимательным проектированием, хорошим знанием объектных библиотек и разбиением процесса разработки на множество маленьких «цикликов» – тогда неудача одного из них не сильно затормозит работу. Но в данном случае ошибка была допущена специально и исправить ее легко. Как вы помните, третий столбец таблицы изначально предназначался нами для помещения полученных в результате теста ответов. Мы пока не заполнили этот столбец – и поплатились за лень. Давайте исправим ошибку, внеся в третий столбец таблицы произвольные значения. Обратите внимание, что для сохранения непрерывности участка данных эти значения должны располагаться в тех же строках, что и значения первой и второй колонок. Например, так:
Проверьте значение нужной конструкции:
Как видите, теперь определение числа рядов происходит правильно.
Удалить сразу все точки останова во всем проекте можно, нажав [Ctrl]+[Shift]+[F9]. Это удобно для того, чтобы не просматривать весь текст, который может быть очень большим.
По достижении последнего, четвертого вопроса, надпись на кнопке меняется на « ». При следующем нажатии выводится окошко сообщения, но перемещения не происходит.Наша цель достигнута.
Доработка документации проектаПри выполнении этого подцикла построения приложения мы не придерживались предыдущей методики – не составляли схемы, иллюстрирующие выполняемые задачи. В таком простом приложении, как наше, можно было обойтись и без схем, но, возможно, вы заметили, что работа усложнилась и стала менее очевидной. Если вы пришли к выводу о важности схем – это хорошо. Давайте сделаем схемы, хотя бы и по окончании работы. Быть может, они пригодятся потом. Для обозначения проверки условий на схемах последовательности действий используется специальный значок – «ромбик»:
Рядом с обозначением проверки условий следует указать, какое именно условие проверяется. Стрелочки, исходящие из ромбика, указывают на цепочку, выполняемую в случае выполнения условия – стрелка с надписью [да] и в случае, когда условие не выполняется – стрелка с надписью [нет]. Если цепочки [да] и [нет] объединяются, используется обозначение:
Как вы видите, на этой схеме два обозначения конца последовательности действий. Так делать допускается, если при этом происходит упрощение схемы.
На этом завершим занятие. Итог занятияЗанятие получилось большим и информативным. Для того чтобы не утратить логической целостности, мы не стали разбивать материал на несколько частей, так что вам пришлось потрудиться. Как вы, наверное, заметили, помимо создания нового кода, мы вносили исправления в уже имевшийся. Это нормально для итерационного процесса разработки. На предыдущих стадиях вы создали работоспособное приложение – но для расширения функциональности пришлось его переработать. Если бы мы составляли код так, чтобы не изменять его в дальнейшем, то ранние версии приложения не смогли бы работать, а тогда вы не имели бы стимула трудиться, накапливались бы ошибки, которые легко «отловить» при итерационной технологии, и был бы недоволен потенциальный заказчик… Без шуток, почему бы и не продавать свои программы? Плох тот солдат, и так далее... Важная иллюстрация, которую вы получили в ходе занятия – создание процедуры с параметром. Более того, эта процедура – модификация написанной ранее процедуры без параметров, что должно сделать нагляднее разницу между ними. Также вы увидели два способа вызова такой процедуры – с передачей абсолютного значения и с аргументом-переменной. Далее вы получили намек на то, как в VBA выполняются арифметические действия. Ничего сложного здесь нет, достаточно вспомнить школьные примеры по математике. Полный, довольно обширный список применяемых операторов, а также порядок их выполнения в сложных формулах вы найдете в справочной системе. Не очень нужная, но полезная в учебных целях конструкция с флагом. В следующей части учебника вы встретите видоизменение этой конструкции, и там без нее нельзя было бы обойтись. Константы для хранения строк – прием, значительно облегчающий написание и отладку. На первый взгляд, с константами больше мороки, проще написать строку прямо в коде – но представьте реальную ситуацию, когда в программе несколько раз встречается одна и та же строка, и в один «прекрасный» момент вы захотели ее изменить. Или решили перевести программу на, предположим, английский язык. Вопрос – как долго вы будете копаться в коде и сколько ошибок при этом допустите? Существует и лучшее решение – ресурсы. Но для начинающих это довольно сложно, заметим лишь, что файлы ресурсов позволяют хранить в одном месте не только строки, но и рисунки, значки, звуковые и другие файлы. В ходе занятия вы дважды столкнулись с появлением ошибок – преднамеренно сделанных нами для иллюстрации приемов отладки. Помните, что на самом деле, в реальной работе ошибок будет куда больше – поэтому следует внимательно (и неоднократно) перечитать разделы, описывающие отладку. Если примитивные синтаксические ошибки VBA заставляет исправлять при наборе кода – вы, конечно, уже сталкивались с окошком-предупреждением, появляющимся при неверном наборе слова, то ошибки, допущенные при проектировании найти гораздо сложнее. Очень неприятная ошибка, продемонстрированная в этом занятии, связана с неверным составлением правильно спроектированных данных, в реальности ее поиск мог бы занять не один день… Будьте внимательны! И конспект:
|