[an error occurred while processing this directive]

В начало

Введение

1-й час. Знакомство с Visual Basic for Applications

2-й час. Работа с макросами

3-й час. Работа с элементами управления

4-й час. Переменные и константы

5-й час. Ввод данных

6-й час. Логика условных операторов

7-й час. Циклические вычисления

8-й час. Введение в объекты

9-й час. Основные объекты Excel

10-й час. Объект Range

11-й час. Редактор Visual Basic

12-й час. Отладка программ

13-й час. Обработка ошибок

14-й час. Экранные формы

15-й час. Автоматизация экранных форм

16-й час. Панели инструментов

17-й час. Работа с меню

18-й час. Диаграммы

19-й час. Сводные таблицы

20-й час. Получение внешних данных

21-й час. Доступ к данным с помощью ADO

22-й час. Еще об ADO

23-й час. Автоматизация

24-й час. Выполнение процедур

Приложение. Ответы

7-й час. Циклические вычисления

Допустим, в приложении необходимо выполнить одну и ту же последовательность действий 15 раз. Неужели для этого необходимо 15 раз повторять запись одной и той же последовательности операторов? Нет! Но чтобы избежать такой участи, надо организовать циклические вычисления. Циклические вычисления, или просто циклы, позволяют повторять выполнение одной группы операторов любое необходимое число раз. В этом часе вы изучите операторы Do… Loop и For… Next, используемые для организации циклических вычислений.

В этом часе будут рассмотрены следующие вопросы.

  • Выполнение оператора For.
  • Использование оператора Do... Loop.

Оператор For…Next

При создании программ вам рано или поздно придется повторно выполнять один и тот же набор операторов заданное число раз. Для организации повторных вычислений используется оператор For... Next, имеющий следующий синтаксис:

For счетчик = начало То конец [Step шаг]

[операторы]

[Exit For]

[операторы]

Next [счетчик]

Число выполнений этого оператора определяется параметрами начало и конец. Переменная счетчик при первом выполнении цикла имеет значение начало и каждый раз при выполнении оператора Next увеличивается на величину, заданную параметром шаг. Если этот необязательный параметр опущен, значение счетчик увеличивается на единицу. Параметр шаг может быть любым действительным числом, как целым, так и дробным, как положительным, так и отрицательным. (Отметим, что в зависимости от типа данных значений начало, конец и шаг объявляется соответствующий тип переменной счетчик.) Если параметр шаг положительный или опущен, то при превышении значения переменной счетчик значения параметра конец прекращается выполнение цикла. Необязательный оператор Exit For служит для экстренного прекращения цикла и обычно вкладывается в оператор If или Select Case.

Для экспериментов с оператором For... Next откройте новую рабочую книгу и сохраните ее под именем Час7. С помощью комбинации клавиш <Alt+F11> откройте редактор Visual Basic. Выполните следующие действия для создания простого примера с использованием оператора For... Next.

  1. В окне проектов Project Explorer щелкните правой кнопкой мыши на элементе ЭтаКнига и выполните команду Insert > Module (Вставка > Модуль).
  2. Вставьте новую процедуру и назовите ее Сигнал. Эта процедура должна исполнять звуковой сигнал компьютера заданное число раз.
  3. Введите следующий код процедуры:

Dim iCounter As Integer

For iCounter = 1 To 15

 Beep

Next

  1. Нажмите клавишу <F5> для выполнения процедуры. Вы должны услышать звуковой сигнал.

В качестве эксперимента с оператором For измените число 15, например на 5 или 10000, чтобы увидеть (точнее, услышать) разницу. Если сравнить приведенный оператор For с его синтаксисом, то нетрудно заметить, что опущен элемент Step шаг. Рассмотрим еще один пример оператора For, где параметр шаг принимает отрицательное значение, осуществляя таким образом обратный счет значения переменной счетчик оператора For.

  1. Вставьте новую процедуру и назовите ее ОбратныйСчет. Эта процедура будет выводить последовательность окон сообщения, показывающих значения переменной iCounter (счетчик) при отсутствии параметра шаг и при его отрицательном значении.
  2. Введите код процедуры ОбратныйСчет:

Dim iCounter As Integer

For iCounter = 1 To 3

 MsgBox “Счет вперед: “ & iCounter

Next

For iCounter = 3 To 1 Step -1

 MsgBox “Обратный счет: “ & iCounter

Next

  1. Выполните процедуру. Вы увидите первое окно сообщения (рис. 7.1), показывающее, что текущее значение переменной iCounter равно 1.
  2. Щелкните в этом окне на кнопке ОК и затем таким же образом закройте следующие два окна сообщения. Далее должно появиться окно сообщения, показанное на рис. 7.2. В этом окне видно, что первоначальное значение счетчика равно 3.
  3. Щелкните на кнопке ОК. В последующих двух окнах значение счетчика каждый раз будет уменьшаться на единицу.
  4. Щелкайте на кнопке ОК в окнах сообщений, пока не завершится выполнение процедуры.

Рис. 7.1. Текст этого окна показывает, что первое значение счетчика равно 1

Рис. 7.2. В каждом последующем окне сообщения значение счетчика будет меньше, чем в предыдущем

Чтобы показать другие возможности применения оператора For, создадим еще одну процедуру, вычисляющую сложные проценты на вклады и конечную величину вклада при 10% годовых. Выполните следующее.

  1. Вставьте новую процедуру и назовите ее Вклад.
  2. Введите код процедуры:

Dim iNumberOfYears As Integer

Dim cSavings As Currency

Dim iCounter As Integer

cSavings = InputBox(“Введите сумму вклада:”)

iNumberOfYears = InputBox(“Введите число лет, на которые помещается вклад:”)

For iCounter = 1 То iNumberOfYears

 cSavings = cSavings * 1.1

Next

MsgBox “3a “ & iNumberOfYears & “ лет вы получите по вкладу “ & _

 Format(cSavings,”0.00”) & “ рублей”

  1. Выполните процедуру Вклад.
  2. Введите число 1000 в качестве суммы вклада.
  3. Введите число 10 как число лет, на которые помещается вклад. Следующее окно покажет общую сумму вклада за 10 лет. Вы не ожидали, что эта сумма составит 2593,74 рубля?
  4. Чтобы закрыть соблазняющее вас окно, щелкните на кнопке ОК.

В этой процедуре для вычисления конечного значения (переменная cSavings) используется переменная iNumberOfYears, задающая, сколько раз будет выполняться цикл. Вы, наверное, заметили новый оператор Format (cSavings, “0.00”), который преобразует значение переменной cSavings в формат с двумя десятичными разрядами.

Оператор Do... Loop

Для выполнения оператора For необходимо задать параметры (эти параметры могут вычисляться или задаваться во время выполнения программы, как в последней процедуре), которые точно определяют, сколько раз должен выполняться оператор цикла. Иногда это свойство оператора For является ограничительным, и в этом случае VBA предлагает другой оператор - Do... Loop, который также может организовать повторяющиеся вычисления, но момент прекращения вычислений здесь определяется с помощью логических условий. Существует два типа операторов Do: Do While и Do Until. Первый из них повторяет выполнение блока операторов до тех пор, пока заданное логическое условие истинно. Второй оператор, Do Until, выполняет циклические вычисления до тех пор, пока изначально ложное логическое условие не станет истинным. Синтаксис этих операторов следующий.

Синтаксис 1:

Do [{While | Until} условие]

 [операторы]

 [Exit Do]

 [операторы]

Loop

Синтаксис 2:

Do

 [операторы]

 [Exit Do]

 [операторы]

Loop [{While | Until} условие]

Различие между этими двумя синтаксисами весьма тонкое. В соответствии с синтаксисом 1 логическое условие помещается в начало цикла. В этом случае, если логическое условие не выполняется, то операторы цикла не выполняются ни разу. Во втором синтаксисе логическое условие помещено в конце цикла. Поэтому операторы цикла в любом случае будут выполнены хотя бы один раз. Оператор Exit Do используется для экстренного выхода из цикла, обычно для этого применяются условные операторы If и Select Case.

Для создания процедуры с использованием оператора Do выполните следующие действия.

  1. Вставьте в текущий модуль новую процедуру и назовите ее ВводИмени. В этой процедуре пользователю предлагается ввести свое имя или выйти из программы.
  2. Введите код процедуры:

Dim sName As String

Dim iResponse As Integer

sName = “”

Do While sName = “”

 sName = InputBox(“Введите свое имя: “)

 If sName = “” Then

 iResponse = MsgBox (“Вы хотите выйти из программы?”, vbYesNo)

  If iResponse = vbYes Then

   Exit Do

  End If

 End If

Loop

Как вы помните, при щелчке на кнопке Отмена функция InputBox возвращает пустую строку, а метод Application.InputBox - значение False (Ложь).

  1. Выполните процедуру.
  2. В окне ввода щелкните на кнопке Отмена или, не вводя значения, нажмите клавишу <Enter>. Появится окно сообщения, спрашивающее, хотите ли вы выйти из программы.
  3. Щелкните на кнопке Нет. Окно ввода появится снова. Введите свое имя и нажмите клавишу <Enter>. Процедура закончится.

В 4-м часе "Переменные и константы" мы познакомились с массивами, а также с такой их разновидностью, как динамические массивы. Динамические массивы позволяют изменять свои размеры во время выполнения программы. Их часто используют совместно с оператором Do... Loop, как показано в следующем примере.

  1. Вставьте новую процедуру с именем СписокИмен. Эта процедура предназначена для ввода списка имен (количество имен заранее не известно), которые записываются в динамический массив.
  2. Код процедуры СписокИмен следующий:

Dim iCount As Integer

Dim sNames() As String

Dim iResponse As Integer

Dim i As Integer

iResponse = vbYes

Do While iResponse = vbYes

 iCount = iCount + 1

 ReDim Preserve sNames(iCount) As String

 sNames(iCount) = InputBox("Введите имя")

 If sNames(iCount) = "" Then

  iResponse = MsgBox("Продолжить?", vbYesNo)

  If iResponse = vbYes Then

   sNames(iCount)= InputBox ("Введите имя")

  End If

 End If

Loop

For i = 1 To iCount - 1

 MsgBox i & "-e имя "&" - "& sNames(i)

Next

  1. Выполните процедуру. Первое окно ввода показано на рис. 7.3.
  2. Введите три имени, нажимая после ввода каждого клавишу <Enter>.
  3. Щелкните на кнопке Отмена. Появится окно сообщения с вопросом "Продолжим?".
  4. Щелкните на кнопке Нет. Появится новое окно сообщения с первым введенным именем.
  5. Щелкните на кнопке ОК. Отобразится следующее окно сообщения со вторым введенным именем.
  6. Щелкните на кнопке ОК. Отобразится окно сообщения с третьим введенным именем.
  7. Щелкните на кнопке ОК. Выполнение процедуры закончится.

Рис. 7.3. Первое окно ввода.

Полный код процедуры СписокИмен приведен в листинге 7.1.

Листинг 7.1. Процедура СписокИмен

1: Public Sub СписокИмен()

2:  Dim iCount As Integer

3:  Dim sNames() As String

4:  Dim iResponse As Integer

5:  Dim i As Integer

6:

7:  iResponse = vbYes

8:

9:  Do While iResponse = vbYes

10:   iCount = iCount + 1

11:   ReDim Preserve sNames(iCount) As String

12:    sNames(iCount) = InputBox("Введите имя")

13:   If sNames(iCount) = " " Then

14:    iResponse = MsgBox("Продолжим?", vbYesNo)

15:    If iResponse = vbYes Then

16:     sNames(iCount) = InputBox("Введите имя")

17:    End If

18:   End If

19:  Loop

20:

21:  For i = 1 To iCount - 1

22:   MsgBox i & "-e имя" & " - " & sNames(i)

23:  Next

24: End Sub

Прежде всего обратите внимание в этом листинге на объявление переменных:

Dim iCount As Integer

Dim sNames() As String

Dim iResponse As Integer

Dim i As Integer

Переменная iCount используется для управления размером массива и возрастает при каждом выполнении цикла. sNames - динамический массив, который изменяет свои размеры во время выполнения цикла. Переменная iResponse следит за тем, хочет ли пользователь продолжать ввод имен. Значение этой переменной - фактор, управляющий завершением цикла. Переменная i является счетчиком цикла For при выводе окон сообщений с именами. После объявления переменных присваивается значение переменной iResponse:

iResponse = vbYes

Когда этой переменной присвоено значение, все готово к началу цикла:

Do While iResponse = vbYes

Поскольку переменной iResponse присвоено значение vbYes, то цикл Do выполнится по крайней мере один раз. При первом выполнении цикла переменная iCount принимает значение 1, при втором - 2 и т.д. Значение переменной iCount используется для задания нового размера массива sNames. Отметим, что массив изменяет свой размер без потери значений, которые уже в нем содержатся:

iCount = iCount + 1

ReDim Preserve sNames(iCount) As String

sNames(iCount) = InputBox("Введите имя")

Следующая группа операторов используется для того, чтобы узнать, сознательно ли пользователь щелкнул на кнопке Отмена, чтобы прекратить ввод имен, или случайно нажал клавишу <Enter>, не введя никакого значения:

If sNames(iCount) = " " Then

 iResponse = MsgBox("Продолжим?", vbYesNo)

 If iResponse = vbYes Then

  sNames(iCount) = InputBox("Введите имя")

 End If

End If

После завершения цикла Do выполняется цикл For для вывода последовательности окон сообщений с введенными ранее именами:

For i = 1 То iCount - 1

 MsgBox i & "-e имя" & " - " & sNames(i)

Next

Количество повторений цикла For задается выражением i = 1 То iCount - 1. Необходимость вычитания единицы из значения переменной iCount возникла из-за того, что эта переменная изменяет свое значение в начале цикла Do еще до проверки условий, по которым заканчивается этот цикл. Если вы хотите посмотреть, что получится, если не вычитать единицу из переменной iCount, удалите -1 в операторе For и выполните процедуру сначала. В конце выполнения процедуры вы получите лишнее окно сообщения с обычным текстом вывода имен, но без самого имени.

Резюме

В этом часе мы изучили механизмы VBA для создания циклических вычислений (операторы циклов For и Do) и на примерах показали способы их применения. Мы также рассмотрели пример совместного использования динамических массивов и операторов цикла.

Вопросы и ответы

Вопрос. Каково основное назначение циклических операторов?

Ответ. Многократное выполнение группы операторов.

Вопрос. Как определить, помещать условия в начале оператора цикла Do... Loop или в конце?

Ответ. Ответьте на такой вопрос: "Какое минимальное число раз должны выполняться операторы цикла?". Если вы ответите, что один раз, тогда условие поместите в конце цикла, если ответите, что ни одного, то в этом случае условие должно стоять в начале цикла.

Практикум

С помощью тестов и упражнений вы проверите, насколько хорошо усвоили изложенный материал. Ответы на вопросы смотрите в Приложении.

Тесты

  1. Назовите два основных типа операторов цикла в VBA.
  2. Какой оператор позволяет досрочно выйти из цикла?
  3. Какие есть два типа оператора Do... Loop?
  4. Истинно или ложно следующее утверждение: логическое условие для оператора Do... Loop должно располагаться только в начале оператора?

Упражнение

С помощью оператора For создайте процедуру с именем РабочиеЧасы, которая позволяет вводить для пяти дней недели количество часов, отработанных в эти дни. Процедура также должна выводить окно сообщения с суммарным количеством рабочих часов за неделю.

Создайте другую процедуру и назовите ее Зарплата. Процедура должна считать недельную зарплату при условии почасовой оплаты. Предположим, что минимальная оплата рабочего часа составляет 6 у.е. Примените оператор Do... Loop для управления окном ввода, где пользователь должен ввести собственную почасовую ставку. Используйте суммарное количество рабочих часов в неделю, подсчитанное процедурой РабочиеЧасы. Итоговое значение выведите на экран с помощью окна сообщения.

Совет: объявите переменную, содержащую суммарное количество рабочих часов в неделю, как глобальную (Public) переменную.

Выполните сначала процедуру РабочиеЧасы, а затем - Зарплата.

[an error occurred while processing this directive]