Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Тема 4. Циклы
Цикл – это процесс повторения набора инструкций. Возможно, вы заранее знаете, сколько раз должен повториться цикл, или это значение определяется переменными в программе. Следующий код, в котором в диапазон вводятся последовательные числа, является примером того, что называют плохим циклом. Процедура использует две переменные для хранения начального значения (StartVal) и общего количества ячеек, которые необходимо заполнить (NumToFill). В этом цикле для управления порядком выполнения операций используется оператор GoTo. Если переменная Cnt, отвечающая за то, сколько ячеек заполнено, меньше числа, заданного пользователем, то выполняется переход назад к метке DoAnother: Sub BadLoop() StartVal = 1 NumToFill = 100 ActiveCell.Value = StartVal Cnt = 1 DoAnother: ActiveCell.Offset(Cnt, 0).Value = StartVal + Cnt Cnt = Cnt + 1 If Cnt < NumToFill Then GoTo DoAnother Else Exit Sub End Sub Описанная процедура выполняется правильно. Почему же она является примером плохого цикла1? Настоящие программисты не используют оператор GoTo, если можно обойтись без него. Применение операторов GoTo в цикле противоречит концепции структурированного программирования. Этот оператор значительно усложняет восприятие кода, поскольку в данном случае практически невозможно структурировать цикл с помощью отступов. Кроме того, такой тип неструктурированного цикла делает процедуру подверженной частым ошибкам. Также использование большого количества меток приводит к получению программы с плохой структурой (или без структуры вообще) и бессистемным порядком следования операций. Поскольку в VBA встроено несколько структурированных команд циклов, в процессе принятия решений практически никогда не требуется прибегать к операторам GoTo. Что же представляет собой структурированное программирование и как его можно применить к VBA? Основное условие заключается в том, что процедура или сегмент программы должны иметь только одну точку входа и одну точку выхода. Другими словами, тело кода должно выступать независимым элементом, а контроль за выполнением программы не должен выходить за рамки этого элемента. В результате структурированное программирование не приемлет оператора GOTO. Если вы обеспечиваете структурированность кода, то ваша программа выполняется в определенном порядке и за ходом выполнения легко уследить – в отличие от кода, в котором программа " перескакивает" с; места на место. Структурированную программу легче воспринимать и анализировать, чем неструктурированную. Что более важно, ее также легче изменять. VBA – структурированный язык. Он предлагает стандартные структурные конструкции, например, If-Then-Else и Select Case, ЦИКЛЫ For-Next, Do Until И Do While. Более того, VBA полностью поддерживает модульную систему создания программ. Цикл For-Next в VBA является самым простым и очень часто используемым. Формат данного цикла следующий: For Счетчик = Начальное_значение То Конечное_значение [Step Шаг] [ Инструкции ] [Exit For] [ Инструкции ] Next [ Счетчик ] Здесь Счетчик – это переменная-итератор любого численного типа. Начальное значение, Конечное_значение, Шаг – численные значения или идентификаторы переменных численного типа. После ключевого слова Next можно (но не обязательно) указывать идентификатор итератора цикла, конец тела которого обозначает данное ключевое слово. Указывать идентификатор переменной-итератора после Next особенно удобно при организации сложных вложенных циклов. В начале выполнения цикла итератору присваивается значение элемента Начальное_значение. Инструкции, записанные в теле цикла, выполняются до тех пор, пока значение итератора не превзойдет значение элемента Конечное_значение (станет больше или меньше его в зависимости от направления изменения итератора). Шаг и направление изменения итератора (увеличение или уменьшение) задаются элементом Шаг. Если шаг изменения итератора равен единице, то данный элемент можно опустить. Для преждевременного выхода из цикла предусмотрена инструкция Exit For. При ее встрече в теле цикла выполнение программы переходит на следующую инструкцию после ключевого слова Next. Ниже приведен пример трех вложенных циклов For-Next, итераторами которых являются целочисленные переменные i, j и k: For i = 10 То 1 Step -1 For j = 1 То 20 For k= 10 To -10 Step -2 `Выполнение каких-то действий … Next k Next j Next i Инструкция VBA If-Then-Else предоставляет возможность выбора одного из действий в зависимости от значений заданных логических выражений. Формат данной инструкции следующий: If Выражение1 Then [Инструкции1] [ElseIf Выражение2 Then [Инструкции2]] … [Elself ВыражениеN Then [ИнструкцииN]] [Else [Инструкции]] End If Здесь Выражение 1 - ВыражениеN – логические выражения. Если какое-либо из этих выражений истинно, то выполняются инструкции, находящиеся после соответствующего ключевого слова If или Elself. Если ни одно из выражений не является истинным, то выполняются инструкции, записанные после ключевого слова Else (если, конечно, это ключевое слово используется). Рассмотрим пример использования инструкции If-Then-Else: If intAction = 1 Then `Выполнение сложения res = а + b Elself intAction = 2 Then `Выполнение вычитания res = a - b Elself intAction = 3 Then `Выполнение умножения res = a * b Else `Заданное действие не поддерживается `… End If В приведенном примере с помощью инструкции If-Then-Else выбирается одно из трех поддерживаемых действий для переменных а и b: сложение, вычитание или умножение. То, какое действие выполнять, определяется по содержимому переменной intAction. Если она имеет значение, отличное от 1, 2 и 3, то выполняются инструкции, следующие после ключевого слова Else. Язык программирования VBA также поддерживает упрощенный вариант инструкции If-Then-Else: If Выражение Then [ Инструкции1 ][Else Инструкции2 ] Здесь Выражение – это логическое выражение, при истинном значении которого выполняются инструкции после ключевого слова Then. Если Выражение не истинно, то выполняются инструкции после ключевого слова Else (если это ключевое слово используется). При использовании этой формы инструкции If-Then-Else следует учитывать, что она записывается в одну строку (или в несколько строк, но с использованием символа подчеркивания). Также необходимо учитывать, что Инструкции1 и Инструкции2 представляют собой либо одну инструкцию VBA, либо несколько инструкций, разделенных двоеточием. Если ключевое слово Else используется, то элемент Инструкции1 может отсутствовать. Оператор Do While – еще один тип циклической структуры, представленной в VBA. В отличие от цикла For-Next, цикл Do while выполняется до тех пор, пока удовлетворяется заданное условие. Цикл Do While может иметь один из двух представленных ниже синтаксисов: Do [While условие] [инструкции] [Exit Do] [инструкции] Loop или DO [инструкции] [Exit Do] [инструкции] Loop [While условие] Как видите, VBA позволяет проверять условие While в начале или в конце цикла. Разница между этими двумя синтаксисами связана с моментом, когда оценивается условие. В первом синтаксисе содержимое цикла может вообще не выполнятся. Во втором содержимое цикла всегда выполняется (как минимум один раз). Следующий пример демонстрирует цикл Do While с первым синтаксисом: Sub DoWhileDemo() Do While Not IsEmpty(ActiveCell) ActiveCell.Value = 0 ActiveCell.OffSet(1, 0).Select Loop End Sub Данная процедура использует активную ячейку как точку отсчета и просматривает значения вниз по столбцу, вставляя ноль в активную ячейку. При каждом повторении цикла активной становится следующая ячейка в столбце. Цикл продолжается, пока функция VBA IsEmpty не определит, что активная ячейка пуста. Далее покажем работу второго синтаксиса цикла Do while, Цикл всегда будет выполнен хотя бы один раз, даже если исходно активная ячейка пуста: Sub DoWhileDemo2() Do ActiveCell.Value = 0 ActiveCell.OffSet(1, 0).Select Loop While Not IsEmpty(ActiveCell) End Sub Ниже следует еще один пример цикла Do While. Эта процедура открывает текстовый файл, считывает каждую строку, преобразует текст в верхний регистр, а затем сохраняет его на активном листе, начиная с ячейки A1, и продолжает перемещаться вниз по столбцу. Представленная процедура использует функцию VBA EOF, возвращающую True, если достигнут конец файла. Последний оператор закрывает текстовый файл. Sub DoWhileDemo3() Open " c: \data\textfile.txt" For Input As #1 LineCt = 0 Do While Not EOF(l) Line Input #1, LineOfText Range(" A1").Offset(LineCt, 0) = UCase(LineOfText) LineCt = LineCt + 1 Loop Close #1 End Sub Структура цикла Do Until имеет много общего с конструкцией Do while. Разница заключается лишь в том, как проверяется условие цикла. В варианте Do while цикл выполняется до тех пор, пока выполняется условие. В цикле Do Until цикл выполняется, пока условие не станет выполняться. Структура Do Until может быть представлена двумя видами синтаксиса: Do [Until условие] [инструкции] [Exit Do] [инструкции] Loop ИЛИ Do [инструкции] [Exit Do] [инструкции] Loop [Until условие] Пример, приводимый далее, уже был продемонстрирован для цикла Do While, но теперь он изменен для иллюстрации возможностей цикла Do Until. Единственное отличие – строка с оператором Do. Этот пример делает программу несколько понятнее, так как не используется отрицание, необходимое в примере Do While: Sub DoUntilDemo() Open " c: \data\textfile.txt" For Input As #1 LineCt =0 Do Until EOF(l) Line Input #1, LineOfText Range(" Al").Offset(LineCt, 0) = UCase(LineOfText) LineCt = LineCt + 1 Loop Close #1 End Sub Конструкция With-End With позволяет выполнять несколько операций над одним объектом. Чтобы понять, как она работает, проанализируем следующую процедуру, которая из меняет пять свойств выделенного объекта (подразумевается, что выделен объект Range): Sub ChangeFontl() Selection.Font.Name = " Times New Roman" Selection.Font.Fontstyle = " Bold Italic " Selection.Font.Size = 12 Selection.Font.Underline = xlUnderlineStyleSingle Selection.Font.Colorlndex = 5 End Sub Эту процедуру можно переписать с помощью конструкции With-End With. Процедура, показанная ниже, работает точно так же, как и предыдущая: Sub ChangeFont2() With Selection.Font .Name = " Times New Roman" .FontStyle = " Bold Italic" .Size = 12 .Underline = xlUnderlineStyleSingle .Colorlndex = 5 End Sub Некоторые считают, что второй вариант этой процедуры читать сложнее. Однако следует помнить, что целью изменений является увеличение скорости выполнения операций Первый вариант более прямолинейный и его легче понять, но процедура, использующая для изменения нескольких свойств одного объекта конструкцию With-End With, помогает повысить эффективность выполнения кода по сравнению с эквивалентной ей процедурой, которая явно ссылается на объект в каждом операторе.
|