
- •1.Программирование в vba. Объекты Application, Workbook, Worksheet и Range
- •2.Редактор Visual Basic
- •2.1.Запуск программы
- •2.1.1.Панель инструментов Стандарт
- •2.2.Отладка программ
- •2.2.1.Ошибки при написании программ
- •2.2.1.1.Ошибки компиляции
- •2.2.1.2.Ошибки выполнения
- •2.2.2.Инструкция Option Explicit
- •2.2.3.Пошаговое выполнение программ
- •2.2.4.Точка останова (Toggle Breakpoint)
- •2.2.5.Отслеживание значений свойств и переменных
- •3.Объекты Application, Workbook, Worksheet и Range. Встроенные функции Dir, MkDir, MsgBox, InputBox
- •3.1.Программа СлучайныеЧисла
- •3.2.Программа УдалениеКниги
- •3.3.Программа СлучайныеЧислаОформление
- •4.Переменные
- •4.1.Объектные переменные
- •4.2.Пользовательский тип данных
- •5.Массивы
- •5.1.1.Функция Erase
- •5.1.2.Функции lBound и uBound
- •6.Подпрограммы. Функции. Область видимости переменных, подпрограмм и функций.
- •6.1.Вызов подпрограммы
- •6.2.Передача данных при вызове программы
- •6.2.1.Передача по ссылке и по значению
- •6.3.Функции
- •6.4.Область видимости переменных
- •6.4.1.Переменные уровня процедуры
- •6.4.2.Переменные уровня модуля
- •6.4.3.Переменные уровня проекта
- •6.4.4.Сохраняемые переменные
- •6.4.5.Область видимости подпрограмм и функций
- •6.4.6.Сохраняемые подпрограммы и функции
- •7.Управляющие структуры: If-Then-Else, Select Case, For-Next, While-Wend, Do-Loop, For-Each-Next
- •8.Инструкция With
- •9.Встроенные функции vba
- •9.1.Математические функции
- •9.2.Функции проверки типов
- •9.3.Функции преобразования форматов
- •9.4.Функции обработки строк
- •9.5.Функции времени и даты
- •10.Обработка ошибок: инструкция On Error
- •11.Пользовательский интерфейс
- •11.1.Создание формы (UserForm) и добавление кнопок (СоmmandButton)
- •11.2.Вывод формы на экран (запуск формы)
- •11.3.Поле (TextBox) и надпись (Label).
- •11.4.Список (ListBox) и поле со списком (ComboBox)
- •11.4.1.Список (ListBox)
- •11.4.2.Определение выбранных элементов списка
- •11.4.3.Поле со списком (ComboBox)
- •11.4.4.Определение выбранного элемента
- •11.4.5.Создание взаимосвязанных элементов управления
- •11.5.Флажок (CheckBox)
- •11.6.Выключатель (ToggleButton)
- •11.7.Переключатель (OptionButton)
- •11.8.Счетчик (SpinButton)
- •11.9.Создание нестандартных меню и панелей инструментов.
- •11.9.1.Пример создания/удаления панели инструментов
- •11.9.2.Пример создания/удаления меню
- •12.События объектов Workbook и Worksheet
- •12.1.События объекта Workbook
- •12.2.События объекта Worksheet
- •Домашнее задание №1
- •Домашнее задание №2 и №3. Типовые варианты.
- •Вариант 1. Домашнее задание №2
- •Списочный состав института
- •Домашнее задание №3
- •Вариант 2. Домашнее задание №2
- •Списочный состав института
- •Домашнее задание №3
- •Вариант 3. Домашнее задание №2
- •Домашнее задание №3
- •Вариант 4. Домашнее задание №2
- •Домашнее задание №3
- •Вариант 5. Домашнее задание №2
- •Домашнее задание №3
5.Массивы
Массивы VBA и других языков программирования весьма схожи; они незаменимы работе с большими объемами данных. Попросту говоря, массив — это переменная, содержащая несколько значений, или еще проще — пронумерованная группа значений одного и того же типа. Если обычные переменные полезны при работе с одиночными значениями определенного типа, массив пригодится при действиях с набором значений того же типа.
Действия с массивами очень похожи на действия с переменными. Прежде чем использовать массив, вы должны его описать и указать тип данных. В массивах используются те же типы данных, что и в одиночных переменных, причем массив может содержать только однотипные значения. Обойти это ограничение легко - создайте массив типа Variant, в котором можно хранить данные любого типа.
Нумерация массивов VBA может начинаться с 0 или 1. Конкретный способ указан в инструкции Option Base в начале модуля. Так, Option Base 0 задает нумерацию всех массивов по умолчанию с 0, a Option Base 1 — с 1. В отсутствие инструкции Option Base нумерация массивов по умолчанию начинается с 0. Но в следующих примерах мы для простоты считаем, что она начинается с 1.
В Модуль4 наберите и протестируйте работу следующих программ:
Пример одномерного трехэлементного целочисленного массива (при отсутствии инструкции Option Base 1 этот массив стал бы четырехэлементным):
Option Base 1
Sub ЦелочисленныйМассив()
Dim Vals(3) As Integer
Vals(1) = Int(100 * Rnd())
Vals(2) = Int(100 * Rnd())
Vals(3) = Int(100 * Rnd())
MsgBox "Выиграли лотерейные номера: " & Vals(1) & ", " & _
Vals(2) & ", " & Vals(3)
End Sub
Пример одномерного, трехэлементного массива Variant, в котором можно хранить «разношерстные» данные:
Sub МассивVariant()
Dim Data(3) As Variant
Data(1) = "Иванов"
Data(2) = #3/21/1947#
Data(3) = Year(Date) - Year(Data(2))
MsgBox Data(1) & " , возраст " & Data(3) & ", родился " _
& Data(2)
End Sub
Пример одномерного двухэлементного массива, в котором определены нижняя и верхняя границы:
Sub НомерПервогоЭлемента()
Dim Data4(4 To 5) As Integer
Data4(4) = lnt(100 * Rnd())
Data4(5) = Int(100 * Rnd())
MsgBox "Выиграли лотерейные номера: " & Data4(4) & ", " _
& Data4(5)
End Sub
Пример динамического массива, который удобен, если вы предполагаете, что в ходе выполнения программы его размер может измениться или заранее неизвестно количество элементов.
Sub ДинамическийМассив()
Dim Data5() As Variant
Dim КолЗаписей As Integer
'Первое объявление массива Data5 как одномерного _
двухэлементного массива:
ReDim Data5(2)
Data5(1) = Int(100 * Rnd())
Data5(2) = Int(100 * Rnd())
MsgBox " Выиграли лотерейные номера: " & Data5(1) & ", " _ & Data5(2)
КолЗаписей = Int(InputBox("Введите количество записей:", _
"Кадры"))
'Второе объявление массива Data5 как двухмерного массива:
ReDim Data5(КолЗаписей,3)
Data5(1,1) = "Иванов"
Data5(1,2) = #3/21/1947#
Data5(1,3) = Year(Date)-Year(Data5(1,2))
MsgBox "Определено " & КолЗаписей & " записей!"
MsgBox "1-я запись: " & Data5(1,1) & ", возраст: " & _
Data5(1,3) & ", родился: " & Data5(1,2)
End Sub
Пример динамического массива с сохранением данных.
Пусть имеется база данных (БД) Excel с полным именем C:\St\Институт.xls, в которой на листе Кадры хранятся сведения о сотрудниках института (Рис. 4 -19). Книга имеет один лист. Количество записей в БД может меняться.
Рис. 4‑19. Фрагмент БД
Требуется: вывести в новую книгу данные о доцентах (Кафедра, Ф.И.О., Разряд), работающих в институте.
|
Sub МассивДоценты_СохранениеДанных() |
|
Dim Сотрудники() As String |
|
Dim КолДоцентов As Integer |
|
Dim НомерСтроки As Integer |
|
КолДоцентов = 0 |
|
НомерСтроки = 3 |
|
' Данные о доцентах считываем в массив: |
|
While Cells(НомерСтроки,2).Value <> "" |
|
If Cells(НомерСтроки,3).Value = "Доцент" Then |
|
КолДоцентов = КолДоцентов + 1 |
|
ReDim Preserve Сотрудники(3,КолДоцентов) |
|
Сотрудники(1,КолДоцентов) = Cells(НомерСтроки,1).Value |
|
Сотрудники(2,КолДоцентов) = Cells(НомерСтроки,2).Value |
|
Сотрудники(3,КолДоцентов) = Cells(НомерСтроки,3).Value |
|
End If |
|
НомерСтроки = НомерСтроки + 1 |
|
Wend |
|
' Добавляем новую книгу и переписываем в неё данные _ из массива: |
|
WorkBooks.Add |
|
For I = 1 To КолДоцентов |
|
Cells(I + 2,1).Value = Сотрудники(1, I) |
|
Cells(I + 2,2).Value = Сотрудники(2, I) |
|
Cells(I + 2,3).Value = Сотрудники(3, I) |
|
Next I |
|
Range("A1").Select |
|
MsgBox "Операция завершена!", vbInformation |
|
End Sub |
В 10-й строке этого кода, при выполнении критерия отбора, счетчик увеличивается на 1 и в оперативной памяти выделяется место для следующей записи (строка 11). При этом предыдущие записи сохраняются. При отсутствии ключевого слова Preserve при повторном определении динамического массива память выделяется заново, при этом все данные уничтожаются.
ОБРАТИТЕ ВНИМАНИЕ: при использовании ключевого слова Preserve, изменяемая размерность должна быть последней. Это значит, что команда:
ReDim Preserve Сотрудники(КолДоцентов, 3)
недопустима!
Замечание: данный код корректен, если находится в книге Институт.xls. Для того чтобы отделить программу от данных, модернизируйте код, как показано ниже, и протестируйте его (код поместите в Модуль4).
|
Sub МассивДоценты_СохранениеДанных_Мод() |
|
Dim Сотрудники() As String |
|
Dim КолДоцентов As Integer |
|
Dim НомерСтроки As Integer |
|
Dim flag As Integer |
|
' Проверяем существование книги C:\St\Институт.xls |
|
If Dir("C:\St\Институт.xls") = "" Then |
|
MsgBox "Файл C:\St\Институт.xls не найден!", _ |
|
vbInformation |
|
Exit Sub |
|
End If |
|
' Проверяем, открыта ли книга Институт.xls: |
|
For I = 1 To Workbooks.Count |
|
If Workbooks(I).Name = "Институт.xls" Then |
|
Workbooks(I).Activate |
|
flag = 1 |
|
Exit For |
|
End If |
|
Next I |
|
If flag = 0 Then Workbooks.Open Filename:= _ |
|
"C:\St\Институт.xls" |
|
' Проверяем, существует ли лист Кадры: |
|
flag = 0 |
|
For I = 1 To Worksheets.Count |
|
If Worksheets(I).Name = "Кадры" Then |
|
flag = 1 |
|
Exit For |
|
End If |
|
Next I |
|
If flag = 1 Then |
|
Sheets("Кадры").Select |
|
Else |
|
MsgBox "Лист Кадры не найден!", vbInformation |
|
Exit Sub |
|
End If |
|
Sheets("Кадры").Select |
|
КолДоцентов = 0 |
|
НомерСтроки = 3 |
|
' Данные о доцентах считываем в массив: |
|
While Cells(НомерСтроки,2).Value <> "" |
|
If Cells(НомерСтроки,3).Value = "Доцент" Then |
|
КолДоцентов = КолДоцентов + 1 |
|
ReDim Preserve Сотрудники(3,КолДоцентов) |
|
Сотрудники(1,КолДоцентов) = _ |
|
Cells(НомерСтроки,1).Value |
|
Сотрудники(2,КолДоцентов) = _ |
|
Cells(НомерСтроки,2).Value |
|
Сотрудники(3,КолДоцентов) = _ |
|
Cells(НомерСтроки,3).Value |
|
End If |
|
НомерСтроки = НомерСтроки + 1 |
|
Wend |
|
' Добавляем новую книгу и переписываем в неё данные _ из массива: |
|
WorkBooks.Add |
|
For I = 1 To КолДоцентов |
|
Cells(I + 2,1).Value = Сотрудники(1, I) |
|
Cells(I + 2,2).Value = Сотрудники(2, I) |
|
Cells(I + 2,3).Value = Сотрудники(3, I) |
|
Next I |
|
' Вызываем программу оформления таблицы, передавая в неё _ |
|
количество форматируемых строк и столбцов: |
|
' Call ОформлениеТаблицы(КолДоцентов, 3) |
|
Range("A1").Select |
|
MsgBox "Операция завершена!",vbInformation |
|
End Sub |
Замечания:
Обратите внимание на строки с 24 по 29 – здесь происходит проверка существования листа Кадры. В строка 30 – 35 происходит обработка событий «лист существует/не существует».
Строка 62 – вызов подпрограммы оформления таблицы – пока занесена в комментарий (см. задание на стр. 49).