Статические процедуры и функции.Процедуры и функции могут быть описаны как статические, при этом все переменные этих процедур и функций также становятся статическими Примеры, относящиеся к вышеизложенному материалу, находятся в книге lect12.XLS в модуле VisVar. Описание констант При описании константы ей можно присвоить значащее имя. Инструкция Const используется для описания константы и определения ее значения. После описания константу нельзя модифицировать и нельзя присваивать ей новое значение. Константа описывается в процедуре или в начале модуля, в разделе описаний. Константы уровня модуля по умолчанию являются личными. При описании общих констант уровня модуля инструкции Const должно предшествовать ключевое слово Public. Для явного описания личных констант перед инструкцией Const надо поставить ключевое слово Private. Это облегчает чтение и отладку программы. В следующем примере константа Public conAge описывается как Integer, и ей присваивается значение 34. Public Const conAge As Integer = 34 Константы могут быть описаны одним из следующих типов данных: Boolean, Byte, Integer, Long, Currency, Single, Double, Date, String, или Variant. Поскольку значение константы уже известно, можно задать тип данных в инструкции Const. Дополнительные сведения содержатся в разделе "Типы данных" справочника Visual Basic. Допускается также описание нескольких констант в одной строке. В этом случае, чтобы задать тип данных, надо указать определенный тип для каждой константы. В следующем примере константы conAge и conWage описываются как Integer. Const conAge As Integer = 34, conWage As Currency = 35000 Устранение конфликтов имен При попытке создать или использовать идентификатор, определенный ранее, возникает конфликт имен. В некоторых случаях при конфликтах имен вырабатываются ошибки типа "Обнаружено повторяющееся имя" или "Повторяющееся описание в текущей области определения". Если конфликты имен не обнаружены, они могут привести к ошибкам в программе, и, как следствие, к ошибочным результатам. Это особенно вероятно в том случае, если все переменные не были описаны явным образом до их применения. Для предотвращения большинства конфликтов имен необходимо аккуратно разобраться с областями определения идентификаторов для данных, объектов и процедур. Язык Visual Basic имеет три уровня областей определения: уровень процедуры, личный уровень модуля и общий уровень модуля. Конфликты имен могут возникать, если идентификатор: · Является видимым более чем на одном уровне областей определения. · Имеет на одном и том же уровне два различных значения. Например, процедуры в различных модулях могут иметь одинаковое имя. Таким образом, процедура по имени MySub может быть определена в модулях Mod1 и Mod2. Конфликты не возникают, если каждая процедура вызывается только из других процедур в ее собственном модуле. Однако возможно возникновение ошибки, если MySub вызывается из третьего модуля и отсутствует полная ссылка на определенный модуль, позволяющая различить эти две процедуры MySub. Большинство конфликтов имен может быть разрешено с помощью предшествующего каждому идентификатору указателя, состоящего из имени модуля и, если нужно, имени проекта. Например: YourProject.YourModule.YourSub MyProject.MyModule.MyVar Предшествующая программа вызывает процедуру Sub YourSub и передает переменную MyVar как аргумент. Допускается использование любой комбинации указателей, позволяющей различить одинаковые идентификаторы. Visual Basic сопоставляет каждую ссылку на идентификатор с "ближайшим" описанием такого идентификатора. Например, если MyID описан как Public в двух модулях проекта (Mod1 и Mod2), то можно указать MyID, описанный в Mod2 без дополнительного указания внутри Mod2, но необходимо точно задать его имя (как Mod2.MyID) для ссылки на него в Mod1. Это справедливо также, если Mod2 находится в другом проекте, который является напрямую адресуемым проектом. Однако если Mod2 находится в косвенно адресуемом проекте, т.е. таком, на который ссылается напрямую адресуемый проект, ссылки на его переменную по имени MyID всегда должны быть полными и содержать имя проекта. Если ссылка на MyID выполняется из внешнего напрямую адресуемого модуля, то она сопоставляется с первым описанием, обнаруженным в следующем порядке: · Напрямую адресуемые проекты в том порядке, в котором они появляются в окне диалога Ссылки, вызываемого из меню Сервис. · Модули каждого проекта. Следует отметить, что не существует внутреннего порядка для модулей проекта. Имена объектов главного приложения (например, R1C1 в Microsoft Excel) не могут повторно использоваться на других уровнях области определения. Совет. К типичным ошибкам, вызывающим конфликты имен, относятся неоднозначные задания имен, повторяющиеся описания, неописанные идентификаторы и ненайденные процедуры. Задание в начале каждого модуля инструкции Option Explicit, требующее явного описания переменных до их использования, помогает избежать как возможных конфликтов имен, так и ошибок, связанных с идентификаторами. Операторы управления Наиболее часто используемые операторы управления VBA следующие: If-Then-Else Проверяет и меняет ход выполнения программы в зависимости от результата проверки. Select Case Выбирает один из возможных вариантов выполнения программы в зависимости от значения переменной или результатов проверки. For-Next Выполняет повторяющиеся действия заданное число раз While-Wend Выполняет повторяющие действия, пока справедливо заданное условие Do-Loop – Выполняет повторяющиеся действия, пока справедливо заданное условие или до тех пор, пока заданное условие не будет выполнено For-Each-Next Выполняет повторяющиеся действия для каждого объекта в семействе или для каждого элемента массива. Рассматривать подробно не будем, примеры приводятся в lect12.XLS модуль UprOper If-Then-Else Данный оператор используется для изменения хода выполнения программы в зависимости от результатов проверки '===================================================
Option Base 1
'=================================================== 'Пример, демонстрирующий использование оператора If-Then-Else. 'Процедура генерирует случайные числа, выигрыш - число 7. '=================================================== Sub Lect12uProc15_IfThenElse() Dim Num1 As Integer Num1 = GetRandomNumber If Num1 = 7 Then MsgBox "Вы выиграли. Ваше число - " & _ Num1 & "." Else MsgBox "Вы проиграли. Ваше число - " & _ Num1 & "." End If End Sub
Function GetRandomNumber() GetRandomNumber = Int(10 * Rnd()) End Function Proc15 начинает свою работу с вызова функции GetRandomNumber для присвоения переменной Num1. Select Case Инструкция Select Case может служить альтернативой инструкции ElseIf в If...Then...Else при оценке одного выражения, которое имеет несколько возможных значений. В то время как If...Then...Else для каждой инструкции ElseIf оценивает разные выражения, инструкция Select Case оценивает выражение только один раз, в начале управляющей структуры. В следующем примере Select Case оценивает аргумент performance, который передается в процедуру. Следует отметить, что каждая инструкция Case оценивает несколько значений, диапазон значений или комбинацию значений и операторов сравнения. Необязательная инструкция Case Else выполняется, если Select Case не находит подходящего значения ни в одной из инструкций Case.
Function Bonus(performance, salary) Select Case performance Case 1 Bonus = salary * 0.1 Case 2, 3 Bonus = salary * 0.09 Case 4 To 6 Bonus = salary * 0.07 Case Is > 8 Bonus = 100 Case Else Bonus = 0 End Select End Function For...Next Инструкция For...Next используется для выполнения наборов инструкций указанное число раз. Циклы For используют в качестве счетчика переменную, значение которой увеличивается или уменьшается при каждом выполнении цикла. Следующая процедура заставляет компьютер подавать звуковой сигнал 50 раз. Инструкция For определяет счетчик х и его начальное и конечное значения. Инструкция Next изменяет счетчик с шагом 1.
Sub Beeps() For x = 1 To 50 Beep Next x End Sub
Имеется возможность увеличивать или уменьшать значение счетчика на указанную величину с помощью ключевого слова Step. В следующем примере счетчик j изменяется с шагом 2 при каждом выполнении цикла. По завершении цикла total равняется сумме 2, 4, 6, 8 и 10.
Sub TwosTotal() For j = 2 To 10 Step 2 total = total + j Next j MsgBox "Сумма равна " & total End Sub
Для уменьшения значения счетчика используется отрицательное значение Step. В этом случае указывается конечное значение, которое должно быть меньше начального значения. В следующем примере счетчик myNum уменьшается на 2 при каждом выполнении цикла. По окончании цикла total равняется сумме 16, 14, 12, 10, 8, 6, 4 и 2.
Sub NewTotal() For myNum = 16 To 2 Step -2 total = total + myNum Next myNum MsgBox "Сумма равна " & total End Sub
Примечание. Указание имени счетчика после инструкции Next не обязательно. В предыдущих примерах имя счетчика было указано для облегчения чтения программы.
Инструкция Exit For дает возможность завершения инструкции For...Next до того, как счетчик достигнет своего конечного значения. Например, если возникает ошибка, для ее проверки можно использовать инструкцию Exit For в блоке True инструкции If...Then...Else или инструкции Select Case. Если ошибки нет, инструкция If...Then...Else имеет значение False, и выполнение цикла продолжается, как ожидалось. While-Wend Выполняет последовательность инструкций, пока заданное условие имеет значение True. While условие [инструкции] Wend
Синтаксис инструкции While...Wend содержит следующие элементы: Условие «Обязательный». Числовое выражение или строковое выражение, которое имеет значение True или False. Если условие имеет значение Null, условие рассматривается как имеющее значение False. Инструкции «Необязательный». Одна или несколько инструкций, выполняемых, пока условие имеет значение True. Дополнительные сведения Если условие имеет значение True, выполняются все инструкции до инструкции Wend. Затем управление возвращается инструкции While и вновь проверяется условие. Если условие по-прежнему имеет значение True, процесс повторяется. Если оно не имеет значение True, выполнение возобновляется с инструкции, следующей за инструкцией Wend. Циклы While...Wend могут иметь любую глубину вложенности. Каждая инструкция Wend соответствует предшествующей инструкции While. Do...Loop Инструкция Do...Loop используется для выполнения наборов инструкций неопределенное число раз. Набор инструкций повторяется, пока условие имеет значение True, либо пока оно не примет значение True. Повторение инструкций, пока условие имеет значение True Имеется два способа проверки условия в инструкции Do...Loop с помощью ключевого слова While: условие проверяется до входа в цикл; условие проверяется после хотя бы однократного выполнения цикла. В следующей процедуре ChkFirstWhile условие проверяется до входа в цикл. Если myNum задать равным 9 вместо 20, инструкции внутри цикла выполняться не будут. В процедуре ChkLastWhile инструкции внутри цикла выполняются только один раз до того как условие примет значение False.
Sub ChkFirstWhile() counter = 0 myNum = 20 Do While myNum > 10 myNum = myNum - 1 counter = counter + 1 Loop MsgBox "Выполнено " & counter & " итераций цикла." End Sub
Sub ChkLastWhile() counter = 0 myNum = 9 Do myNum = myNum - 1 counter = counter + 1 Loop While myNum > 10 MsgBox "В цикле выполнено " & counter & " итераций." End Sub
Имеется два способа проверки условия в инструкции Do...Loop с помощью ключевого слова Until: условие проверяется до входа в цикл (как продемонстрировано в процедуре ChkFirstUntil), или условие проверяется после хотя бы однократного выполнения цикла (как показано в процедуре ChkLastUntil). Итерации продолжаются, пока условие имеет значение False.
Sub ChkFirstUntil() counter = 0 myNum = 20 Do Until myNum = 10 myNum = myNum - 1 counter = counter + 1 Loop MsgBox "В цикле выполнено " & counter & " итераций." End Sub
Sub ChkLastUntil() counter = 0 myNum = 1 Do myNum = myNum + 1 counter = counter + 1 Loop Until myNum = 10 MsgBox "В цикле выполнено " & counter & " итераций." End Sub
Инструкцию Do...Loop можно завершить с помощью инструкции Exit Do. Например, для завершения бесконечного цикла используется инструкция Exit Do в блоке True инструкции If...Then...Else или инструкции Select Case. Если условие имеет значение False, цикл будет выполняться как обычно. В следующем примере переменной myNum присваивается значение, приводящее к бесконечному циклу. Инструкция If...Then...Else проверяет условие на myNum, а затем завершает инструкцию Do...Loop, предотвращая, таким образом, бесконечный цикл.
Sub ExitExample() counter = 0 myNum = 9 Do Until myNum = 10 myNum = myNum - 1 counter = counter + 1 If myNum < 10 Then Exit Do Loop MsgBox "В цикле выполнено " & counter & " итераций." End Sub
Примечание. Для прекращения бесконечного цикла используются клавиши ESC или CTRL+BREAK. Совет. Инструкция Do...Loop обеспечивает более структурированный и гибкий способ организации циклов. For Each...Next Инструкция For Each...Next повторяет набор инструкций для всех объектов семейства или для всех элементов массива. Visual Basic автоматически задает переменную во время каждого выполнения цикла. Например, в следующей процедуре закрываются все формы, за исключением формы, содержащей текущую процедуру.
Sub CloseForms() For Each frm In Application.Forms If frm.Caption <> Screen. ActiveForm.Caption Then frm.Close Next End Sub
В следующих строках программы выполняется цикл для всех элементов массива, и их значения присваиваются индексной переменной I. Dim TestArray(10) As Integer, I As Variant For Each I In TestArray TestArray(I) = I Next I
Инструкция For Each...Next используется также для организации циклов по диапазонам ячеек. Следующая процедура выполняет цикл по диапазону A1:D10 на листе Sheet1 и присваивает любому числу, имеющему абсолютное значение меньше 0.01, значение 0 (ноль).
Sub RoundToZero() For Each myObject in myCollection If Abs(myObject.Value) < 0.01 Then myObject.Value = 0 Next End Sub
Допускается выход из цикла For Each...Next с помощью инструкции Exit For. Например, если возникает ошибка, для ее проверки можно использовать инструкцию Exit For в блоке True инструкции If...Then...Else или инструкции Select Case. Если ошибки нет, инструкция If...Then...Else имеет значение False, и выполнение цикла продолжается, как ожидалось. В следующем примере проверяется первая ячейка диапазона A1:B5, которая не содержит числового значения. Когда такая ячейка найдена, на экран выводится сообщение, и Exit For завершает цикл.
Sub TestForNumbers() For Each myObject In MyCollection If IsNumeric(myObject.Value) = False Then MsgBox "Объект не содержит числового значения." Exit For End If Next c End Sub
|
| Оглавление| |