Циклы типа Do – Loop While
Чтобы выполнить тело цикла хотя бы один раз, нужно использовать вторую форму оператора типа Do While. В данном случае условие помещается в самом конце цикла, после ключевых слов Loop While. Такое размещение условия указывает программе, что она должна вначале выполнить операторы цикла, а затем проверить условие на истинность. Ниже приведён фрагмент кода, определяющим является ли число простым (простое число делится без остатка только на единицу и само на себя).
Dim N as Long ‘заданное число
Dim D as Long ‘делитель
Dim Sim as Boolean ‘флаг простого числа
N = txtN ‘считывание числа из текстового поля txtN
S = True ‘число является простым
D = 2 ‘начальное значение делителя
Do ‘начало цикла
If N mod D = 0 Then S = False ‘если число N делится без остатка на D,
‘то число N непростое
D = D + 1 ‘увеличение делителя на единицу
Loop While D < N Or S ‘выполнение цикла до тех пор, пока
‘делитель меньше заданного числа или число простое
В начале приведённого фрагмента кода делается утверждение, что заданное число N – простое (S = True). Начальное значение делителя D устанавливается равным двойке (D = 2). Далее в операторе цикла осуществляется поиск значения делителя D в диапазоне от 2 до N-1, на которое число N делится без остатка. Цикл выполняется до тех пор, пока делитель D находится в заданном диапазоне и флаг простого числа S равен True.
Цикл завершается тогда, когда делитель D становится равным N или значение флага S равным False. Нетрудно видеть, что цикл завершится при первом делении без остатка, не доходя до конца диапазона, что уменьшает количество операций. Если в заданном диапазоне не найдено ни одного делителя, то оператор S = False не будет выполнен ни разу и значение флага так и останется равным True.
Используя данную форму оператора типа Do While, будьте особенно внимательны, поскольку тело цикла выполняется первый раз без проверки указанного условия. Если тело цикла содержит операторы , которые могут выполняться с ошибками, то лучше использовать оператор цикла с предусловием.
Внимание! Не помещайте условие одновременно в начало и конец цикла, после ключевых, слов Do While и Loop While, поскольку это вызовет ошибку в момент запуска программы.
Циклы типа Do Until
Циклы типа Do Until работают аналогично рассмотренным выше циклам Do While за одним исключением. Тело цикла типа Do Until будет выполняться, только если условие будет ложным, тогда как циклы типа Do While выполняются только в случае истинности условия. Таким образом, как только условие становится истинным, цикл типа Do Until прекращает свою работу. Также как и для циклов типа Do While, существует две формы циклов типа Do Until. Они отличаются местом расположения условия – в заголовке цикла (в операторе Do Until), либо в конце цикла (в операторе Loop Until). Если условие находится в начале цикла в операторе Do, то оно проверяется перед выполнением цикла. Если же условие помещается в конце цикла, в операторе Loop, то оно проверяется после выполнения цикла. Таким образом, в последнем случае цикл будет выполнен хотя бы один раз, тогда как в первом случае он может ни разу не быть выполнен.
Приведённый ниже фрагмент кода считывает значение положительного целого числа из текстового поля txtN, разлагает это число на простые множители и добавляет эти множители в список lstMul.
Dim N as Integer ‘заданное число
Dim D as Integer ‘делитель
N = txtN ‘считывание числа из текстового поля txtN
D = 2 ‘начальное значение делителя
Do ‘начало цикла
Do While N mod D = 0 ‘до тех пор, пока остаток от деления N на D равен нулю
N = N \ D ‘целочисленное деление N на D
lstMul.AddItem D ‘добавление D в список
Loop ‘конец оператора цикла
D = D + 1 ‘увеличение делителя на единицу
Loop Until N = 1 ‘выйти из цикла, если N = 1
Приведённый фрагмент кода содержит два цикла, вложенных друг в друга. Внешний цикл (Do … Loop Until N = 1) является циклом с постусловием. Он выполняется, по крайней мере, один раз и выполняется до тех пор, пока N не станет равным единице. Условие (N = 1) является условием выхода из цикла. Внешний цикл содержит внутренний цикл и оператор увеличения делителя D на единицу.
Внутренний цикл (Do While N mod D = 0 … Loop) является циклом с предусловием. Он проверяет, делится ли число N на D нацело и, если делится, то делит два числа друг на друга и добавляет значение делителя D в список lstMul. Эти операции продолжаются до тех пор, пока число N не перестанет делиться на число D.
Если N = 180, то оно дважды будет разделено на 2, дважды на 3, ни разу на 4 и один раз на 5. После этих операций N станет равным единице, и фрагмент кода завершит работу. В результате список будет содержать строки со значениями 2, 2, 3, 3, 5. Не трудно видеть, что эти числа являются простыми и их произведение равно 180.
В следующем фрагменте кода в процедуре проверки введённых данных программа предлагает пользователю ввести число в окне ввода InputBox до тех пор, пока он этого не сделает.
Private Sub txtN_Validate (Cancel As Boolean)
Do Until IsNumeric ( txtN ) ‘до тех пор, пока txtN – не число
‘предлагает в окне ввода ввести число и передаёт его в поле txtN
txtN = InputBox ( “Введите число” , ”Ошибка” , 5)
Loop ‘конец оператора цикла
End Sub
Циклы типа While-Wend
Если вам приходилось разбираться в чужих программах, возможно, вы сталкивались с циклом, который начинается с оператора While и заканчивается оператором Wend. Последний является сокращением от английских слов While End, что означает конец цикла типа While. Данная форма оператора цикла является устаревшей и оставлена только для совместимости с ранними версиями языка Basic. Она полностью аналогична первой форме оператора цикла типа Do While, в которой условие выполнения цикла помещается в начало. Хотя в шестой версии Visual Basic циклы While ... Wend по-прежнему поддерживаются, мы не рекомендуем ими пользоваться. Причина состоит в том, что циклы типа Do While являются более универсальными и удобными.
Совет. Рекомендуем при наборе текста программы делать отступы для операторов, расположенных внутри цикла или любой другой конструкции (например, в блоке If … Then … Else или между служебными словами For … Next). Это улучшит восприятие программы. Для создания отступа в начале строки нажмите клавишу Таb, После ввода текущего оператора и нажатия клавиши Enter для перехода на следующую строку, Visual Basic автоматически поместит курсор прямо под предыдущим оператором, соблюдая, таким образом, уровень отступа (или вложенности) операторов. Для смещения нескольких строк вправо выделите их и нажмите клавишу Tab, для смещения влево Shift+Tab. Старайтесь всегда выделять с помощью отступов начальные и конечные операторы блока кода, как это сделано во всех примерах данной книги.
Перечислимые циклы
В Visual Basic предусмотрен еще один вариант цикла, начинающегося с ключевых слов For Each. Это так называемый перечислимый тип цикла, поскольку он используется для обработки каждого элемента некоторого набора объектов. Наборы объектов могут храниться в виде коллекций.
В качестве одного из примеров коллекций можно привести коллекцию Printers. Это встроенная коллекция Visual Basic, в которой в виде объектов хранятся все установленные в системе принтеры. В приведенном ниже фрагменте программы цикл типа For Each используется для вывода значения свойства DeviceName всех системных принтеров.
Dim objPrinter As Printer
For Each objPrinter In Printers
Debug.Print objPrinter.DeviceName
Next objPrinter
В данном случае объектная переменная objPrinter выполняет роль переменной цикла, по аналогии со счетчиком для циклов типа For Next. В ней содержится ссылка на текущий обрабатываемый в цикле объект.
Циклы типа For Each можно также использовать для обработки элементов управления в форме, как показано ниже на примере.
Dim ctrl As Control ‘объявление переменной типа Control
For Each ctrl In frmMain ‘для каждого элемента управления в форме frmMain
If Left ( ctrl.Name , 3 ) = "txt" Then ‘если имя элемента управления начинается с "txt"
ctrl.BackColor = frmMain.BackColor
‘установить цвет фона элемента управления такой же, как и у формы frmMain
ctrl.Locked = True ‘заблокировать элемент управления
End If ‘конец условного оператора
Next ctrl ‘переход к следующему элементу управления
Приведённый фрагмент кода обращается ко всем элементам управления в форме frmMain и если имя элемента управления начинается с подстроки “txt” (все текстовые поля, если вы придерживаетесь соглашения о стандартных префиксах в именах элементов управления), то цвет фона элемента управления устанавливается таким же, как и у формы frmMain. Кроме того, все текстовые поля блокируются (пользователь не сможет изменить содержимое полей).