- •3 Семестр
- •Оглавление
- •Язык программирования Visual Basic for Application Основные средства и возможности vba Основные элементы vba
- •Основы программирования на vba Типы данных
- •Описание переменных
- •Допустимые имена
- •Инструкция Def Тип
- •Массивы
- •Динамические массивы
- •Функции и процедуры для работы с массивами
- •Константы
- •Тип данных, определенный пользователем
- •Операции vba
- •Приоритеты операций
- •Встроенные функции vba
- •Математические функции
- •Функции проверки типов
- •Функции преобразования форматов
- •Функции обработки строк
- •Функции времени и даты
- •Функции выбора
- •Функции, возвращающие строки
- •Встроенные диалоговые окна
- •Инструкции vba
- •Оператор присвоения
- •Перенос строки
- •Комментарии
- •Расположение нескольких операторов на одной строке
- •Операторы перехода и выбора
- •Операторы повтора
- •Условная компиляция
- •Процедура
- •Переход в подпрограмму и возвращение из подпрограммы
- •Вызов процедуры
- •Рекурсивные процедуры
- •Область определения переменной
- •Время жизни переменной
- •Процедуры обработки ошибок и отладка программ Разработка процедур, предотвращающих появление ошибок
- •Перехват и обработка ошибок
- •Свойства объекта Err
- •Методы объекта Err
- •Отладка программ
- •Ошибки компиляции
- •Ошибки выполнения
- •Логические ошибки
- •Инструкция Option Explicit
- •Пошаговое выполнение программ
- •Точка останова
- •Вывод значений свойств и переменных
- •Работа с файлами Типы файлов в vba
- •Открытие и закрытие файла
- •Ввод данных в файл последовательного доступа
- •Вывод данных из файла последовательного доступа
- •Работа с файлом произвольного доступа
- •Наиболее употребляемые инструкции и функции при работе с файлами
- •Объект FileSearch
- •Элементы управления и пользовательская форма Элементы управления
- •Режим конструктора
- •Установка свойств элемента управления
- •Редактор кода
- •Пользовательская форма UserForm
- •Семейство Controls
- •Создание пользовательской формы
- •Общие свойства элементов управления
- •Соглашения об именах
- •Общие методы и события элементов управления
- •Объект DataObject
- •Надпись
- •Заполнение списка
- •Выбор нескольких элементов из списка
- •Поле со списком
- •Полоса прокрутки и счетчик
- •Переключатель
- •Флажок и выключатель
- •Ссылки на ячейки и диапазоны
- •Набор страниц
- •Набор вкладок
- •Дополнительные элементы управления
- •Последовательность выбора элементов управления
- •Инициализация и отображение диалогового окна
- •Закрытие диалогового окна
- •Отображение встроенных диалоговых окон
- •Открытие документа
- •Объект Application
- •Свойства объекта Application
- •Методы объекта Application
- •События объекта Application
- •Объект Workbook и семейство Workbooks
- •Свойства объекта Workbook и семейства Workbooks
- •Методы объекта Workbook и семейства Workbooks
- •События объекта Workbook и семейства Workbooks
- •Объект Worksheet и семейство Worksheets
- •Свойства объекта Worksheet и семейства Worksheets
- •Методы объекта Worksheet и семейства Worksheet
- •События объекта Worksheet
- •Объекты Range и Selection
- •Адресация ячеек
- •Задание групп строк и столбцов с помощью объекта Range
- •Связь объекта Range и свойства Cells
- •Свойства и методы объекта Range
- •Программирование панели инструментов
- •Объект CommandBar и семейство CommandBars
- •Семейство CommandBarControls и объект CommandBarControl
- •Пример создания панели инструментов пользователя
- •Пример создания строки меню пользователя
- •Создание пользовательской панели инструментов вручную
- •Удаление элемента управления из панели инструментов вручную
- •Удаление пользовательской панели инструментов вручную
- •Назначение вручную макроса кнопке
- •Изменение и создание вручную изображения на кнопке
- •Программирование средств для работы со справочной информацией
- •Структура помощника
- •Типы помощника
- •Свойства объекта Assistant
- •Объект Balloon
Рекурсивные процедуры
В VВА возможно создание рекурсивных процедур, т. е. процедур, вызываюх самих себя. Стандартным примером рекурсивной процедуры является процедура вычисления факториала, т. е. функции, возвращающей результат произведения первых n натуральных чисел, где n — аргумент функции. Для этой функции имеется стандартное обозначение: Fact(n)=n!, где Fact (0) = 1. Ясно, что
Fact (n) = n Fact (n - 1)
Основываясь на данном соотношении, приводимая ниже рекурсивная функция вычисляет значение факториала.
Function Fact(n As Integer) As Integer
If n<l Then
Fact = 1
Else
Fact = Fact (n - 1) n End If End Function
Другим стандартным примером применения рекурсивных функций является нахождение наибольшего общего делителя двух целых чисел по алгоритму Евклида. Наибольший общий делитель (НОД) двух целых чисел — это наибольшее целое, на которое делятся оба числа. Например, НОД (10, 14) = 2 и НОД (15, 31) = 1.
Алгоритм Евклида состоит в следующем:
1. Если а делится на b, то НОД(а, b) = b
2. В противном случае — НОД(а, b) = НОД(b, a Mod b)
Приводимая ниже рекурсивная функция программирует алгоритм Евклида.
Function НОД(Целое1 As Long, Целое2 As Long) As Long
If Целое2 Mod Целое1 = О Then
НОД = Целое1
Else
НОД = НОД(Целое2, Целое! Mod Целое2)
End If
End Function
Несмотря на элегантность рекурсивных процедур, применять их надо с осторожностью,
т. к. неаккуратное использование может привести к проблемам с памятью — многократный вызов такой процедуры быстро исчерпывает стековую память.
Область определения переменной
Область определения переменной задает область, в которой может быть ис пользована переменная. В VBA имеется три соответствующих уровня переменных:
-
Переменные уровня процедуры используются только в процедуре, в которой они описаны при помощи инструкции Dim, размещенной в процедуре.
-
Переменные уровня модуля используются только в модуле, в котором они описаны при помощи инструкции Dim, размещенной в области описания модуля, т. е. перед описанием процедур.
-
Общие переменные, используемые во всех модулях данного проекта. Описываются при помощи инструкции Public, размещенной в области описания модуля.
Время жизни переменной
Личная (Private) переменная сохраняет свое значение только пока выполняется процедура, в которой эта переменная описана. При завершении процедуры значение переменной теряется, и при повторном запуске процедуры его надо заново инициализировать. Переменные, описанные при помощи инструкции Static, сохраняют свое значение по выходу из процедуры, но пока работает программа.
Процедуры обработки ошибок и отладка программ Разработка процедур, предотвращающих появление ошибок
При составлении приложений важно предусмотреть, чтобы программа анализировала возможные ошибки, возникающие при ее выполнении по вине пользователя, и информировала его об этом, подсказывая, что конкретно он сделал неправильно. При этом возможно два подхода:
- Предотвращение ошибок: программно анализировать вводимые или вычисляемые данные и в случае, если они могут приводить к ошибке, обеспечить, чтобы программа информировала пользователя о необходимости корректного задания данных.
- Обработка ошибок: в случае появления ошибки, перехватить ее, обработать и программно откликнуться на возникшую ошибку.
При создании приложений надо сочетать оба подхода, применяя в каждом конкретном случае и для каждой возможной ошибки тот, который кажется разработчику наиболее эффективным.
В данном разделе рассмотрим процесс создания приложения, в котором предотвращается появление ошибок, на простейшем примере:
- В диалоговом окне два поля (Числитель И Знаменатель) предусмотрены для ввода данных. Пользователь вводит в них по числу (рис. 12.1).
- По нажатию кнопки Счет, программа делит число, введенное в поле Числитель, на число, введенное в поле Знаменатель, и выводит полученный результат в поле Ответ.
Следующая программа производит деление числителя на знаменатель по нажатию кнопки Счет без контроля появления возможных ошибок:
Private Sub CommandButton1_Click()
Dim Числитель, Знаменатель, Результат As Double
Числитель = CDbl(TextBox1.Text)
Знаменатель = CDbl(TextBox2.Text)
Результат = Числитель / Делитель
TextBox3.Text = CStr(Результат)
End Sub
Несмотря на то что рассматриваемая ситуация очень простая, она уже таит в себе множество подводных камней. Например, если пользователь по невнимательности забудет ввести в поле Числитель или в поле Знаменатель число, при нажатии кнопки Счет происходит аварийное прерывание выполнения программы с малопонятным сообщением о несоответствии типов, отображаемом в диалоговом окне Microsoft Visual Basic (рис. 12.2).
Рис. 12.1. Диалоговое окно Деление
Рис. 12.2. диалоговое окно Microsoft Visual Basic с сообщением об ошибке
Данное сообщение об ошибке связано с одной из следующих двух инструкций в программе:
Числитель = CDbl(TextBox1.Text)
Знаменатель = CDbl(TextBox2.Text)
где аргументом функции CDbl должна быть строка, преобразуемая в число. Если в какое-то из полей, Числитель ИЛИ Знаменатель, ничего не введено, по умолчанию из этого поля будет считываться пустая строка. Но пустая строка не может быть преобразована в число, и поэтому из-за функции CDbl происходит ошибка. Ошибка о несоответствии типов возникнет также, если в одно из полей пользователь по неосторожности введет число с десятичной занятой, а установками системы предусматривается десятичная точка и наоборот.
Такие ошибки ввода легко избежать, если производить в программе предварительную проверку: преобразуются ли вводимые данные в числа? Эту предварительную проверку можно, например, сделать, как показано в следующей процедуре, в которой предусмотрены:
- Проверка того, будет ли вводимая информация в поля ввода преобразовываться в числа.
Если вводимая информация не преобразуется в числа, то выдается сообщение о поле, в которое некорректно введены данные, и на него перемещается фокус. Например, в ситуации, показанной на рис. 12.3, в поле Знаменатель было введено число с десятичной запятой, в то время как установки системы предусматривают десятичную точку.
Поэтому процедура вызвала отображение диалогового
Рис. 12.3. Пример сообщения о некорректном вводе данных
окна деление с сообщением об ошибке в знаменателе и установила фокус на поле Знаменатель.
Private Sub CommandButton1_Click()
Dim Числитель, Знаменатель, Результат As Single
‘
If IsNumeric(TextBox1.Text) = False Then
MsgBox “Ошибка в числителе”,
vbInformation, “деление”
TextBox1.SetFocus
Exit Sub
End If
‘
If IsNumeric(TextBox2.Text) = False Then
MsgBox “Ошибка в знаменателе”,
vbInformation, “деление”
TextBox2.SetFocus
Exit Sub
End If
‘
Числитель = CDbl(TextBox1.Text)
Знаменатель = CDbl(TextBox2.Text)
Результат = Числитель / Делитель
TextBox3.Text = CStr(Результат)
End Sub
Но это еще не все подводные камни, которые подстерегают неосторожного пользователя при вводе данных даже в этом простом примере. Если пользователь в поле Знаменатель введет 0, то также произойдет аварийная остановка выполнения программы с отображением в диалоговом окне Microsoft Visual Basic сообщения: деление на 0. для избежания подобной ошибки будем проверять не только, являются ли введенные в поле данные числом, но и что это не ноль. Например, добавим перед расчетным блоком в процедуре следующую дополнительную проверку:
If CDbl (TextBox2.Text) = 0 Then
MsgBox “Знаменатель не может быть нулем”,
vbInformation, “деление”
TextBox2.SetFocus
Exit Sub