Безусловный переход. Оператор GoTo
Для безусловного перехода на некоторый оператор в программах на VBA используется оператор GoTo, за которым указывается метка оператора, к которому требуется перейти. Эта же метка указывается перед оператором, к которому требуется перейти. Между меткой и оператором указывается двоеточие.
Пример 4.5 – В программу вводится для некоторых вычислений число x, причем требуется, чтобы оно было не меньше 0 и не больше 100. Если вводится число меньше 0 или больше 100, то программа должна выводить сообщение об ошибке и завершать работу.
Sub primer4_5a()
Dim x As Single
x = InputBox("Введите число")
If (x < 0) Or (x > 100) Then GoTo oshibka
… ‘операторы вычислений с переменной x
GoTo konec
oshibka: MsgBox (“Введена недопустимая величина”)
konec: End Sub
Здесь oshibka и konec – метки. Если верно одно из условий x < 0 или x > 100, то выполняется переход на метку oshibka. Если ни одно из этих условий не верно, то выполняются операторы вычислений, а затем – переход на метку konec (это требуется, чтобы не выводилось сообщение об ошибке).
Эту задачу можно решить и многими другими способами, в том числе и без операторов GoTo, например, так:
Sub primer4_5b()
Dim x As Single
x = InputBox("Введите число")
If (x >= 0) And (x <= 100) Then
… ‘операторы вычислений с переменной x
Else
MsgBox (“Введена недопустимая величина”)
End If
End Sub
Цикл ДО. Оператор For
Цикл ДО (т.е. цикл, повторяющийся заданное количество раз) реализуется в VBA оператором For, имеющим следующий вид:
For переменная_цикла = начальное_значение To конечное_значение Step шаг
операторы, составляющие цикл
Next переменная_цикла
При выполнении такого оператора переменная цикла сначала принимает указанное начальное значение. Затем выполняются операторы, составляющие цикл. После этого вычисляется следующее значение переменной цикла: к ее текущему значению прибавляется величина шага. Если слово Step (а значит, и величина шага) не указано, то переменная изменяется с шагом, равным 1. Снова выполняются операторы, составляющие цикл. Процесс завершается, когда переменная цикла превышает конечное значение.
Пример 4.6 – Программа, вычисляющая сумму всех четных чисел от 0 до 100, т.е. 0+2+4+6+…+100.
Sub primer4_6()
sum = 0
For x = 0 To 100 Step 2
sum = sum + x
Next x
MsgBox(“Сумма = ” & sum)
End Sub
Пример 4.7 – Программа, вычисляющая и выводящая на экран значения ex для x=1, 4, 7, 10, 13, 16, 19.
Sub primer4_7()
For x = 1 To 19 Step 3
y = exp(x)
MsgBox(“x = ” & x & “ y = ” & y)
Next x
End Sub
Массивы
Массив в языке VBA, как и в других языках – объект программы, состоящий из нескольких элементов. Массивы необходимо объявлять в начале программы с помощью оператора Dim. Например, следующее объявление
Dim a(1 To 6) As Integer, b(1 To 3, 1 To 10) As Single, c (1 To 6, 1 To 3) As String
означает, что переменная a – одномерный массив, который может содержать не более шести элементов (целых чисел, так как указан тип Integer). Переменная b– двумерный массив из трех строк и десяти столбцов; элементы этого массива – вещественные числа (тип Single). Переменная c – массив из шести строк и трех столбцов; его элементы – строки символов.
Использование переменных для указания размеров массивов в операторе Dim не допускается. Например, объявление Dim a(1 To m) As Integer недопустимо, даже если переменной m уже присвоено некоторое значение.
Во многих случаях удобно задавать размеры массива не в операторе Dim (т.е. не в начале программы), а позже, в ходе выполнения программы. Для этого используется оператор ReDim. Массив в этом случае называется динамическим.
Пусть требуется использовать в программе массив из целых чисел, но количество этих чисел сначала неизвестно (например, его нужно запрашивать у пользователя). Объявление массива в этом случае может быть следующим:
Dim a() As Integer, m As Byte
m = InputBox ("Введите количество элементов массива ")
ReDim a(1 To m)
Как видно из этого примера, для указания размеров динамического массива можно использовать переменные. Если массив объявлен как динамический, то изменять его размеры, используя оператор ReDim, можно неоднократно.
При обращении в программе к отдельным элементам массива номера элементов указываются в круглых скобках. Если массив двумерный, то сначала указывается номер строки, затем – номер столбца. Примеры:
a(2) = 15
b(2,7) = 8.3
c(1,4) = “Минск”
Здесь второму элементу массива a присвоено значение 15. Элементу массива b, расположенному во второй строке и седьмом столбце, присвоено значение 8,3. Элементу массива c, расположенному в первой строке и четвертом столбце, присвоено значение “Минск”.
Пример 4.8 – Программа запрашивает количество элементов, которые должны содержаться в одномерном массиве (имя массива – a, максимально допустимое количество элементов – 20), затем – сами элементы массива a. Запрашивается также некоторое число x. Все элементы массива a, превосходящие x, умножаются на два. Подсчитывается также количество элементов, которые потребовалось умножить.
Sub primer4_8a()
Dim a(1 To 20) As Single, x As Single, m As Byte
m = InputBox("Введите количество элементов: ")
MsgBox(“Вводите элементы массива”)
For i = 1 To m
a(i) = InputBox("a(" & i & "): ")
Next i
x = InputBox("Введите число x: ")
For i = 1 To m
If a(i) > x Then
a(i) = a(i)*2
umnozheno = umnozheno + 1
End If
Next i
MsgBox(“Измененный массив ”)
For i = 1 To m
MsgBox("a(" & i & ") = " & a(i))
Next i
MsgBox ("Умножено: " & umnozheno)
End Sub
Здесь оператор Dim – объявление переменных: массива a и обычных (скалярных) переменных x и m. Запись Dim a(1 To 20) As Single означает, что переменная a – одномерный массив, который может содержать не более двадцати элементов. Эти элементы могут быть как целыми, так и дробными числами (тип данных Single).
Для обработки массива используются циклы. Например, для ввода элементов массива a применяется следующий цикл:
For i = 1 To m
a(i) = InputBox("a(" & i & "): ")
Next i
Здесь переменная i принимает сначала значение 1. При i=1 выполняется оператор InputBox, т.е. вводится значение первого элемента массива a(1). Затем выполняется оператор Next i, где переменная i принимает значение 2. Цикл повторяется: запрашивается элемент a(2). Аналогично вводятся остальные элементы.
Затем в программе выполняются еще два цикла. В одном из них каждый элемент массива сравнивается с переменной x, и если выполняется условие a(i) > x, то умножается на два. В последнем цикле элементы измененного массива выводятся на экран.
Примечание – Приведенная в примере 4.8 реализация программы имеет ряд недостатков. Так, массив a в любом случае хранится в памяти компьютера как массив из двадцати элементов, даже если фактическое количество элементов массива (т.е. значение переменной m) меньше. В то же время ввести значение переменной m, превышающее 20, нельзя: при выполнении цикла произойдет выход за объявленную границу массива, и программа будет прервана с выдачей сообщения об ошибке. Разрешить эти проблемы можно, используя динамические массивы. В этом случае начало программы будет иметь следующий вид:
Sub primer4_8b()
Dim a() As Single, m As Byte
m = InputBox("Введите количество элементов: ")
ReDim a (1 To m)
Теперь размер массива a может быть любым, в зависимости от введенного значения переменной m.
Пример 4.9 – В программе вводится одномерный массив a и некоторое число x (аналогично примеру 4.8). Из элементов массива a должны составляться два новых массива: в один из них включаются все элементы, превышающие x, а в другой – все остальные.
Sub primer4_9()
Dim a() As Single, bol() As Single, men() As Single, m As Byte, x As Single
m = InputBox("Введите количество элементов: ")
ReDim a (1 To m), bol (1 To m), men (1 To m)
MsgBox(“Вводите элементы массива”)
For i = 1 To m
a(i) = InputBox("a(" & i & "): ")
Next i
x = InputBox("Введите число x: ")
For i = 1 To m
If a(i) > x Then
j = j+1 : bol(j) = a(i)
Else
k = k+1 : men(k) = a(i)
End If
Next i
MsgBox(“Элементы больше ” & x)
For i = 1 To j
MsgBox(bol(i))
Next i
MsgBox(“Элементы меньше ” & x)
For i = 1 To k
MsgBox(men(i))
Next i
End Sub
Здесь каждый элемент массива a сравнивается с переменной x. Если выполняется условие a(i) > x, то элемент a(i) включается в массив bol. Для этого увеличивается на единицу переменная j – номер очередного элемента массива bol. Затем создается новый (j-й) элемент массива bol: bol(j) = a(i). Если же условие a(i) > x не выполняется, то элемент a(i) включается в массив men. Для определения номера очередного элемента массива men используется переменная k.
Пример 4.10 – В программе вводится двумерный массив (имя массива – a). Для этого запрашивается сначала количество строк и столбцов (переменные m и n), затем – сами элементы массива. Вычисляются суммы столбцов массива. Из них составляется новый массив – одномерный массив asum.
Sub primer4_10a()
Dim a(1 To 5, 1 To 10) As Single, asum(1 To 10) As Single
m = InputBox("Введите количество строк: ")
n = InputBox("Введите количество столбцов: ")
For i = 1 To m
For j = 1 To n
a(i, j) = InputBox("a(" & i & "," & j & "): ")
Next j
Next i
For j = 1 To n
For i = 1 To m
asum(j) = asum(j) + a(i, j)
Next i
Next j
For j = 1 To n
MsgBox ("Сумма " & j & "-го столбца = " & asum(j))
Next j
End Sub
Здесь оператор Dim – объявление переменных (в данном случае – массивов). Объявление Dim a(1 To 5, 1 To 10) As Single означает, что переменная a – двумерный массив, который может содержать не более пяти строк и не более десяти столбцов. Элементы массива – числа, которые могут быть как целыми, так и дробными (тип Single).
Для ввода массива a и для суммирования его столбцов используются вложенные циклы. Рассмотрим, например, вложенные циклы для суммирования столбцов массива:
For j = 1 To n
For i = 1 To m
asum(j) = asum(j) + a(i, j)
Next i
Next j
Здесь переменная j (номер столбца) принимает сначала значение 1. При j=1 выполняется вложенный цикл:
For i = 1 To m
asum(j) = asum(j) + a(i, j)
Next i
т.е. переменная i (номер строки) принимает значения от 1 до m, и выполняется суммирование элементов a(1,1), a(2,1),…,a(m,1). В результате вычисляется величина asum(1) – первый элемент нового массива asum, сумма элементов первого столбца массива a.
Затем переменная j (номер столбца) принимает значение 2. Снова выполняется вложенный цикл, т.е. переменная i (номер строки) принимает значения от 1 до m, и выполняется суммирование элементов a(1,2), a(2,2),…,a(m,2). В результате вычисляется величина asum(2). Аналогичные действия выполняются для значений j=3,…,n, т.е. для каждого столбца массива a.
Для вывода элементов массива asum на экран используется следующий цикл:
For j = 1 To n
MsgBox ("Сумма" & j & "-го столбца = " & asum(j))
Next j
Здесь переменная j изменяется от 1 до n с шагом 1, т.е. принимает значения 1, 2, 3, …, n. В каждом цикле (т.е. n раз) выполняется оператор MsgBox ("Сумма" & j & "-го столбца = " & asum(j)), т.е. на экран выводится j-й элемент массива asum.
Примечание – Чтобы массивы a и asum могли иметь любые размеры в соответствии с введенными значениями переменных m и n, следует объявить их как динамические массивы. В этом случае начало программы будет иметь следующий вид:
Sub primer4_10b()
Dim a() As Single, asum() As Single, m As Byte, n As Byte
m = InputBox("Введите количество строк")
n = InputBox("Введите количество столбцов")
ReDim a (1 To m, 1 To n), asum(1 To n)
Пример 4.11 – Программа запрашивает элементы массива из пяти строк и трех столбцов (массив a), а также некоторое число (переменная x). Затем программа подсчитывает в каждой строке массива a количество элементов, равных переменной x. Если строка полностью состоит из чисел x, то номер строки выводится на экран.
Sub primer4_11a()
Dim a(1 To 5, 1 To 3) As Single, x As Single
m = 5 : n = 3
MsgBox(“Вводите массив”)
For i = 1 To m
For j = 1 To n
a(i, j) = InputBox("a(" & i & "," & j & "): ")
Next j
Next i
x = InputBox("Введите число x: ")
For i = 1 To m
kol = 0
For j = 1 To n
If a(i,j) = x Then kol = kol + 1
Next j
If kol = n Then MsgBox (i & "-я строка состоит из чисел " & x)
Next i
End Sub
Здесь для подсчета количества элементов строки, равных числу x, используется переменная kol. Цикл For i = 1 To m используется для перебора строк, цикл For j = 1 To n – для перебора элементов строки. В начале перебора очередной (i-й) строки выполняется оператор kol=0, т.е. переменная kol обнуляется. Затем каждый элемент i-й строки проверяется на равенство переменной x, и если равенство выполняется, то переменная kol увеличивается на единицу (If a(i,j) = x Then kol = kol + 1). Таким образом, после завершения цикла For j = 1 To n (т.е. по окончании перебора элементов i-й строки) переменная kol оказывается равной количеству элементов строки, значение которых совпало с переменной x. В операторе If kol = n Then MsgBox (i & "-я строка состоит из чисел " & x) проверяется значение переменной kol. Если оно равно количеству столбцов массива (т.е. количеству элементов в строке), значит, вся строка состояла из переменных, равных числу x. В этом случае номер строки выводится на экран. Затем выполняется возврат к началу цикла For i = 1 To m, т.е. переменная i увеличивается на единицу, и проверяется очередная строка.
Следует обратить внимание, что переменная x, вводимая с клавиатуры, объявлена в операторе Dim с типом Single, т.е. с тем же типом, что и элементы массива. В данном случае такое объявление обязательно. Если не объявить переменную x, то при ее сравнении с элементом массива a(i,j)(в операторе If a(i,j) = x Then …) эти величины всегда будут распознаваться как разные, так как элементы массива имеют тип Single (т.е. представляют собой десятичные числа), а переменная x будет рассматриваться как строка символов, а не как число (например, значение 7 будет распознано как строка “7”).
Рассмотрим еще один способ решения данной задачи. Чтобы определить, состоит ли вся строка массива из чисел x, воспользуемся логической переменной vse.
Sub primer4_11b()
... См. программу primer4_11a …
For i = 1 To m
vse = True
For j = 1 To n
If a(i,j) <> x Then vse = False
Next j
If vse = True Then MsgBox (i & "-я строка состоит из чисел " & x)
Next i
End Sub
Здесь в начале перебора каждой строки переменной vse присваивается значение True. Затем каждый элемент строки проверяется на равенство переменной x, и если равенство не выполняется, то переменная vse получает значение False. Таким образом, по окончании перебора элементов строки переменная vse будет иметь значение False, если хотя бы один элемент строки будет иметь значение, отличное от x (и останется равной True, если все элементы строки будут равны переменной x). В операторе If vse = True Then …проверяется значение переменной vse. Если эта переменная равна True, значит, вся строка состояла из переменных, равных числу x. В этом случае номер строки выводится на экран.
Пример 4.12 – В программу вводится двумерный массив. Программа определяет в каждом столбце массива максимальное число и выводит его на экран.
Sub primer4_12()
Dim a(1 To 3, 1 To 5) As Single
m = 3 : n = 5
MsgBox(“Вводите массив”)
For i = 1 To m
For j = 1 To n
a(i, j) = InputBox("a(" & i & "," & j & ")")
Next j
Next i
For j = 1 To n
maximum = a(1,j)
For i = 1 To m
If a(i,j) > maximum Then maximum = a(i,j)
Next i
MsgBox ("В " & j & "-м столбце максимальный элемент равен " & maximum)
Next j
End Sub
Здесь цикл For j = 1 To n используется для перебора столбцов, цикл
For i = 1 To m – для перебора элементов столбца. Переменная maximum используется для запоминания максимального элемента столбца. Сначала она принимается равной первому элементу столбца: maximum = a(1,j). Если в ходе перебора столбца обнаруживается элемент, превышающий текущее значение переменной maximum, то он присваивается этой переменной. В результате по окончании перебора столбца переменная maximum будет равна его максимальному элементу.
Пример 4.13 – В программу вводится двумерный массив. Программа определяет в каждом столбце массива максимальное число и меняет его местами с первым элементом данного столбца. Измененный массив выводится на экран.
Sub primer4_13()
Dim a(1 To 3, 1 To 5) As Single
m = 3 : n = 5
MsgBox(“Вводите массив”)
For i = 1 To m
For j = 1 To n
a(i, j) = InputBox("a(" & i & "," & j & ")")
Next j
Next i
For j = 1 To n
maximum = a(1,j)
nomer = 1
For i = 1 To m
If a(i,j) > maximum Then
maximum = a(i,j)
nomer = i
End If
Next i
x = a(1,j)
a(1,j) = a(nomer,j)
a(nomer,j) = x
Next j
For i = 1 To m
For j = 1 To n
MsgBox("a(" & i & "," & j & ") = " & a(i,j))
Next j
Next i
End Sub
Поиск максимального элемента столбца выполняется аналогично предыдущему примеру. В переменной maximum запоминается максимальный элемент столбца, а в переменной nomer – номер этого элемента (или, другими словами, номер строки, в которой находится максимальный элемент данного столбца). В следующей группе операторов первый и максимальный элемент j-го столбца меняются местами:
x = a(1,j)
a(1,j) = a(nomer,j)
a(nomer,j) = x
Здесь x – вспомогательная переменная, используемая для промежуточного хранения первого элемента столбца.
Пример 4.14 –В программу вводится двумерный массив. По каждой строке вычисляется среднее значение. Составляется массив из средних значений, превышающих некоторую заданную величину (эта величина вводится с клавиатуры и обозначается как переменная predel). Этот массив выводится на экран.
Sub primer4_14()
Dim a() As Single, sred() As Single, predel As Single, m As Byte, n As Byte
m = InputBox("Введите количество строк ")
n = InputBox("Введите количество столбцов ")
ReDim a(1 To m, 1 To n), sred (1 To m)
For i = 1 To m
For j = 1 To n
a(i, j) = InputBox("a(" & i & "," & j & ")")
Next j
Next i
predel = InputBox(“Введите минимально допустимое среднее”)
k = 0
For i = 1 To m
sum = 0
For j = 1 To n
sum = sum + a(i,j)
Next j
sred_stroki = sum/n
If sred_stroki > predel Then
k=k+1 ‘Вычисляется номер нового элемента массива sred
sred(k) = sred_stroki
End If
Next i
For i = 1 To k
MsgBox (sred(i))
Next i
End Sub
Здесь sred – массив из средних значений, превышающих заданную величину predel. Каждый раз, когда среднее значение строки превышает переменную predel (т.е. выполняется условие sred_stroki > predel), вычисляется новое значение переменной k - номер очередного элемента массива sred. Для этого переменная k увеличивается на единицу (k=k+1). Затем создается новый (k-й) элемент массива sred: sred(k) = sred_stroki.
Примечание – Здесь для переменной k обнуление необязательно, так как все переменные по умолчанию сначала равны нулю. Оператор k=0 приведен в программе только для наглядности. Для переменной sum обнуление обязательно, так как она вычисляется для каждой строки заново.
Пример 4.15 –В программу вводится двумерный массив, и по каждой его строке вычисляется среднее значение. Составляется новый двумерный массив (обозначенный в программе как nov): в него включаются строки исходного массива, для которых среднее значение превышает некоторую заданную величину (переменная predel).
Sub primer4_15()
Dim a() As Single, nov() As Single, predel As Single, m As Byte, n As Byte
m = InputBox("Введите количество строк ")
n = InputBox("Введите количество столбцов ")
ReDim a(1 To m, 1 To n), nov(1 To m, 1 To n)
… ‘Ввод исходного массива (имя массива – a), как в примере 4.14
predel = InputBox(“Введите минимально допустимое среднее”)
k = 0
For i = 1 To m
sum = 0
For j = 1 To n
sum = sum + a(i,j)
Next j
sred_stroki = sum/n
If sred_stroki > predel Then
k=k+1 ‘Вычисляется номер новой строки массива nov
For j = 1 To n
nov(k,j) = a(i,j) ‘i-я строка исходного массива, в которой среднее превышает
Next j ‘предел, копируется в очередную (k-ю) строку нового массива
End If
Next i
MsgBox("Составлен новый массив”)
For i = 1 To k
For j = 1 To n
MsgBox("nov(" & i & "," & j & ") = " & nov(i,j))
Next j
Next i
End Sub