2 семестр / Программирование на VBA
.pdf
|
False |
|
Condition |
True |
|
|
|
|
|||
|
|
|
|
||
|
|
|
|
|
|
ElseStatements |
|
Statements |
|||
|
|
|
|
|
|
|
|
|
|
|
|
Оператор If…Then…Else выбирает одну или другую ветвь, но никогда не выбирает обе ветви одновременно.
Сложный выбор
При необходимости принятия более сложных решений можно помещать оператор If …Then или If…Then…Else внутрь другого оператора If…Then или If…Then…Else, что называется вложением операторов (nesting). Вложение
означает помещение одного типа структуры управления выполнением кода внутрь другой
Задание 3. Напишите процедуру, содержащую вложенные операторы
If…Then…Else.
Для этого:
ü введите процедуру (листинг 11):
Листинг 11 – Вложенные операторы If…Then…Else
1Sub List4_11 ()
2' Определение скидки (в %) в зависимости от
3' количества продаваемого товара
4Dim IStr As String
5Dim IntNum As Variant
6 |
|
7 |
IntNum = Application.InputBox( _ |
8 |
Prompt:="Введите количество товара", _ |
9 |
Title:="Исходные данные", Type:=1) |
10If Not (TypeName(IntNum) = "Boolean") Then
11If IntNum > 1000 Then
12 |
IStr = "10" |
13 |
Else |
14 |
If IntNum > 500 Then |
15 |
IStr = "6" |
16 |
Else |
17 |
IStr = "0" |
18 |
End If |
19End If
20MsgBox "Скидка " & IStr & "%"
21Else
22MsgBox "Количество не указано"
23End If
24End Sub
71
Аргументы в строках 8, 9 Prompt, Title, Type являются именованными аргументами функции Application.InputBox. Написанная так процедура будет работать только в Excel, так как она использует метод Application.InputBox. Этот метод применен для того, чтобы не дать пользователю во время работы функции InputBox ввести что-либо, кроме числа (необязательный аргумент Type:=1 говорит о том, что вводить можно только численные значения). VBA отображает сообщение об ошибке, если пользователь вводит не число (рис. 17), и ожидает до тех пор, пока пользователь не введет численное значение или не выберет кнопку
Cancel.
Рис. 17
Если пользователь, не вводя данные в окне функции Application.InputBox, щелкнет на кнопке OK, VBA также выдаст сообщение об ошибке (рис. 18).
Рис. 18
Если пользователь использует «спасительную» кнопку Cancel, чтобы отказаться от ввода, программа (в строке 10) проверит результат ввода, который при щелчке на кнопке Cancel имеет тип Boolean, и выберет необходимую ветвь оператора If…Then…Else (выполнится оператор в строке 23).
VBA предоставляет сокращенную версию оператора If…Then…Else, являющуюся сжатым эквивалентом вложенных операторов If…Then…Else, показанных в листинге 11. Такой краткой формой является оператор
If…Then…ElseIf.
Оператор If…Then…ElseIf имеет следующий синтаксис:
If Condition1 Then Statements1
ElseIf Condition2
Statements2
[Else
Statements3] End If
Изображение оператора If…Then…ElseIf на блок-схеме:
72
Condition1 True
False Statements1
Condition1 True
False Statements2
Statements3
Упражнение 2
Напишите процедуру, использующую оператор If…Then…ElseIf.
Для выполнения выбора из нескольких возможных ветвей кода можно вкладывать операторы If…Then…Else на много уровней вглубь, но уследить за ходом выполнения ветвей становится прогрессирующе труднее. Оператор If…Then…ElseIf имеет подобную проблему: когда имеется много операторов ElseIf, оператор If…Then…ElseIf становится трудно читать и сопровождать.
К «счастью», VBA имеет условный оператор перехода для использования в случаях, когда необходимо выбирать из большого количества различных ветвей кода: оператор Select…Case. Оператор Select…Case имеет следующий синтаксис:
Select Case TestExpression
Case ExpressionListl
Statements1
Case ExpressionList2
Statements2
… … … … … …
Case ExpressionListN
StatementsN
[Case Else
ElseStatements
End Select
ТеstExpression – любое численное или строковое выражение. ExpressionListl, ExpressionList2, …, ExpressionListN – (каждый) представляют список логических выражений, отделенных запятыми. Statements1, statements2, …, statementsN и ElseStatements (каждый) представляют один, несколько или ни одного оператора VBA. В Select…Case можно включать столько операторов Case ExpressionList, сколько необходимо.
Блок-схема оператора Select…Case подобна блок-схеме оператора
If…Then…ElseIf.
В отдельных операторах Case выражение ExpressionList может состоять из одного или более выражений, отделяемых запятой. Список ExpressionList имеет следующий синтаксис:
73
Expressionl, Expression2, …, ЕxpressionN
Выражения в ExpressionList могут быть любыми численными, строковыми или логическими выражениями. Выражение в ExpressionList может также определять диапазон значений при использовании оператора То:
Expression1 To Expression2
Для выбора ветвей на основе сравнения, является ли TestExpression больше, меньше или равным какому-либо значению, или на основе какого-либо другого реляционного сравнения, используйте следующий синтаксис:
Is ComparisonOperator expression
Задание 4. Напишите процедуру, содержащую вложенные операторы
If…Then…Else.
Для этого:
ü введите процедуру (листинг 12):
Листинг 12 – Использование оператора Select…Case
1Sub List4_12 ()
2' Определение скидки (в %) в зависимости от
3' количества продаваемого товара
4Dim IStr As String
5Dim IntNum As Variant
6 |
|
7 |
IntNum = Application.InputBox( _ |
8 |
Prompt:="Введите количество товара", _ |
9 |
Title:="Исходные данные", Type:=1) |
10If Not (TypeName(IntNum) = "Boolean") Then
11Select Case IntNum
12 |
Case Is > 1000 |
13 |
IStr = "10" |
14 |
Case Is > 500 |
15 |
IStr = "5" |
16 |
Case Else |
17 |
IStr = "0" |
18End Select
19MsgBox "Скидка " & IStr & "%"
20Else
21MsgBox "Количество не указано"
22End If
23End Sub
Безусловный переход
Оператор безусловного перехода, пожалуй, самый спорный оператор во всех языках программирования. В ранних языках он являлся почти единственным средством организации циклических выполнений блоков кода. Сторонники
структурного программирования посвящают много времени критике программ и
74
языков программирования, в которых используется этот оператор. Поэтому не
очень увлекайтесь применением этого оператора в своем коде и старайтесь вспоминать о нем только в чрезвычайных ситуациях, когда все другие средства уже испробованы и не помогли.
Оператор безусловного перехода всегда изменяет порядок выполнения операторов в процедуре или функции VBA. При этом VBA не проверяет никаких условий (отсюда термин безусловный (unconditional)), а просто переходит к выполнению кода с другого места.
VBA имеет только один оператор безусловного перехода: GoTo. Оператор GoTo имеет следующий синтаксис:
GoTo Name
выражение Name представляет любую допустимую метку или номер строки в той же процедуре или функции, которая содержит оператор GoTo. При выполнении оператора GoTo VBA немедленно переходит к выполнению оператора в строке, определенной с помощью Name. Метка строки (line label) – это особый тип идентификатора, который задает определенную строку по имени. Метки строк имеют следующий синтаксис:
Name:
выражение Name – любой допустимый идентификатор VBA. Метка строки может начинаться в любом столбце в строке, если она является первым непустым символом в строке. Номер строки (line number) – в основном, то же самое, что и метка строки, но он является просто номером, а не идентификатором. Использование номеров строк в процедурах VBA является крайне нежелательным, следует всегда использовать метку строки вместо них.
Использование MsgBox для обеспечения возможности выбора
До сих пор вы использовали оператор MsgBox с целью отображения сообщений для пользователя в диалоговых окнах с заголовками. Как уже отмечалось в частях 2 и 3, при помощи необязательного аргумента Buttons можно использовать VBA-процедуру MsgBox как функцию для получения выбора от пользователя в ответ на сообщения или вопросы, которые отображает ваша процедура. Для многих простых вариантов выбора использование функции MsgBox для получения ответа от пользователя является гораздо более легким,
чем получение текстового ввода с помощью функции InputBox и последующий анализ этого текста для определения того, какой выбор сделал пользователь.
При включении аргумента Buttons с необходимыми круглыми скобками оператор MsgBox работает подобно функции и отображает окно сообщения, содержащее различные командные кнопки. Число и тип командных кнопок, отображаемых диалоговым окном MsgBox, задается с помощью аргумента Buttons. Buttons указывает также кнопку по умолчанию в диалоговом окне и, содержит ли это диалоговое окно стандартные значки Windows: Critical, Information, Exclamation или Question для предупредительных сообщений и запросов пользователя (табл. 20). MsgBox возвращает численный результат, указывающий, какую командную кнопку выбрал пользователь (табл. 21).
75
Таблица 20 – Аргументы-константы функции MsgBox
|
Константа |
|
Назначение |
|
|
|
|
|
|
(числовое значение) |
|
|
|
|
|
|
|
|
vbOKOnly |
|
Отображает только кнопку OK; то же самое происходит при |
|||||
|
(0) |
|
опускании аргумента Buttons |
|
|
|||
|
vbOKCancel (1) |
Отображает кнопки OK и Отмена (OK, Cancel) |
|
|||||
|
vbAbortRetryIgnore |
Отображает командные кнопки Стоп, Повтор, Пропустить |
||||||
|
(2) |
|
(Abort, Retry, Ignore) |
|
|
|
||
|
vbYesNoCancel (3) |
Отображает кнопки Да, Нет и Отмена (Yes, No, Cancel) |
||||||
|
vbYesNo (4) |
|
Отображает кнопки Да и Нет (Yes, No) |
|
||||
|
vbRetryCancel (5) |
Отображает кнопки Повтор и Отмена (Retry, Cancel) |
||||||
|
vbCritical |
|
Отображает |
в |
диалоге |
значок |
критического |
|
|
(16) |
|
предупредительного сообщения (Critical Message) Windows |
|||||
|
|
|
(красный кружок) |
|
|
|
||
|
vbQuestion |
|
Отображает значок запроса (Query icon) Windows ("?"); |
|||||
|
(32) |
|
обычно используется, чтобы задать пользователю очень |
|||||
|
|
|
важный вопрос или выдать предупредительное сообщение, |
|||||
|
|
|
требующее ответа |
|
|
|
||
|
vbExclamation |
|
Отображает значок ("!") предупреждения (Warning |
|||||
|
(48) |
|
Message); обычно используется для отображения важной |
|||||
|
|
|
информации или предупреждения, не требующего ответа |
|||||
|
vbInformation |
|
Отображает значок ("i") информации (Information Message); |
|||||
|
(64) |
|
обычно используется для отображения важной информации, |
|||||
|
|
|
кроме предупреждения |
|
|
|||
|
vbDefaultButton1 |
Первая командная кнопка в диалоговом окне является |
||||||
|
(0) |
|
кнопкой по умолчанию |
|
|
|||
|
vbDefaultButton2 |
Вторая командная кнопка в диалоговом окне является |
||||||
|
(256) |
|
кнопкой по умолчанию |
|
|
|||
|
vbDefaultButton3 |
Третья командная кнопка в диалоговом окне является |
||||||
|
(512) |
|
кнопкой по умолчанию |
|
|
|||
|
vbDefaultButton4 |
Четвертая командная кнопка в диалоговом окне является |
||||||
|
(768) |
|
кнопкой по умолчанию |
|
|
|||
|
Таблица 21 – Возвращаемые значения-константы функции MsgBox |
|||||||
|
|
|
|
|||||
|
Константа |
Значение |
Означает, что пользователь выбирает кнопку |
|||||
|
vbOK |
1 |
|
OK |
|
|
|
|
|
vbCancel |
2 |
|
Отмена (Cancel) |
|
|
||
|
vbAbort |
3 |
|
Стоп (Abort) |
|
|
|
|
|
vbRetry |
4 |
|
Повтор (Retry) |
|
|
|
|
|
vbIgnore |
5 |
|
Пропустить (Ignore) |
|
|
||
|
vbYes |
6 |
|
Да (Yes) |
|
|
|
|
|
vbNo |
7 |
|
Нет (No) |
|
|
|
|
Задание 4. Напишите процедуру, демонстрирующую использования аргумента Buttons функции MsgBox.
76
Для этого:
ü введите процедуру (листинг 13):
Листинг 13 – Использование MsgBox и аргумента Buttons
1Sub List4_13 ()
2' Процедура демонстрирует MsgBox, используемую как функция
3Const mTitle = "Демонстрация кнопок MsgBox"
4Dim Resp As Integer
5 |
|
6 |
Resp = MsgBox(Prompt:="Выберите кнопку", _ |
7 |
Title:=mTitle, _ |
8 |
Buttons:=vbYesNoCancel + vbQuestion) |
9Select Case Resp
10Case Is = vbYes
11 |
MsgBox Prompt:="Вы выбрали кнопку 'Да'", _ |
12 |
Title:=mTitle, _ |
13 |
Buttons:=vbInformation |
14 |
Case Is = vbNo |
15 |
MsgBox prompt:="Вы выбрали кнопку 'Нет'", _ |
16 |
Title:=mTitle, _ |
17 |
Buttons:=vbInformation |
18 |
Case Is = vbCancel |
19 |
MsgBox prompt:="Вы выбрали кнопку 'Отмена'", _ |
20 |
Title:=mTitle, _ |
21 |
Buttons:=vbCritical |
22End Select
23End Sub
Процедура List4_13 () демонстрирует использование оператора MsgBox как функции, результаты различных аргументов Buttons и оценку значения, которое возвращает функция MsgBox. Диалоговое окно, в котором пользователю необходимо сделать выбор, представлено на рис. 19.
Рис. 19 Результаты работы кода этой процедуры при всех трех (по отдельности,
конечно) выборах представлены на рис. 20.
Рис. 20
77
Как только пользователь выбирает командную кнопку в окне сообщения, VBA возвращает численное значение, соответствующее выбору пользователя. В строке 6 результат функции MsgBox присваивается переменной Resp. VBA использует различные значения в зависимости от того, какую командную кнопку выбрал пользователь: одно значение для обозначения кнопки Да, другое – для обозначения кнопки Нет и еще одно – для кнопки Отмена. В строке 9 начинается оператор Select Case, который оценивает значение, возвращаемое функцией MsgBox в строке 6 и сохраняемое в переменной Resp. Тестовое выражение для оператора Select Case – это сама переменная Resp, поэтому VBA сравнивает значение в переменной Resp, чтобы проверить, совпадает ли оно с каким-либо условием Case в операторе Select Case.
Использование оператора Exit
Для того чтобы процедура прекратила выполнение, используется форма VBA-оператора Exit.
Оператор Exit имеет следующий синтаксис:
Exit Sub
Exit Sub используется для окончания процедуры.
Использование оператора End
Одним из хороших принципов программирования является принцип модульности. Процедура не должна содержать бесконечно длинный код, части которого выполняют совершенно не связанные между собой задачи. Следует помещать в каждую процедуру небольшой и функционально законченный код, который легко читать и сопровождать. Например, хорошо понимается код со следующей структурой:
Sub ГлавнаяПроцедура()
Call Процедура1 'Вызов процедуры Процедура1
Call Процедура2 'Вызов процедуры Процедура2
End Sub
Sub Процедура1()
'Код процедуры
End Sub
Sub Процедура2()
'Код процедуры
End Sub
Обратите внимание на то, что в этих фрагментах кода процедуры не возвращают никаких результатов свой работы. Это может быть только в случае, когда эти процедуры по очереди обрабатывают какие-то общие данные, выполняя над ними определенные действия. Результатами этих действий могут быть либо сами преобразованные данные, либо новые (и тоже общие) данные.
Контрольные вопросы
1. Что такое условный и безусловный переход?
78
2.Какие вы знаете инструкции условного перехода?
3.Какие вы знаете инструкции безусловного перехода?
4.Каким термином пользуются при описании ситуации, когда одну инструкцию If…Then или If…Then…Else размещают внутри другой инструкции?
5.Сколько предложений ElseIf может содержать инструкция
If…Then…Else?
6.Сколько предложений Case можно включать в инструкцию Select…Case?
7.Какой цели служит аргумент Buttons функции MsgBox?
8.Для чего используется инструкция Exit Sub?
Часть 5. ПОВТОРЕНИЕ ДЕЙСТВИЙ В VBA: ЦИКЛЫ
Теперь, когда вы научились выбирать различные действия на основе предопределенных условий, вы узнаете, что необходимо делать, чтобы процедуры VBA повторяли действия заданное количество раз или пока выполняется (или не выполняется) некоторое условие.
Для организации циклов VBA предоставляет несколько мощных и гибких структур, позволяющих легко повторять различные действия. Программные структуры, приводящие к неоднократному повторению одного или нескольких операторов, называются структурами организации циклов, потому что поток
выполнения операторов процедуры проходит циклично по одним и тем же операторам неоднократно.
Процесс выполнения всех операторов, заключенных в структуру цикла, один раз называется итерацией (iteration) цикла. Некоторые структуры цикла организуются так, что они всегда выполняются заданное количество раз. Структуры цикла, всегда выполняющиеся заданное количество раз, называются циклами с фиксированным числом итераций (fixed iteration). Другие типы
структур цикла повторяются переменное количество раз в зависимости от некоторого набора условий. Поскольку количество раз повторений этих гибких структур цикла является неопределенным, такие циклы называются
неопределенными циклами (indefinite loops).
Существуют два основных способа создания неопределенного цикла. Можно построить цикл так, что VBA будет тестировать некоторое условие (детерминант цикла) перед выполнением цикла. А также можно построить цикл таким образом, что VBA будет тестировать условие детерминанта цикла после выполнения операторов в цикле.
Тело (body) цикла – это блок операторов VBA, находящийся между началом и концом цикла.
Можно также создать неопределенный цикл таким образом, чтобы он не имел условия детерминанта вообще; циклы, не имеющие условия детерминанта, повторяются бесконечно и называются бесконечными циклами (infinite loops). Бесконечный цикл не заканчивается никогда (для прерывания VBA нажмите клавишу Esc или комбинацию клавиш Ctrl+Break); большинство бесконечных циклов являются результатом ошибок программирования, хотя имеется несколько случаев, когда удобно использовать бесконечные циклы.
79
Лабораторная работа № 5. Операторы циклов
Цель занятия: Знать операторы циклов For…Next, Do… Уметь
использовать вложенные циклы
Материалы к занятию: MS Excel 2003.
Использование цикла For…Next
Используйте цикл For…Next, когда вам необходимо повторить действие или ряд действий заданное количество раз, известное до начала выполнения цикла. Цикл For…Next имеет следующий синтаксис:
For Counter = Start To End [Step StepSize]
Statements
[Exit For]
Next [Counter]
здесь counter – любая численная переменная VBA; Start – любое численное выражение и определяющее начальное значение для переменной Counter; End – это также численное выражение, определяет конечное значение для переменной Counter. По умолчанию VBA увеличивает переменную Counter на 1 каждый раз при выполнении операторов в цикле (считает количество циклов). Можно задавать другое значение (StepSize), на которое будет изменяться Counter, включая необязательное ключевое слово Step. При включении ключевого слова Step необходимо задавать значение для изменения переменной Counter. В указанной синтаксической конструкции StepSize представляет любое численное выражение и определяет значение для изменения переменной Counter. Досрочно завершить цикл For…Next можно с помощью оператора Exit For. Statements представляет один, несколько или ни одного оператора VBA. Эти операторы составляют тело цикла For; VBA выполняет каждый из этих операторов при каждом выполнении цикла. Ключевое слово Next сообщает VBA о том, что достигнут конец цикла; необязательная переменная Counter после ключевого слова Next должна быть той же самой переменной Counter, которая была задана после ключевого слова For в начале структуры цикла. Включайте необязательную переменную Counter после ключевого слова Next для улучшения читабельности программного кода (особенно при использовании вложенных циклов For…Next) и для повышения скорости выполнения кода (иначе VBA придется потратить время на определение того, какая переменная Counter является правильной, для ее изменения после достижения ключевого слова Next).
Изображение оператора For…Next на блок-схеме:
Counter=Start, End, StepSize
Statements
Counter
80