VBA в MS Office 2007

Массивы, циклы, принятие решений

Показывать лекцию целиком

7.1. Массивы

Решим простую задачу: ввести в ответ на вопросы программы фамилии сотрудников. Если фамилий немного - 5 или 10 - использование переменных, с которыми вы уже знакомы, вполне оправдано. Программа будет состоять из нескольких строк такого вида:

a = InputBox("Введите фамилию сотрудника").

Как быть, если нужно работать со списком из 20 фамилий? А если их будет 50, 1000 или их количество должно быть определено в ходе выполнения программы?

Для обработки больших объемов информации использовать переменные неудобно. Что же делать? Ответ прост: использовать массивы.

Массив - это именованный набор индексированных ячеек. Ячейки так же называют элементами или индексированными переменными.

У каждого массива 5 основных характеристик: имя, размерность, число элементов, номер первого элемента и тип элементов.

  • Имя - правила именования массивов аналогичны правилам именования переменных.

  • Размерность - одномерные массивы напоминают одну строку таблицы, каждая ячейка которой содержит какие-то данные. Многомерные массивы имеют больше измерений. Их можно сравнивать с таблицами, имеющими множество строк и столбцов и с наборами таблиц.

  • Нумерация элементов подчиняется следующим правилам:

  • По умолчанию нумерация элементов массива начинается с 0. Первый по счету элемент получит индекс 0, второй - 1 и т.д.
  • В объявлении отдельного массива можно явно указать индекс его первого и последнего элемента, разделив их ключевым словом To.
  • Если вы хотите, чтобы индексы всех массивов начинались с 1, добавьте в раздел объявлений модуля (вне процедур, функций и обработчиков событий) команду Option Base 1.
  • Тип - подчиняется тем же правилам, которые мы ранее рассмотрели для переменных. Если пользователь не указал его явно, массив получит тип по умолчанию - Variant. Это требует больше системных ресурсов, но позволяет обрабатывать значения различных типов.

  • Не всегда количество элементов и размерность массива известны до начала работы программы. VBA умеет работать с динамическими массивами, параметры которых можно менять в ходе выполнения программы. О них мы поговорим ниже.

    7.2. Одномерные массивы

    07-01-Одномерный массив.docm- пример к п. 7.2.

    Для объявления массивов используют оператор Dim. Объявить массив можно двумя способами. Первый заключается в указании общего количества элементов. Например, так:

    Dim MyArrayA(30) As Single

    Объявленный массив MyArrayА содержит 31 элемент (с индексами от 0 до 30) типа Single. Поскольку нумерация явно не задана, элементы получат индексы по обычным правилам.

    Можно объявить массив и другим способом:

    Dim MyArrayB(1 To 25)

    Массив MyArrayB содержит 25 элементов. Границы нумерации заданы явно - первый элемент получит индекс 1, второй - 2 и т.д. Тип не указан - в массиве можно хранить любые данные.

    Работа с элементами массива ничем не отличается от работы с переменными. Давайте решим следующую задачу:

  • Объявить одномерный массив на 3 элемента
  • Внести в первый элемент число 5 в программе, во второй - запросив значение с помощью окна ввода
  • Вычислить в третьем элементе массива произведение значений, хранящихся в первом и втором элементах.
  • Вывести полученное значение в окне сообщения.
  • Решение задачи приведено в листинге 7.1.

    Dim A(2)
    A(0) = 5
    A(1) = InputBox("Введите значение второго элемента")
    A(2) = A(0) * A(1)
    MsgBox A(2)

    В конце работы программы, если на вопрос о вводе числа мы введем число 2, массив A будет иметь такой вид - табл. 7.1.

    Массив А после работы программы
    Индекс 0 1 2
    Значение 5 2 10

    Как видите, серьезное отличие массивов от переменных - использование индексов для работы с различными элементами массива. Однако, можно заметить, что эта задача легко решается с использованием переменных, без массивов.

    Возможно, сейчас вы еще не вполне осознаете полезность массивов. Если сейчас вы напишите программу для ручного ввода данных в несколько элементов массива, она получится такой же громоздкой, как раньше. Так чем же массивы лучше? Ответ на этот вопрос кроется в использовании циклов.

    7.3. Циклы

    Циклы позволяют выполнять одни и те же команды много раз. В табл. 7.2. собрана информация об основных видах циклов.

    Виды циклов
    Название цикла Вид
    For - Next С фиксированным количеством повторов. Выполняется заданное количество раз
    While - Wend С предусловием. Если не верно условие, заданное на входе в цикл, может не выполниться ни разу
    Do - Loop С постусловием. Выполняется по меньшей мере один раз.

    7.4. Цикл For - Next

    07-02-Цикл For-Next.docm - пример к п. 7.4.

    Решим задачу: вывести цифры от 1 до 10 в окнах сообщений. Ее можно решить и без использования циклов, написав 10 строк такого вида: MsgBox ("1"). А вот конструкция For - Next позволяет делать то же самое гораздо изящнее. В листинге 7.2. вы можете найти решение задачи.

    For i = 1 To 10
            MsgBox (i)
        Next i

    Ключевое слово For задает начало цикла. После него следует переменная i, которая увеличивается при каждом проходе цикла. В ходе работы конструкции For - Next значение i изменяется от 1 до 10.

    Начальное значение счетчика устанавливается при входе в цикл. Мы просто приравниваем i какому-либо числу. Конечное значение переменной задается после ключевого слова To. Переменная i доступна внутри цикла - ведь именно ее мы выводим в окне сообщения.

    Ключевое слово Next с указанием переменной, к которой оно относится, закрывает цикл.

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

    Вы могли заметить, что переменная цикла меняется с приращением 1. Это приращение можно задать в явном виде с помощью ключевого слова Step. В листинге 7.3. вы можете видеть пример оператора For - Next, выводящего нечетные числа в диапазоне от 1 до 10.

    For i = 1 To 10 Step 2
            MsgBox (i)
        Next i

    С помощью ключевого слова Step можно создать не только возрастающий, но и убывающий счетчик. Для этого в Step надо указать отрицательное число и проследить за тем, чтобы первое значение переменной цикла было больше последнего. Например, так: For i=10 to 1 Step -1. Первое значение переменной в таком цикле будет равняться 10, второе - 9 и т.д. - до 1.

    Теперь перейдем к совместному использованию циклов и массивов. Напишем программу, которая предлагает пользователю ввести 10 фамилий, сохраняет их в массиве, а потом выводит в окнах сообщений.

    Готовая программа приведена в листинге 7.4.

    Dim MyArray(9) 
    For i = 0 To 9 
    MyArray(i) = InputBox("Введите фамилию №"  i + 1)
    Next i 
    For i = 0 To 9 'Начало еще одного цикла
    MsgBox ("Фамилия №"  (i + 1)  " "  MyArray(i)) 
    Next i 'Конец цикла

    Обсудив цикл типа For-Next, продолжим разговор о массивах. На очереди - многомерные массивы.

    7.5. Многомерные массивы

    07-03-Многомерные массивы.docm - пример к п. 7.5.

    Многомерные массивы имеют несколько измерений. Чаще всего применяются двумерные массивы (матрицы). Матрицу можно представить в виде обычной таблицы с несколькими строками и столбцами.

    Для того чтобы объявить двумерный массив, нужно воспользоваться командой Dim с указанием размерности каждого из измерений. Остальные правила объявления таких массивов и работы с ними аналогичны таковым для одномерных массивов. Например, мы можем указать лишь размеры измерения массива:

    Dim MyArrayA(10, 1) As Single

    Массив MyArrayА содержит 11 строк и 2 столбца типа Single.

    Можно в явном виде задать границы размерностей:

    Dim MyArrayB(1 To 25, 1 To 5)

    Массив MyArrayB содержит 25 строк и 5 столбцов. Границы нумерации заданы явно. Тип не указан - в массиве можно хранить любые данные.

    В листинге 7.5. приведен пример программы, которая объявляет двумерный массив 5х2 и предлагает ввести в него фамилии и номера телефонов сотрудников.

    Dim MyArray(1 To 5, 1 To 2)
    For i = 1 To 5
        MyArray(i, 1) = InputBox("Введите фамилию №"  i)
        MyArray(i, 2) = InputBox("Введите Телефон №"  i)
    Next i

    В табл. 7.3. вы можете видеть массив MyArray после заполнения его фамилиями и номерами телефонов. В MyArray (1,1) мы внесли фамилию "Иванов", в MyArray (1,2) - телефон Иванова 898989898 и т.д.

    Заполненный массив MyArray
    Индекс 1 2
    1 Иванов 898989898
    2 Петров 343434343
    3 Сидоров 565656565
    4 Александров 121111212
    5 Маринин 545454544

    Эта программа очень похожа на те, которые мы писали для работы с одномерными массивами. В цикле, тело которого повторяется 5 раз, мы поочередно запрашиваем фамилию и номер телефона.

    Один цикл неудобно использовать для работы с массивами больших размерностей. Нетрудно представить себе, какой громоздкой получится решение задачи копирования одной матрицы 100х100 в другую такую же. Кстати, при обработке данных в Microsoft Excel вам постоянно придется обращаться с большими двумерными матрицами. К счастью, существует механизм вложенных циклов, который помогает решать подобные задачи.

    7.6. Вложенные циклы For-Next

    07-04-Вложенные циклы.docm - пример к п. 7.6.

    Принцип работы вложенных циклов кроется в их названии. Все очень просто - один цикл вкладывается в другой. Например, для заполнения массива 10х10 случайными целыми числами от 1 до 10 можно написать такую программу (листинг 7.6.)

    Dim MyArray(1 To 10, 1 To 10)
    For i = 1 To 10
        For j = 1 To 10
            MyArray(i, j) = Int(Rnd(1) * 10)
        Next j
    Next i

    Внешний цикл ( i ) выполняется один раз, после чего внутренний ( j ) - десять раз. За один проход внешнего цикла внутренний выполняет десять - заполняется первая строка массива (с индексами от 1,1 до 1,10) и т.д.

    7.7. Динамические массивы

    07-05-Динамические массивы.docm - пример к п. 7.7.

    Когда вы используете массив, не всегда известно заранее, сколько элементов он будет иметь. В такой ситуации можно объявить массив, который содержит заведомо больше элементов, чем может понадобиться, но это приведет к нерациональному использованию системных ресурсов. Что же делать? Динамические массивы - вот достойный ответ на этот вопрос.

    Решим задачу. Программа просит пользователя ввести количество сотрудников, которое сохраняет в переменной ArraySize, а потом создает массив, одна из размерностей которого равняется ArraySize.

    Чтобы воспользоваться динамическим массивом, сначала нужно объявить пустой массив, например, командой Dim MyArray(), а потом задать размерность массива командой ReDim (листинге 7.7.)

    Dim MyArray()
    	ArraySize = InputBox("Введите количество сотрудников")
    	ReDim MyArray(1 To ArraySize, 1 To 2)

    В итоге, если на вопрос программы о количестве сотрудников мы ввели число 15, будет создан двумерный массив размерностью 15х2.

    Если в программе возникла ситуация, когда последней размерности объявленного и заполненного массива не хватает для хранения данных, вы можете увеличить его командой ReDim с ключевым словом Preserve. Благодаря ему данные, внесенные ранее в массив, будут сохранены. Например, для добавления двух дополнительных столбцов в динамический массив из листинга 7.7. нужно использовать такую команду:

    ReDim Preserve MyArray(1 To ArraySize, 1 To 4)

    7.8. Дополнительные команды работы с массивами

    07-06-Дополнительные команды.docm - пример к п. 7.8.

    Для работы с массивами вы можете использовать еще некоторые команды.

    Array (Список аргументов)- позволяет быстро заполнять массив. Например, в листинге 7.8. массив MyArray заполняется числами 1, 2, 6, 9 и 19, после чего первый элемент массива выводится в окне сообщения.

    Dim MyArray 
    MyArray = Array(1, 2, 6, 9, 19) 
    MsgBox MyArray(0)

    IsArray (Имя переменной) - возвращает True если переменная является массивом. Например, в листинге 7.9. мы объявляем две переменные - одну из них как массив, вторую - как обычную переменную. Далее мы используем оператор IsArray для проверки того, является ли переменная массивом. После чего программа выводит соответствующее сообщение. Здесь мы использовали оператор сравнения If, подробности о котором мы рассмотрим ниже.

    Dim MyArray(10)
    Dim MyArr
    If IsArray(MyArray) Then _
    MsgBox ("Переменная MyArray - массив") _
    Else MsgBox ("Переменная MyArray - не массив")
    If IsArray(MyArr) Then _
    MsgBox ("Переменная MyArr - массив") _
    Else MsgBox ("Переменна MyArr - не массив")

    LBound (Имя Массива, Размерность) - возвращает нижнюю границу для указанной размерности массива.

    UBound (Имя Массива, Размерность) - возвращает верхнюю границу для указанной размерности массива.

    Рассмотрим пример. Создадим динамический двумерный массив, размерности которого заданы с помощью генератора случайных чисел. После этого с помощью операторов LBound и UBound узнаем размерности массива и выведем их в окнах сообщений. Далее - используем двойной цикл для заполнения массива случайными числами (листинг 7.10.)

    Dim MyArray()
        ReDim MyArray(Int(Rnd * 5 + 5), Int(Rnd * 5 + 5))
        MsgBox ("Двумерный массив MyArray:" + Chr(13) + _
        "Первая размерность:" + _
        Str(LBound(MyArray, 1)) + " -" + _
        Str(UBound(MyArray, 1)) + Chr(13) + _
        "Вторая размерность:" + _
        Str(LBound(MyArray, 2)) + " -" + _
        Str(UBound(MyArray, 2)))
        For i = LBound(MyArray, 1) To UBound(MyArray, 1)
            For j = LBound(MyArray, 2) To UBound(MyArray, 2)
                MyArray(i, j) = Int(Rnd * 100)
            Next j
        Next i

    В нашем случае команда LBound для обеих размерностей массива возвращает 0 так как по умолчанию нумерация элементов массива начинается с 0. А вот Ubound возвращает границу каждой из размерностей, которая установлена случайным образом с помощью оператора ReDim. На рис. 7.1. вы можете видеть окно сообщения c информацией о границах массива.

    (рис 7.1) Сообщение о размерностях массива

    Erase Имя_массива - очистить массив. Элементы обычных массивов, содержащих числовые данные, обнуляются. Если мы применим команду Erase к массиву строк - каждый его элемент будет хранить строку нулевой длины (""). Применяя команду Erase к динамическому массиву, мы очищаем память, выделенную этому массиву командой ReDim. Причем, для повторного использования динамического массива, придется снова устанавливать его размерности. Если команда Erase применяется к объектному массиву, в каждый его элемент записывается специальное значение Nothing, которое означает пустую ссылку на объект.

    Теперь, когда мы обсудили циклы For-Next и работу с массивами, поговорим о других типах циклов.

    7.9. Цикл с предусловием

    07-07-Цикл с предусловием.docm - пример к п. 7.9.

    Как вы уже знаете, цикл с предусловием While - Wend выполняется до тех пор, пока условие, указанное на входе, верно.

    В листинге 7.11. представлено решение такой задачи: выводить на экран случайные числа от 0 до 20 до тех пор, пока не будет выведено число больше 10.

    А = 1 
        While А < 10 
            А = Int(Rnd() * 20)
            MsgBox А 
        Wend

    Сначала мы приравниваем переменной А число 1. Проверка при входе в цикл находит, что А меньше 10 и запускает первый проход. Переменной А приравнивается целое случайное число, это число выводится в окне сообщения. Дальше следует новая проверка - если A все еще меньше 10 - все повторяется снова. Если A больше или равно 10 - число не выводится, после чего выполнение цикла прекращается.

    Теперь рассмотрим цикл с постусловием.

    7.10. Цикл с постусловием

    07-08-Цикл с постусловием.docm - пример к п. 7.10.

    Цикл Do-Loop While выполняется до тех пор, пока значение на выходе из цикла не верно. Подобные циклы используют, например, для проверки правильности ввода каких-либо данных пользователем. Если данные введены неверно - цикл выполняется снова.

    Аналогично действует цикл Do-Loop Until - он будет выполняться до тех пор, пока условие цикла неверно (то есть равно False ).

    В листинге 7.12. вы можете найти пример такого цикла. Здесь пользователю предлагается ввести какое-нибудь число. Если введено не число (то есть функция IsNumeric возвратит False ), программа выведет окно ввода снова.

    Dim var_A
        Do
            var_A = InputBox("Введите число")
        Loop Until IsNumeric(var_A)

    7.11. Принятие решений: If-Then-Else

    07-09-If-Then-Else.docm - пример к п. 7.11.

    Программы на VBA умеют принимать решения - для этого существуют операторы условного перехода. Они объединены в конструкцию If - Then - Else.

    В этой конструкции могут быть использованы следующие операторы сравнения (табл. 7.4.)

    Операторы сравнения
    Оператор Описание
    = Равно
    <> Не равно
    > Больше
    < Меньше
    >= Больше или равно
    <= Меньше или равно
    Like Сравнение строки с шаблоном
    Is Сравнение объектов

    Напишем простую программу (листинг 7.13.), которая спрашивает у пользователя его возраст. Если введенный возраст меньше 18 - программа должна вывести надпись "Вам менее 18 лет", если больше или равен 18 - надпись "Вам 18 или больше".

    a = InputBox("Введите ваш возраст")
    If a < 18 Then MsgBox ("Вам меньше 18")
    If a >= 18 Then MsgBox ("Вам 18 или больше")

    Здесь представлен оператор в простейшем виде - проверка условия и выполнение однострочной команды. А что если нужно выполнить не одну команду, а несколько? Для этого служит команда End If (листинг 7.14.)

    a = InputBox("Введите ваш возраст")
    If a < 18 Then
        MsgBox ("Вам меньше 18")
        MsgBox ("Вам не следует смотреть этот фильм")
    End If
    If a >= 18 Then MsgBox ("Добро пожаловать")

    Здесь программа выводит два сообщения, если пользователю меньше 18 лет.

    Оператор может иметь вид If - Then - Else (листинг 7.15). Благодаря ему два оператора If - Then из листинга 7.13. можно объединить в один.

    a = InputBox("Введите ваш возраст")
    If a < 18 Then MsgBox ("Вам меньше 18") _
    Else MsgBox ("Вам больше 18")

    Применение команды Else так же позволяет исполнять многострочные команды. Например, вот так - листинг 7.16.

    a = InputBox("Введите ваш возраст")
    If a < 18 Then
        MsgBox ("Вам меньше 18")
        MsgBox ("Вам не следует смотреть этот фильм")
    Else
        MsgBox ("Вам больше 18")
        MsgBox ("Добро пожаловать")
    End If

    В операторе If возможно использование сложных условий. Например, вы просите пользователя ввести имя и пароль. Если они соответствуют данным, хранящимся в системе, программа выводит приветствие, иначе - сообщает о том, что пользователь ввел неправильные сведения. Очевидно, что нам нужно проверить два условия, причем важно, чтобы и то и другое выполнялось. Для этого можно воспользоваться логическим оператором And, который трактуется как "И". Конструкция с And выглядит так - листинг 7.17.

    UserName = InputBox("Введите имя пользователя")
    UserPass = InputBox("Введите ваш пароль")
    If UserName = "Александр" And UserPass = "12345" Then
        MsgBox ("Добро пожаловать в систему")
    Else
        MsgBox ("Неверное имя пользователя или пароль")
    End If

    Словесно вышеприведенную конструкцию можно описать так: " Если имя равно Александр и пароль равен 12345…".

    Логический оператор Or (переводится как "Или") позволяет принять положительное решение, если выполняется хотя бы одно из условий. Например, нам нужно узнать имя пользователя, и если оно соответствует одному из имен, зарегистрированных в системе, вывести приветствие, иначе - вывести информацию об отсутствии в системе такого пользователя - листинг. 7.18.

    UserName = InputBox("Введите имя пользователя")
    If UserName = "Александр" Or UserName = "Сергей" Or _
    UserName = "Николай" Then
        MsgBox ("Добро пожаловать в систему, "  UserName)
    Else
        MsgBox ("В системе нет такого пользователя!")
    End If
    

    And и Or можно использовать вместе. Оператор Not (Не) позволяет задавать условия с отрицанием. Например, вы можете пропустить в систему всех пользователей кроме пользователя с именем "Владимир".

    Для проверки дополнительных условий можно использовать оператор If - Then - Else.

    Выше, в табл. 7.4., есть пара необычных операторов - Like для сравнения строк с шаблоном, и Is - для сравнения объектных переменных.

    7.12. Сравнение с использованием Like и Is

    07-10-Сравнение строк с шаблонами.docm - пример к п. 7.12.

    Оператор Like используется для сравнения строк с шаблонами. Шаблон - это особым образом записанная последовательность символов. При построении шаблонов используются специальные символы, приведенные в табл. 7.5.

    Символы для построения шаблонов
    Символы Описание
    ? Любой одиночный символ
    * Любое количество любых символов
    # Любая одиночная цифра
    [список символов] Любой одиночный символ, входящий в список символов
    [!список символов] Любой одиночный символ, не входящий в список

    После построения шаблона его заключают в кавычки.

    Давайте рассмотрим пример, реализующий следующие проверки.

  • Узнать, есть ли в строке прописные и заглавные буквы латинского алфавита.
  • Проверить, состоит ли введенное слово из четырех символов (цифр или букв)
  • Проверить, состоит ли введенная последовательность из двух любых символов (цифр или букв) и двух цифр
  • Проверить, нет ли во введенной строке русских букв " а " и " о "
  • Если введенная строка начинается двумя буквами " d " и заканчивается тремя буквами " f ", сообщить об этом
  • В листинге 7.19. вы можете найти решение этой задачи

    Dim str_Inp As String
        str_Inp = InputBox("Введите строку")
        'Есть ли латинские буквы в строке
        If str_Inp Like "*[a-z]*" Or _
        str_Inp Like "*[A-Z]*" _
        Then MsgBox ("В строке есть латинские буквы")
        'Состоит ли введенное слово из 4-х символов
        If str_Inp Like "????" Then _
        MsgBox ("Введенное слово состоит из 4-х символов")
        'Состоит ли введенная последовательность
        'из 2-х любых символов и 2-х цифр
        If str_Inp Like "??##" Then _
        MsgBox ("Введены два любых символа и две цифры")
        'Проверка на отсутствие букв
        '"а", "о"
        If str_Inp Like "[!а]" And _
        str_Inp Like "[!о]" Then
        MsgBox ("В строке нет букв " + Chr(34) + _
        "а" + Chr(34) + " и " + Chr(34) + "о" + Chr(34))
        End If
        'Проверка на наличие в начале
        'введенной строки двух букв "d", а в конце
        'трех "f"
        If str_Inp Like "dd*fff" _
        Then MsgBox ("Строка имеет вид: dd*fff")

    Как вы можете видеть, шаблон для сравнения с текстом всегда заключается в двойные кавычки. На основе информации об использовании шаблонных символов вы можете самостоятельно построить выражения для проверки различных последовательностей.

    Оператор Is используется для работы с объектными переменными. Мы будем подробно рассматривать их в начале следующей главы. Оператор Is проверяет, ссылаются ли две объектные переменные на один и тот же объект. Если это так - он возвращает True, если нет - то False.

    7.13. Принятие решений: Select Case

    07-11-Select Case.docm - пример к п. 7.13.

    Если вам предстоит проверить данные на множество значений, для каждого из которых надо выполнить какое-то особое действие, можно использовать множество операторов If или один Select Case.

    В листинге 7.20. приведен пример использования Select Case - в зависимости от введенного имени программа здоровается с пользователями по-разному.

    Dim str_UserName As String
    str_UserName = InputBox("Введите имя пользователя")
    Select Case str_UserName
        Case "Александр"
            MsgBox ("Привет")
        Case "Сергей"
            MsgBox ("Здравствуй")
        Case "Николай"
            MsgBox ("Добро пожаловать")
        Case Else
            MsgBox ("Не существует такого пользователя")
    End Select

    После Select Case указано имя переменной, анализ которой осуществляется. Дальше расположено произвольное количество вариантов - каждый вариант после ключевого слова Case. Если не выполнен ни один из Case - выполняется Case Else. В конце этой конструкции находится оператор End Select.

    7.14. Оператор безусловного перехода

    07-12-GoTo.docm - пример к п. 7.14.

    В VBA есть один оператор, которым не рекомендуется пользоваться при написании программ. Это оператор безусловного перехода GoTo. Он позволяет передать управление в определенное место программы, заданное номером строки или меткой. Меткой строки может быть любое слово (подчиняющееся правилам именования переменных), после которого следует двоеточие.

    Например, цикл с постусловием можно создать таким способом (листинг 7.21.):

    Dim num_Cycle
        num_Cycle = 0
    Cycle_Start:
        num_Cycle = num_Cycle + 1
        MsgBox ("Проход цикла номер: " + Str(num_Cycle))
        If num_Cycle < 5 Then GoTo Cycle_Start

    Здесь мы создаем метку Cycle_Start, которая означает начало цикла. После этого увеличиваем на единицу переменную, которая является счетчиком цикла, выводим ее в окне сообщения. В последней строке мы проверяем переменную. Если она меньше 5 - команда GoTo Cycle_Start передает управление на соответствующую метку. В такой простой конструкции, как наша, особенных сложностей в чтении кода не видно. Но стоит программе хотя бы немного увеличиться, несколько подобных циклов (особенно - вложенных, а еще хуже - использующих номер строки для перехода) превратят ее в сложный для чтения и правки текст.

    GoTo делает программы трудночитаемыми, его практически всегда можно заменить, используя другие программные конструкции. Единственное место, где GoTo пока незаменим - это использование его при написании обработчиков ошибок времени выполнения. В следующей лекции мы поговорим о таких ошибках и об использовании GoTo для организации подпроцедур в исполняемой процедуре.

    7.15. Работа с файлами

    07-13-Работа с файлами.docm - пример к п. 7.15.

    Программы, написанные на VBA, умеют работать с внешними файлами. В частности, на практике могут возникнуть задачи по поиску файлов в директориях, по открытию, обработке, сохранению файлов. Открытие, обработка, сохранение - дело отдельных приложений (например, MS Word, MS Excel) - то есть эти задачи решаются с помощью объектных моделей этих приложений. А вот поиск файлов осуществляется общими для всех методами VBA.

    Как правило, чтобы открыть файл, нужно знать его имя. Иными словами, поиск файлов заключается в получении имен файлов, находящихся в определенной директории. Для этого можно использовать команду Dir. Она возвращает строку, содержащую имя файла, используя путь, заданный при вызове. Давайте рассмотрим конструкцию (листинг 7.23.), которая позволяет найти все файлы, находящиеся в корневой директории диска C.

    var_Doc = Dir("C:\*.*")
        Do While var_Doc <> ""
            MsgBox var_Doc
            var_Doc = Dir()
        Loop

    Сначала мы присваиваем переменной ? - он символизирует один любой символ. Если не указать путь к файлам, а лишь маску - Dir будет искать их в текущей директории. Например, для Microsoft Word по умолчанию это папка Мои документы.

    Помимо пути и маски при поиске файлов можно указать некоторые дополнительные параметры. Так, по умолчанию функция ищет лишь обычные файлы, не обращая внимания на папки, скрытые и системные файлы. Чтобы функция нашла по заданному пути не только файлы, но и папки, ее нужно вызвать так:

    var_Doc = Dir("C:\*.*", vbDirectory)

    Обратите внимание на то, что после пути и маски указан параметр vbDirectory - он указывает функции, что она должна включить в поиск и директории.

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

    В цикле есть две строки. Первая выводит найденное имя на экран, а вторая - вызывает функцию Dir еще раз - без параметров. Такой вызов возвращает следующее имя файла, подходящее под заданный при первом вызове Dir шаблон. После этого все повторяется. В реальной программе в такой цикл можно вставить команды для работы с найденными файлами.

    Помимо Dir полезной может оказаться команда ChDir. Она позволяет перейти в указанную при ее вызове директорию, которая будет использоваться в качестве директории по умолчанию. Такая конструкция, предшествующая циклу из предыдущего примера позволит найти все файлы в папке "Документы", которая расположена по пути " C:\Документы ":

    ChDir ("C:\Документы")
    var_doc = Dir("*.*")

    Существует множество других функций работы с файлами, вы можете найти информацию о них в справочной системе VBA.

    7.16. Выводы

    В этой лекции мы познакомились с массивами, циклами, операторами принятия решений, обсудили основные положения, касающиеся работы с файлами. Следующая лекция посвящена отладке программ и обработке ошибок.

    Вернуться к учебному плану