VBA (Стеценко) / VBA_ЛБ_13v2
.pdfСтеценко А. А. |
31 |
Worksheets("ToDay").Select
Set Rng1 = Range("b2:c4") Set Rng2 = Range("e12:g14") Set Rng3 = Range("b22:c24")
Set bigRng = Union(Rng1, Rng2, Rng3) bigRng.Value = "=pi()"
End Sub
Рабочее задание
Р1. Разработайте программу, в которой:
а) с помощью свойства Cells создаётся объект Range, включающий диапазон С4:С23 на листе "Секрет";
б) во все ячейки созданного записывается формула
"=RANDBETWEEN(0,100)";
Функция RANDBETWEEN (в русифицированных версиях Excel называется СЛУЧМЕЖДУ), которая используется далее в создаваемой программе, встроена в Excel 2007 и более поздних версий. В Excel 2003 и более ранних версиях она находится в надстройке "Пакет анализа", поэтому для выполнения программы в среде Excel 2003 требуется заранее подключить указанную надстройку.
в) в соседний столбец копируются только значения из диапазона С4:С23;
г) с помощью метода AdvancedFilter выполняется копирование оригинальных значений в другой объект Range, сдвинутый относительно исходного на два столбца право;
д) с помощью свойства End определяется границы диапазона оригинальных значений;
е) подсчитывается количество оригинальных значений.
Сравните свою программу с программой CopyUnique (листинг 15)
Листинг 15
Sub CopyUnique()
'30.06.13.
Dim Rng1 As Range, Rng2 As Range
Dim RLast As Long, KolUnique As Long
Set Rng1 = Worksheets("Секрет").Range("d4:d23") Set Rng2 = Worksheets("Секрет").Range("e4") Rng1.AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=Rng2, _ Unique:=True
RLast = Range("e1024").End(xlUp).Row
Set Rng2 = Range(Range("e4"), Cells(RLast, "e")) KolUnique = Rng2.Cells.Count Rng2.Cells(KolUnique + 2, 1) = KolUnique
End Sub
32 |
Программирование в среде электронных таблиц Microsoft Excel |
Р2. Выделите на каком-либо листе произвольный диапазон в одной строке и запишите макрос СеткаДиапазона. Стиль и цвет линий выберите самостоятельно.
Р3. Отредактируйте макрос СеткаДиапазона:
а) в заголовке в скобки поставьте формальный аргумент типа Range,
например, Diap As Range;
б) уберите строки, связанные с выделением диапазона;
в) замените Selection на имя формального аргумента, которое было указано в п. а);
г) удалите строки обрамления диагоналей.
В результате макрос превратился в подпрограмму, которая может обрамлять задаваемый объект Range.
Р4. Разберите программу "Зебра" (листинг 13), выясните, с какой целью в ней используется свойство OffSet. Наберите программу "Зебра" в новом модуле
VBA.
Р5. Скопируйте в свою книгу лист, заданный преподавателем, из книги ФизДанные.xls. Выделите в листе содержательную часть (объект Selection) и запустите программу "Зебра" на выполнение. Рассмотрите и оцените результат выполнения программы.
Р6. Добавьте в программу "Зебра" обращение к подпрограмме, подготовленной в п. Р10, и ещё раз запустите программу "Зебра" на выполнение. Оцените полученный результат, покажите преподавателю.
Р7. Разберите программу tstUnion (листинг 14). Подготовьте и выполните подобную программу, размещая объекты Range на листе "Лист2". Объясните полученный результат.
Покажите результат преподавателю. Сохраните книгу.
Контрольные вопросы к работе VBA5
К1. Объясните синтаксис свойства Cells объекта Range. К2. Объясните синтаксис свойства Cells объекта Worksheet. К3. Сколько ячеек представляет свойство Cells?
К4. Объясните синтаксис свойства OffSet.
К5. Сколько ячеек представляет свойство OffSet? Приведите примеры. К6. Объясните, как организовать просмотр всех ячеек объекта Range.
К7. Объясните метод Union. Какие объекты являются аргументами Union? Могут ли аргументы Union принадлежать разным рабочим листам?
К8. С какой целью в программе "Зебра" (листинг 13) используется свойство
OffSet?
Стеценко А. А. |
33 |
Работа VBA6. Свойство End и метод EdvancedFilter
Цель работы: изучение свойства End и метода EdvancedFilter объекта Range, закрепление навыков работы с объектом Range.
Введение
Свойство End
Свойство End объекта Range представляет ячейку в конце исходного диапазона. Оно является аналогом клавиатурных комбинаций <End>+<>, <End>+<>, <End>+<>, <End>+<>, которые перемещают на рабочем листе курсорную рамку на соответствующую границу диапазона данных. Например, если на листе, часть которого представлена в табл. 2, установить курсорную рамку на ячейку А100, а затем нажать клавиши <End>+<> (нажать и удерживать клавишу End и нажать клавишу со стрелкой вверх), то курсорная рамка станет на ячейку А19. К такому же результату приведёт выполнение инструкции
rEnd = Range("a100").End(xlUp).Row
Переменная rEnd в рассматриваемом примере получит значение 19.
Аргументами свойства End могут быть константы xlUp, xlDown, xlToLeft, xlToRight. Назначение этих констант не нуждается в пояснениях.
Объект Range, представляемый свойством End, доступен только для чте-
ния.
Таблица 2.
Исходный список
|
A |
B |
|
C |
D |
E |
F |
G |
5 |
Curr |
Prev |
|
Name |
DOB |
Nation |
Rank pts |
Tours |
6 |
1 |
1 |
|
Wozniacki, Caroline |
11.07.1990 |
DEN |
7395 |
21 |
|
|
|
|
|
|
|
|
|
7 |
2 |
2 |
|
Sharapova, Maria |
19.04.1987 |
RUS |
6370 |
14 |
8 |
3 |
4 |
|
Kvitova, Petra |
08.03.1990 |
CZE |
5970 |
19 |
|
|
|
|
|
|
|
|
|
9 |
4 |
3 |
|
Azarenka, Victoria |
31.07.1989 |
BLR |
5750 |
20 |
10 |
5 |
7 |
|
Li, Na |
26.02.1982 |
CHN |
5351 |
17 |
|
|
|
|
|
|
|
|
|
11 |
6 |
5 |
|
Zvonareva, Vera |
07.09.1984 |
RUS |
5190 |
21 |
12 |
7 |
6 |
|
Stosur, Samantha |
30.03.1984 |
AUS |
5115 |
20 |
|
|
|
|
|
|
|
|
|
13 |
8 |
8 |
|
Radwanska, Agnieszka |
06.03.1989 |
POL |
4940 |
19 |
14 |
9 |
9 |
|
Bartoli, Marion |
02.10.1984 |
FRA |
4610 |
27 |
|
|
|
|
|
|
|
|
|
15 |
10 |
10 |
|
Petcovic, Andrea |
09.09.1987 |
GER |
4580 |
18 |
16 |
11 |
12 |
|
Schiavone, Francesca |
23.06.1980 |
ITA |
3900 |
22 |
17 |
12 |
14 |
|
Williams, Serena |
26.09.1981 |
USA |
3180 |
13 |
18 |
13 |
11 |
|
Clijsters, Kim |
08.06.1983 |
BEL |
3161 |
14 |
19 |
14 |
13 |
|
Jancovic, Jelena |
28.02.1985 |
SRB |
3115 |
22 |
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Метод AdvancedFilter
Из заданного диапазона данных метод AdvancedFilter отбирает данные по критериям, которые задаются в специальном диапазоне, или, как говорят, выполняет расширенную фильтрацию данных.
Синтаксис:
34 |
Программирование в среде электронных таблиц Microsoft Excel |
expression.AdvancedFilter(Action, CriteriaRange, CopyToRange, Unique)
Все аргументы, указанные в скобках, необязательные.
expression переменная, определяющая объект Range, в котором содержится список.
Action одна из констант типа XlFilterAction:
xlFilterCopy (значение = 2) фильтрованные данные копируются на новое место;
xlFilterInPlace (значение = 1) фильтрованные данные остаются на месте (фильтрация in situ).
CriteriaRange диапазон, в котором находится набор критериев. Если аргумент опущен, то нет критериев.
CopyToRange целевой диапазон для скопированных строк, если аргумент Action равен xlFilterCopy. В другом случае этот аргумент игнорируется.
Unique True, если требуется копировать только уникальные записи. False означает копирование всех записей, удовлетворяющих набору критериев. По умолчанию принимается False.
Для правильной работы метода AdvancedFilter требуется выполнить следующие условия:
а) данные, подлежащие фильтрации, должны иметь заголовок (другими словами, таблица должна иметь "шапку"). Желательно выделить заголовок полужирным шрифтом (см. табл. 2); б) условия фильтрации требуется разместить в диапазоне, в первой строке ко-
торого повторяется "шапка" таблицы; в следующих под заголовком строках записываются условия фильтрации, "привязанные" к столбцам исходной таблицы.
В табл. 3 диапазон фильтрации I1:O4 для наглядности обведен двойной линией. В фильтре указано, что требуется отобрать из исходного списка спортсменок России, Белоруссии и Франции, которые участвовали не менее чем в 20 турнирах.
Не обязательно закрашивать или обрамлять диапазон фильтрации, но необходимо точно указывать его координаты. Если в рассматриваемом примере указать диапазон фильтрации I1:O5, будет зафиксирована ошибка из-за того, что "диапазон фильтрации пустой".
Таблица 3
Диапазон фильтрации
|
I |
|
J |
|
K |
|
L |
|
M |
|
N |
|
O |
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
Curr |
Prev |
Name |
DOB |
Nation |
Rank pts |
Tours |
2 |
|
|
|
|
RUS |
|
>=20 |
|
|
|
|
|
Стеценко А. А. |
|
|
35 |
||
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
|
|
|
|
BLR |
|
>=20 |
|
|
4 |
|
|
|
|
|
FRA |
|
>=20 |
|
|
5 |
|
|
|
|
|
|
|
|
|
Таблица 4
Результат фильтрации
4
|
Curr |
Prev |
Name |
DOB |
Nation |
Rank pts |
Tours |
5 |
|||||||
6 |
4 |
3 |
Azarenka, |
31.07.1989 |
BLR |
5750 |
20 |
7 |
6 |
5 |
Zvonareva, |
07.09.1984 |
RUS |
5190 |
21 |
8 |
9 |
9 |
Bartoli, Ma |
02.10.1984 |
FRA |
4610 |
27 |
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Программа, реализующая расширенный фильтр для данных, представленных в табл. 2 с учетом диапазона фильтрации I1:O4 (табл. 3) и выводящая результат в диапазон, начинающийся в ячейке A5 на листе Target (табл. 4), представлена в листинге 16.
Листинг 16 Реализация расширенного фильтра
Sub РасширенныйФильтр()
'Стеценко А., 12.06.2013
Dim Rng1 As Range, Rng2 As Range, Rngf As Range
Sheets("Tennis").Select |
|
|
|||
Set Rng1 = Range("A5:G19") |
'Исходный |
диапазон |
|||
Set |
Rngf |
= |
Range("I1:O4") |
'Диапазон |
фильтрации |
Set |
Rng2 |
= |
Sheets("Target").Range("a5") 'Начало целевого |
||
|
|
|
|
|
' диапазона |
Rng1.AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=Rngf, _
CopyToRange:=Rng2, _
Unique:=True
End Sub
Слабым местом программы "РасширенныйФильтр" является жёсткая привязанность к диапазону A5:G19, в котором находятся исходные данные. Но исходные данные могут занимать несколько сот или даже тысяч строк, и этот набор может изменяться. Чтобы программа могла работать с любым количеством строк в исходном наборе, в ней нужно предусмотреть определение нижней границы диапазона исходных данных с помощью метода End объекта
Range:
rBeg = 5 Col = 7
rEnd = Range("a65535").End(xlUp).Row
Set Rng1 = Range(Cells(rBeg, 1), Cells(rEnd, Col))
36 |
Программирование в среде электронных таблиц Microsoft Excel |
Рабочее задание
Р1. Активизируйте лист, скопированный согласно п. Р5 работы VBA5, и оцените действие команд, отдаваемых комбинацией клавиши Ctrl и клавиш со стрелками:
а) установите курсорную рамку на любую ячейку в пределах диапазона данных и поочерёдно нажмите комбинации клавиш <Ctrl>+<>, <Ctrl>+<>, <Ctrl>+<>, <Ctrl>+<>; отметьте, куда смещается кур-
сорная рамка;
б) ещё раз установите курсорную рамку на любую ячейку в пределах диапазона данных и дважды нажмите комбинацию клавиш <Ctrl>+<>, каждый раз отмечая положение курсорной рамки (рамка должна установиться на ячейке последней строки);
в) нажмите комбинацию клавиш <Ctrl>+<>, отметьте новое положение курсорной рамки (рамка должна установиться на ячейке последней строки диапазона).
Р2. Подготовьте, наберите и опробуйте в шаговом режиме программу, которая сначала выделяет ячейку в верхней строке диапазона, затем ячейку в последней строке листа и, наконец, ячейку в последней строке диапазона данных. Продемонстрируйте результат преподавателю.
Р3. Подготовьте рабочий лист, скопированный в п. Р1, к обработке расширенным фильтром. Задание на фильтрацию получите у преподавателя.
Р4. Разберите программу "РасширенныйФильтр" (листинг 11) и подготовьте на её основе свою программу, решающую полученное в предыдущем пункте задание с помощью метода AdvancedFilter. Согласуйте программу с преподавателем.
Предположим, что в п. 1 задано скопировать лист "Теплопроводность" из книги "ФизДанные.xls". Задание на фильтрацию может иметь следующий вид:
|
Газ |
|
|
Формула |
|
|
0° С |
|
|
100° С |
|
|
200° С |
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
>200 |
|
>350 |
|
>400 |
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Целевой диапазон может размещаться на этом же листе ниже диапазона фильтрации.
Р5. В среде VBA в отдельном модуле наберите подготовленную программу и выполните её в пошаговом режиме. Покажите результат преподавателю.
Р6. Сохраните и закройте свою книгу, скопируйте файл на личный носитель.
Контрольные вопросы к работе VBA6
К1. Объясните свойство End объекта Range.
К2. Объясните, как программа может определить номер 1-й строки диапазона. К3. Объясните, как программа может определить номер последней строки диа-
пазона.
Стеценко А. А. |
37 |
К4. Объясните, как строится диапазон фильтрации для метода AdvancedFilter. К5. Объясните аргументы свойство End.
К6. Объясните аргументы метода AdvancedFilter.
Работа VBA7. Текстовые функции VBA
Цель работы: укрепление навыков подготовки программ в стандартном модуле, ознакомление с текстовыми функциями VBA и их применением, ознакомление с простейшими приёмами отладки программ с использованием окна Immediate.
Введение
В Visual Basic, в отличие от С/С++, символьные и строковые данные не различаются, это данные типа String. Чаще говорят "символьные" или "текстовые" данные. Символ считается строкой единичной длины. Примеры объявления строковых данных:
Dim s1 As String, s2 As String
Dim sym As String*1
Переменная s1 объявлена строковой, ей можно присвоить любое текстовое значение, например,
s1 = " Белая берёза "
Переменная sym объявлена строковой длиной в один символ. Правила Visual Basic допускают выполнить присваивание
sym = s1
В переменную sym запишется первый символ из s1, для нашего примера это пробел.
Для работы с текстовыми данными в Visual Basic имеется несколько функций. Далее рассматриваются некоторые их них. Более полные сведения можно найти в справочной системе VBA.
Функция Trim(Arg) удаляет из строки ведущие (в начале строки) и концевые пробелы. Пусть, например, имеются следующие инструкции:
Dim d As Integer
s2 = Trim (s1)
Переменная s2 примет значение "Белая берёза", без пробелов в начале и в конце строки. Пробелы внутри строки функция Trim не затрагивает.
Функции LTrim и RTrim представляют частные случаи от функции Trim: LTrim удаляет пробелы в начале строки ("левые"), а RTrim – в конце строки ("правые").
В программе VBA можно использовать функции рабочего листа Excel, для этого перед именем функции Excel нужно записать WorksheetFunction и поставить точку. Среди текстовых функций Ex-
38 |
Программирование в среде электронных таблиц Microsoft Excel |
cel есть функция Trim, имя которой полностью совпадает с именем аналогичной функции VBA, но действие отличается. Функция Trim, входящая в Excel, удаляет из аргумента все пробелы, кроме одиночных пробелов между словами. Если в программе VBA записать ин-
струкцию s2 = WorksheetFunction.Trim (s1), то значени-
ем s2 для приведённого выше значения s1 будет "Белая берёза" с единственным пробелом между словами.
Функция Len(Arg) вычисляет длину строки:
d = Len (s2)
Переменная d для рассматриваемого примера примет значение 14: (5 букв
Белая)+(3 пробела)+(6 букв берёза).
Функция InStr([start,] s1, s2 [, comp]) ищет в строке s1
позицию, с которой начинается строка s2. Необязательный аргумент start задаёт стартовую позицию поиска, по умолчанию start=1. Необязательный аргумент comp определяет тип сравнения строк:
comp = vbBinaryCompare – двоичное сравнение; сравниваются коды символов, так что заглавные и строчные буквы различаются;
comp = vbTextCompare – текстовое сравнение, заглавные и строчные буквы не различаются.
Если аргумент comp опущен, то выполняется двоичное сравнение.
В следующем примере функция InStr возвращает позицию первого пробела в строке s1:
d = InStr (s1, " ")
Функция Left(Arg, Length) возвращает левые Length символов из строки Arg. В следующем примере переменной s1 присваивается значение "Буря" (кавычки ограничивают текстовое значение):
s1 = Left ("Буря мглою небо кроет", 4)
Функция Right(Arg, Length) возвращает правые Length символов из строки Arg. В следующем примере переменной s2 присваивается значение "кроет":
s2 = Right ("Буря мглою небо кроет", 5)
Функция Mid(Arg, start [, Length]) возвращает Length симво-
лов из строки Arg, начиная с позиции start. В следующем примере переменной s3 присваивается значение "мглою":
s3 = Mid ("Буря мглою небо кроет", 6, 5)
Функция Asc(Arg) возвращает десятичное значение кода символа Arg. В программе tstMid (листинг 17) демонстрируется применение функций Len, Mid и Asc. В цикле For…Next переменная k пробегает по всем символам строки st, в окно Immediate выводятся символы строки и их коды.
Стеценко А. А. |
39 |
Листинг 17
Sub tstMid()
Dim st As String, sym As String * 1
Dim k As Integer
st = "09AaZz"
For k = 1 To Len(st) sym = Mid(st, k, 1)
Debug.Print "Символ: "; sym, "Код: "; Asc(sym) Next k
End Sub
Выдача в окно Immediate имеет вид:
Символ: 0 |
Код: |
48 |
Символ: 9 |
Код: |
57 |
Символ: A |
Код: |
65 |
Символ: a |
Код: |
97 |
Символ: Z |
Код: |
90 |
Символ: z |
Код: |
122 |
Функция Chr(Arg) возвращает символ, соответствующий коду Arg, т.е. её действие обратно по отношению к функции Asc(sym): Chr(Asc(х)) = х.
Функции LCase(Arg) и UCase(Arg) выполняют преобразование символов строкового аргумента Arg к нижнему (LCase) или верхнему (UCase) регистру. Другими словами, функция LCase делает все буквы строчными, а функция UCase – прописными. На другие символы, кроме букв, эти функции не действуют.
Рабочее задание. Подготовить и опробовать программу, использующую текстовые функции VBA
Выполнение
Р1. Скопируйте в свою книгу на свободный лист заданный список2. Переименуйте лист, чтобы его название соответствовало содержанию списка, например, “Группа П12-13”.
Р2. Перейдите в окно VBA и вставьте новый модуль. Дайте ему имя “Списки”. Р3. Составьте программу по образцу программы ReadFIO (листинг 18), которая читает значение ячейки с задаваемыми номерами строки и столбца и выводит прочитанное в окно Immediate. Обратите внимание, что именем объекта, выделяемого из коллекции WorkSheets, является имя рабочего листа, которое Вы дали в п. Р1 и которое не обязательно совпадает с тем, которое указано в
программе ReadFIO.
2 В лабораторном практикуме – это список одной из студенческих групп своего факультета, но это может быть любой другой список, содержащий фамилию, имя и отчество в одной строке.
40 Программирование в среде электронных таблиц Microsoft Excel
Листинг 18
Sub ReadFIO()
'Чтение текста из ячейки рабочего листа
' |
А.Стеценко, 13.04.2004 |
Dim |
ИсхСтрока As String |
Dim |
i As Integer, j As Integer |
Worksheets("Группа").Activate |
|
i = |
3 |
j = |
2 |
ИсхСтрока = Cells(i, j).Value Debug.Print ИсхСтрока
End Sub
Пояснения к программе ReadFIO
Инструкция
Worksheets("Группа").Activate
активизирует рабочий лист по его имени. Имя листа может указываться текстовой константой, как сделано в программе, или строковой переменной, например:
sn = "Группа" Worksheets(sn).Activate
Инструкция
ИсхСтрока = Cells(i, j).Value
считывает значение из ячейки с координатами i (номер строки) и j (номер столбца) и присваивает его переменной ИсхСтрока. Примененное здесь свойство Cells может использоваться для последовательного перебора ячеек по задаваемым индексам строки и столбца.
Инструкция Debug предназначена для отладки программы. Debug.Print – это вывод в окно отладки Immediate. Знание значений переменных оказывает неоценимую помощь при отладке программы.
Р4. Откройте окно Immediate (комбинация клавиш <Ctrl>+<G> или команда View | Immediate Window), щелкните мышкой где-нибудь в пределах программы ReadFIO и выполните её в пошаговом режиме (нажимая клавишу F8). Проверьте, соответствует ли строка, выведенная в окне Immediate, тексту в ячейке. Если да, переходите к следующему шагу задания, иначе ищите и устраняйте ошибки.
Р5. Добавьте в программу ReadFIO следующие строки (для каждой строки найдите подходящее по смыслу место в тексте программы):
dim s1 As String,s2 As String,s3 As String dim PosBlank As Integer
posblank = instr(ИсхСтрока, " ") s1 = left(ИсхСтрока, posblank-1)