- •Министерство образования российской федерации
- •М инистерство образования российской федерации
- •Аннотация
- •Содержание
- •Тема 1. Основы программирования
- •Создание, редактирование и запуск программ
- •Переменные, константы и типы данных
- •Управляющие конструкции
- •Управляющая конструкция If…Then позволяет выполнять один или несколько операторов, если условие истинно. Можно использовать однострочный и блочный синтаксис. Например:
- •Тема 2. Введение в модели объектов
- •2.1. Обзор моделей объектов
- •2.2. Автоматизация операций с использованием объектов
- •2.3. Программирование объектов другого приложения
- •Тема 3. Объекты Microsoft Office
- •3.1. Объекты Microsoft Access
- •3.2. Объекты Microsoft Excel
- •3.3. Объекты Microsoft Power Point
- •3.4. Объекты Microsoft Word
- •Тема 4. Меню и панели инструментов
- •4.1. Средства настройки пользовательского интерфейса
- •4.2. Выбор подходящих элементов пользовательского интерфейса
- •4.3. Система меню
- •4.4. Модификация системы меню на этапе разработки
- •4.5. Модификация системы меню в период выполнения
- •4.6. Панели инструментов
- •4.7. Модификация панелей инструментов на этапе разработки
- •4.8. Модификация панелей инструментов в период выполнения
- •Тема 5. Элементы управления на базе ActiveX и диалоговые окна
- •5.1. Разработка нестандартных диалоговых окон
- •5.2. Использование нестандартных диалоговых окон
- •5.3. Работа с элементами управления в документе, листе или на слайде
- •Тема 6. Оптимизация кода
- •6.1. Основные принципы оптимизации кода
- •6.2. Оптимизация кода для Microsoft Excel
- •6.3. Оптимизация кода для Microsoft Word
- •Тема 7. Отладка и обработка ошибок
- •7.1. Создание обработчика ошибок
- •7.2. Иерархия обработчиков ошибок
- •7.3. Тестирование обработчика за счет эмуляции ошибок
- •7.4. Строчная обработка ошибок
- •7.5. Отключение обработки ошибок
- •7.6. Общие принципы отладки
- •7.7. Режимы конструктора, выполнения и прерывания
- •7.8. Окна отладки
- •7.9. Просмотр стека вызовов
- •Тема 8. Разработка приложений для Интернета и Word Wide Web
- •8.1. Термины и концепции, связанные с Интернетом
- •8.2. Работа с гиперссылками
- •8.3. Сохранение документов и объектов в формате html
- •8.4. Элемент средства просмотра Web Microsoft
- •8.5. Элемент управления Internet Transfer
- •Указывать допустимый сервер-заместитель в свойстве AccessType элемента управления Internet Transfer (таблица 8.4);
- •Элемент управления Internet Transfer автоматически настраивается на нужный протокол, заданный в первой части url. Поэтому применение метода OpenUrl или Execute не требует установки свойства Protocol.
- •8.6. Элемент управления WinSock
- •8.7. Создание персонального Web-сервера
- •Тестовые задания для закрепления материала учебного пособия
- •Рекомендуемая литература
- •Б) дополнительная литература
Управляющие конструкции
1.3.1. Операторы ветвления
Управляющая конструкция If…Then позволяет выполнять один или несколько операторов, если условие истинно. Можно использовать однострочный и блочный синтаксис. Например:
If thisVal < 0 Then thisVal = 0
If thisVal > 5 Then
thatVal = thisVal + 25
thisVal = 0
End if
В однострочной форме оператор End If не применяется. Если необходимо выполнить более одной строки кода, когда оценка условного выражения дает True, применяется блочный вариант – If … Then … End If.
Если в условии содержатся два выражения, объединенных оператором Or, то проверяется оба выражения, даже если первое уже True. Иногда это влияет на результат работы оператора; если переменная во втором выражении содержит неверное значение, в период выполнения может возникнуть ошибка.
Оператор ветвления If…Then…Else позволяет определить два блока оператора. Первый блок выполняется, когда условие истинно, а второй – когда оно ложно. Пример:
If age < 16 Then
MsgBox “You are not old enough for a license”
Else
MsgBox “You can be tested for a license”
End If
Для проверки дополнительных условий не обязательно вкладывать операторы If … Then друг в друга – можно добавить операторы ElseIf, тогда код программы станет более читаемым и лаконичным. Допустим, по условию задачи необходимо рассчитать премии сотрудникам с учетом их вклада в общее дело. Процедура типа Function из следующего примера использует для этого серию операторов ElseIf:
Function Bonus(jobClass, salary, rating)
If jobClass = 1 Then
Bonus = salary * 0.1 * rating / 10
ElseIf jobClass = 2 Then
Bonus = salary * 0.09 * rating / 10
ElseIf jobClass = 3 Then
Bonus = salary * 0.07 * rating / 10
Else
Bonus = 0
End If
End Function
Оператор If … Then … ElseIf очень гибок. Можно начать с простого оператора If … Then, а потом добавлять операторы Else и ElseIf по мере необходимости. Но если все операторы ElseIf сравнивают одно и то же выражение с разными значениями, лучше воспользоваться оператором Select Case.
Оператор ветвления Select Case заменяет серию операторов ElseIf в том случае, когда одно выражение сравнивается с несколькими значениями. Он обеспечивает ветвление по условию, аналогичное возможностям оператора If … Then … ElseIf; но делает код эффективнее и читабельнее. Например, чтобы добавить еще несколько уровней в предыдущий пример фрагмента кода, можно было бы ввести дополнительные операторы ElseIf, однако лучше переписать эту функцию на основе оператора Select Case:
Function Bonus(jobClass, salary, rating)
Select Case jobClass
Case 1
Bonus = salary * 0.1 * rating / 10
Case 2
Bonus = salary * 0.09 * rating / 10
Case 3
Bonus = salary * 0.07 * rating / 10
Case 4, 5 ‘можно включать несколько значений…
Bonus = salary * 0.05 * rating / 5
Case 6 To 8 ‘…или задавать диапазон
Bonus = 150
Case Is > 8 ’…или сравнивать с другими значениями
Bonus = 100
Case Else
Bonus = 0
End Select
End Function
В конструкции Select Case вычисляется только одно выражение – в самом ее начале. Оператор If … Then … ElseIf, напротив, позволяет проверять разные выражения в каждом ElseIf. Поэтому оператор If … Then … ElseIf можно заменить оператором Select Case, только если все ElseIf вычисляют одно выражение.
1.3.2. Операторы цикла
Цикл Do … Loop позволяет выполнять блок операторов неопределенное число раз, используется в случаях, когда заранее не известно точное количество итераций. Существует несколько вариантов этого оператора, но в каждом из них проверяется условие и по результатам проверки делается вывод о необходимости продолжения цикла. Как и в операторе If … Then, условие должно быть значением или выражением, которое можно вычислить как True или False. Если блок операторов нужно выполнять заданное число раз, используется цикл For … Next.
Оператор Do While … Loop позволяет проверить условие перед началом цикла и выполняет цикл, пока оно истинно (True). Проверяемое в цикле Do While … Loop условие рано или поздно должно стать False, иначе цикл будет бесконечным. Чтобы остановить бесконечный цикл, предусмотрено сочетание клавиш Ctrl + Break. Процедура Function из следующего примера подсчитывает число вхождений одной строки в другую, выполняя цикл до тех пор, пока не будут найдены все вхождения. Поскольку проверка осуществляется в начале цикла, тот выполняется, только если заданная строка присутствует в другой строке:
Function CountStrings(longstring, target)
Position = 1
‘возвращает True или False
Do While InStr(position, longstring, target)
Position = IntStr(position, longstring, target) + 1
Count = Count + 1
Loop
CountString = Count
End Function
Оператор Do Until … Loop позволяет проверять условие в самом начале цикла и продолжает выполнять цикл, пока оно не окажется истинным (True). Если окажется, что условие выполнено в самом начале цикла (даст True), то операторы в теле цикла пропускаются. В следующем примере цикл не выполняется, если Response равна vbNo:
Response = MsgBox (“Do you want to process more data?”, vbYesNo)
Do Until Response = vbNo
ProcessUserData ‘вызываем процедуру для обработки данных
Response = MsgBox (“Do you want to process more data?”, vbYesNo)
Loop
Если операторы цикла следует выполнить хотя бы раз, используется оператор Do … Loop While, который позволяет проверять условие в конце цикла. Операторы выполняются пока условие истинно. В следующем примере для Microsoft Excel цикл повторяется, только если метод Find находит ячейку со строкой «test». Если текст найден, ячейка выделяется синим цветом, и продолжается поиск следующей строки «test». Если таких строк больше нет, цикл завершается:
Sub MakeBlue()
Set rSearch = Worksheet (“sheet1”).Range (“a1:a10”)
Set c = rSearch. Find (“test”)
If Not c Is Nothing Then
first = c.Address
Do
c.Font.ColorIndex = 5
Set c = rsearch.FindNext (c)
Loop While (Not c Is Nothing) And (c.Address <> first)
Else
MsgBox “Not found”
End If
End Sub
В конструкции Do … Loop Until проверка осуществляется в конце цикла, поэтому цикл выполняется минимум один раз и прекращается, когда условие становится истинно (True):
Do
ProcessUserData ‘вызываем процедуру для обработки данных
Response = MsgBox (“Do you want to process more data?”, vbYesNo)
Loop Until Response = vbNo
Если заранее известно, что какой-то блок кода надо повторить определенное число раз, используется цикл For … Next. В отличие от операторов серии Do … Loop, в данном операторе используется счетчик, уменьшаемый или увеличиваемый на каждой итерации цикла. Если разновидности оператора Do … Loop завершают цикл, как только условие становится истинным или ложным, то цикл For … Next прекращается, как только счетчик достигает заданного значения. Приведенная ниже процедура Sub генерирует сигнал заданное число раз:
Sub BeepSeveral()
numBeeps = InputBox(“How many beeps?”)
For counter = 1 To numBeeps
Beep
Next counter
End Sub
По умолчанию (как и в этом примере) счетчик увеличивается на каждой итерации цикла на единицу. Ключевое слово Step позволяет изменить шаг приращения, если указывается отрицательное число - счетчик уменьшается на каждой итерации цикла. Пример процедуры Sub, использующей цикл с шагом приращения счетчика равным двум:
Sub ClearArray(ByRef ArrayToClear())
For i = LBound(ArrayToClear) To UBound(ArrayToClear) Step 2
ArrayToClear(i) = 0
Next i
End Sub
Имя переменной в операторе Next указывать не обязательно, но ее присутствие облегчает восприятие программного текста, особенно если в ходе программы используется несколько вложенных циклов For.
Цикл For Each … Next похож на цикл For … Next за исключением того, что он выполняет одну и ту же группу операторов для каждого элемента набора объектов или массива. Он используется в том случае, когда заранее не известно число элементов в наборе или когда их количество может измениться в ходе выполнения процедуры. Синтаксис оператора выглядит следующим образом:
For Each элемент In группа
операторы
Next элемент
Встретив оператор For Each … Next, Visual Basic:
Считает элемент именем первого элемента в группе (если группа не пуста).
Выполняет операторы.
Проверяет, не последний ли это элемент в группе, и, если да, завершает цикл.
Подставляет вместо элемента имя следующего элемента в группе.
Повторяет операции, описанные в пунктах 2-4 данной последовательности.
В следующем примере, для Microsoft Excel, проверяется каждая ячейка текущего региона для ячейки А1 в таблице с именем «Sheet3» и закрашивается содержимое ячейки красным цветом, если ее значение меньше -1:
For Each c In Worksheets(“sheet3”).Range(“a1”).CurrentRegion.Cells
If c.Value < -1 Then c.Font.ColorIndex = 3
Next c
А в примере для Word просматриваются все исправления в выделенном тексте и поочередно принимаются:
For Each myRev In Selection.Range.Revisions
myRev.Accept
Next myRev
Указывать имя переменной после Next не обязательно, но это облегчает восприятие текста в программе, особенно при наличии нескольких встроенных циклов For Each.
Если необходимо удалить все объекты из набора, следует использовать цикл For … Next, а не For Each … Next. Например, необходимо удалить все слайды из текущей презентации:
Set allSlides = ActivePresentation.Slides
For s = allSlides.Count To 1 Step -1
allSlides.Item(s).Delete
Next
Но код, приведенный ниже, работать не будет – он удалит каждый второй слайд в презентации:
For Each s In ActivePresentation.Slides
s.Delete
Next
Применяя оператор For Each … Next, следует помнить о следующих ограничениях:
в случае наборов элементом может быть переменная типа Variant, Object или конкретного объектного типа из библиотеки объектов, а для массивов – только Variant;
оператор For Each … Next не годится для массивов пользовательских типов, так как в переменную типа Variant нельзя записать значение пользовательского типа.
1.3.3. Вложение управляющих конструкций
Управляющие конструкции можно включать друг в друга, например, вставить блок If … Then внутрь цикла For Each … Next, который в свою очередь находится в другом блоке If … Then и т.д. Такие конструкции называются вложенными.
В следующем примере просматривается заданный диапазон ячеек и подсчитывается число ячеек, содержащих определенное значение:
Function CountValues(rangeToSearch, searchValue)
If TypeName(rangeToSearch) <> “Range” Then
MsgBox “You can search only a range of cells”
Else
For Each c In rangeToSearch.cells
If c.Value = searchValue Then
counter = counter + 1
End If
Next c
End If
CountValues = counter
End Function
Первый оператор End If закрывает внутренний блок If … Then, а последний оператор End If – внешний. По аналогии, в случае вложенных циклов For … Next и For Each … Next операторы Next автоматически применяются к ближайшему предыдущему оператору For или For Each. Вложенные конструкции Do … Loop ведут себя сходным образом.
1.3.4. Выход из циклов и процедур
Обычно процедуры и циклы в макросах выполняются от начала до конца. Но бывают ситуации, когда досрочный выход из процедуры или цикла ускоряет работу за счет отказа от ненужных повторений.
Например, осуществляя поиск в массиве в цикле For … Next и найдя нужное значение уже на первой итерации, нет смысла просматривать остальную часть массива – разумнее тут же прекратить цикл и перейти к следующим за ним оператором. Если при выполнении процедуры происходит ошибка, делающая бессмысленным выполнение остальных ее операторов, то, естественно, надо немедленно выйти из процедуры. Для таких случаев предназначен оператор Exit.
Хотя оператор Exit достаточно удобен, использовать его следует только при крайней необходимости, а не при нормальном ходе выполнения процедуры или цикла. Злоупотребление оператором Exit затруднит чтение и отладку кода.
Кроме того, для пропуска части кода можно придумать и более подходящие способы. Например, при поиске значения в массиве внутрь цикла For … Next вместо оператора Exit можно поставить оператор Do … Loop, чтобы поиск шел только до тех пор, пока текущее значение индекса меньше верхней границы массива и значение переменной типа Boolean равно False. Когда искомое значение найдено, переменная типа Boolean устанавливается как True, и цикл прекращается:
i = LBound(searchArray)
ub = UBound(searchArray)
foundIt = False
Do
If searchArray(i) = findThis Then foundIt = True
i = i + 1
Loop While i <= ub And Not foundIt
Для досрочного выхода из оператора Do … Loop используется оператор Exit Loop, а для досрочного выхода из цикла For – оператор Exit For:
For Each c In rangeToSearch
If c.Value = searchValue Then
found = True
Exit For
End If
Next
Для досрочного выхода из процедур служат операторы Exit Sub и Exit Function:
For Each c In rangeToSearch
If c.Value = searchValue Then
counter = counter + 1
ElseIf c.Value = “Bad Data” Then
countValues = Null
Exit Function ‘прекратить проверку и немедленно выйти
End If
Next c