Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Приемы программирования в среде Visual Basic for Application. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
If Not IsEmpty(AW.Cells(1, 1)) And _ Not IsEmpty(AW.Cells(1, 2)) Then
Если их (данных) нет, то выводим сообщение об этом и закры­ваем книгу без сохранения сделанных изменений
MsgBox "На листе открытой книги данных нет", _ vbInformation + vbOKOnly ActiveWorkbook.Close False
Иначе подготавливаем место для сохранения данных на листе «Эксперимент». Для этого определяем переменную
ic = 1
(номер первого столбца на листе «Эксперимент») и ищем свободный столбец с приращением в 2 столбца:
ic = 1 Do While Not IsEmpty(TW.Cells(1, ic)) ic = ic + 2 Loop
Теперь вносим начальные данные по серии – дату, время и имя
файла
TW.Cells(1, ic) = Date TW.Cells(1, ic + 1) = Time TW.Cells(2, ic) = ActiveWorkbook.Name
Остается перенести сами данные, и сосчитать их количество. Для этого используем две переменные строки в файле данных и
ke = 0
– число экспериментов в серии. Хо-
ir = 1
– текущий номер
тя можно воспользоваться и одной переменной с прибавлением или отниманием 1. Потом в цикле с предусловием переносим данные:
ir = 1: ke = 0 Do While Not IsEmpty(AW.Cells(ir, 1)) Or _ Not IsEmpty(AW.Cells(ir, 2)) TW.Cells(ir + 3, ic) = AW.Cells(ir, 1) TW.Cells(ir + 3, ic + 1) = AW.Cells(ir, 2) ir = ir + 1: ke = ke + 1 Loop
Строки в листе «Эксперимент» будут отличаться от строк на листе с исходными данными на 3 из-за наличия дополнительной ин­формации в 3-х первых строках. Если возникнут другие требования, то можно просто изменить это число и добавить или уменьшить чис­ло строк с дополнительными данными. После переноса всех данных остается только закрыть файл с данными, и внести в третью строку данных на листе «Эксперимент» число пар данных в серии:
ActiveWorkbook.Close False
- 81 -
TW.Cells(3, ic) = ns
В полном виде программа показана ниже:
Public Sub Get_Dates() R = Application.Dialogs(xlDialogOpen).Show If R Then Set AW = ActiveWorkbook.Sheets(1) Set TW = ThisWorkbook.Sheets("Эксперимент") If Not IsEmpty(AW.Cells(1, 1)) And _ Not IsEmpty(AW.Cells(1, 2)) Then ic = 1 Do While Not IsEmpty(TW.Cells(1, ic)) ic = ic + 2 Loop TW.Cells(1, ic) = Date TW.Cells(1, ic + 1) = Time TW.Cells(2, ic) = ActiveWorkbook.Name ir = 1: ke = 0 Do While Not IsEmpty(AW.Cells(ir, 1)) Or _ Not IsEmpty(AW.Cells(ir, 2)) TW.Cells(ir + 3, ic) = AW.Cells(ir, 1) TW.Cells(ir + 3, ic + 1) = AW.Cells(ir, 2) ir = ir + 1: ke = ke + 1 Loop ActiveWorkbook.Close False TW.Cells(3, ic) = ns Else MsgBox "На первом листе книги данных нет", _ vbInformation + vbOKOnly End If Else MsgBox "Для работы укажите файл с данными", _ vbInformation + vbOKOnly End If End Sub
Здесь мы рассмотрели приемы записи и считывания данных на листах книги. Наряду с этими приемами мы можем управлять непо­средственно событиями, как книги, так и отдельными ее листами. Для этого мы должны писать свой программный код в специальные моду­ли самих объектов. Причем в них обычно пишутся программы обра­ботки событий, которые характерны этим объектам. Так, например, для книги могут быть реализованы события:
- 82 -
• Activate – происходит в момент активации листа. В этот момент
мы может настроить вид листа (выбрать масштаб просмотра, опре­делить активную ячейку, вывести определенную область листа на экран и т.п.);
• Deactivate – противоположное событие, происходящее перед вы-
бором другого листа. Здесь можно проверить правильность вве­денных данных, и при выявленных ошибках вернуть пользователя для их исправления, выполнить какие-либо расчеты, которые тре­буют времени и были деактивированы при вводе данных на листе, и другие операции;
• Change – в момент изменения данных в ячейках листа. Здесь
обычно проводят проверки правильности ввода данных;
• SelectionChange – изменение положения курсора ввода данных с
одной ячейки на другую. Тут отслеживаются ситуации, когда тре­буется контролировать ввод только в разрешенные ячейки.
Имеются и другие события, которые можно использовать для управления листом при различных действиях мышки, пересчетах формул на листе и др.
Свои события имеют и книги. Чаще всего используются события управления книгой:
• Open – в момент открытия книги. Здесь настраиваются вид оболочки
Excel, запускаются пользовательские формы, выполняются первона- чальные расчеты и подготовка памяти для дальнейших работ;
• Группа событий Before… Close, Save, Print и другие. В них
можно выполнить действия перед выполнением указанных выше операций закрытия книги, печати и сохранения или проверить пра­вомочность этих действий и отказаться от их выполнения;
• Имеются операции, привязанные к листам, которые были описаны
выше, и в них можно писать процедуры и привязывать их к раз­личным листам, так как в формальном параметре программы при­сутствует имя листа.
Попробуем расширить возможности наших программ, написан­ных выше с использованием операций с обработкой событий.
Для программы построения графиков добавим событие Open, в котором запишем проверку на открытие листа «Данные». Для собы­тия листа «Данные» в событие SelectionChange введем контроль ввода данных только в разрешенные ячейки. И последняя проблема – поставить элемент управления для построения графика. Посмотрим,
- 83 -
как выполнить эти исправления. Для этого открываем файл «VBA_График.xls», входим в редактор VBA, и открываем модуль «ЭтаКнига» (рис.29). В окне модуля (слева) выбираем в левом выпа-
дающем списке объект –WorkBook и в правом событие Open.
Рис.29. Выбор модуля «ЭтаКнига» и ввод кода в событие Open
В предложенную заготовку вписываем одну строку:
ThisWorkbook.Sheets("Данные").Activate
Теперь переходим к «Лист2(Данные)», выбираем объект WorkSheet и событие SelectionChange (Рис.30). Здесь надо поду­мать об алгоритме работы программы. Нам надо сделать так, чтобы программа могла проверить разрешен ввод данных в эту ячейку или нет.
Вначале мы закрасили все ячейки светло-зеленым фоном, давай­те примем правило, если ячейка имеет фон отличный от заданного, то ввод в нее недопустим, надо найти следующую ячейку с нужным цветом. Вспомним вид нашего листа с данными для графика:
- 84 -
Рис.30. Выбор модуля «Лист2(Данные)» и событие SelectionChange
Реально нам надо искать нужные ячейки в области от «B2:G4». Попробуем записать макрос, который будет искать нужные нам ячей­ки. Для этого выполняем все необходимые операции в режиме записи макроса, как было показано выше.
Вызываем команду СервисМакросыНачать запись, со­глашаемся с предложенным именем макроса и начинаем записывать саму программу:
• Выделяем диапазон от ячейки B2 до G4;
• Вызываем команду поиска ПравкаНайти…;
• На панели Найти и заменить нажимаем кнопку Параметры;
• На открывшейся расширенной панели поиска нажимаем кнопку
Формат;
• В открывшемся окне Найти формат открываем закладку Вид и
выбираем необходимый нам цвет;
• Подтверждаем выбор цвета кнопкой Ok и нажимаем кнопку Най-
ти далее;
• Завершаем запись макроса.
Переходим в редактор VBA и видим там новый модуль «Мо­дуль2», в нем созданный нами макрос.
Range("B2:G4").Select Application.FindFormat.Interior.ColorIndex = 35 Selection.Find(What:="", After:=ActiveCell, _ LookIn:=xlFormulas, LookAt:=xlPart, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=False, SearchFormat:=True).Activate
- 85 -
В первой строке мы выделили диапазон, а во второй задаем по­иск по формату, и далее выполняем поиск внутри указанного диапа­зона. Ведем поиск по рядам со следующей ячейки после активной. Теперь остается доработать код программы до нужного нам вида. Наиболее сложная задача возникает, если пользователь делает актив­ной ячейку вне диапазона поиска, эта ситуация приведет к ошибке. Второй задачей является отказ от поиска, если ячейка нас удовлетво­ряет. В результате получаем следующий код:
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Interior.ColorIndex = 35 Then Exit Sub Ok = False If Target.Row < 2 Then r = 2: Ok = True ElseIf Target.Row > 4 Then r = 4: Ok = True Else r = Target.Row End If If Target.Column < 2 Then c = 2: Ok = True ElseIf Target.Column > 7 Then c = 7: Ok = True Else c = Target.Column End If If Ok Then Cells(r, c).Activate Range("B2:G4").Find(What:="", _ After:=ActiveCell, _ LookIn:=xlFormulas, _ LookAt:=xlPart, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=False, _ SearchFormat:=True).Activate End Sub
Разберем его более подробно. В первой строке проверяем, удов­летворяет нас ячейка, которая в данный момент выбрана, и выходим из программы, если это так. Дальше проверяем, находится ли актив­ная ячейка внутри диапазона поиска. Если это не так, выбираем бли­жайшую к ней ячейку внутри диапазона, и делаем эту ячейку актив­ной. Переменная Ok сообщает о необходимости перемещения актив-
- 86 -
ной ячейки внутри диапазона. Теперь можно выполнять поиск необ­ходимой ячейки.
Ясно, что для полнофункциональной версии работы программы надо вывести на лист элемент управления, который будет вызывать под­программу построения графика. Воспользуемся формами для управле­ния объектами. Вызовем стандартную панель инструментов Формы, и выберем кнопку. Нарисуем ее на листе ниже заголовков для графика. Как только мы завершаем рисование кнопки, открывается меню выбора макроса, который будет привязан к этой кнопке, и выбираем MakeGraf. После этого предлагается изменить заголовок кнопки. Пишем «Строим
график», и получаем кнопку вида . Можно настроить и ряд других параметров, если вызвать с помощью контекстного меню
свойства этого объекта.
Лабораторные задания по темам
Целочисленное программирование
Все входные и выходные данные в заданиях этой группы явля­ются целыми числами. Все числа, для которых указано количество цифр (двузначное число, трехзначное число и т.д.), считаются поло­жительными.
1. Даны две целые переменные а, b. Составить фрагмент программы,
после исполнения которого значения переменных поменялись бы местами (новое значение а равно старому значению b и наоборот).
2. Дано расстояние L в сантиметрах. Используя операцию деления
нацело, найти количество полных метров в нем (1 метр = 100 см).
3. Дан размер файла в байтах. Используя операцию деления нацело,
найти количество полных килобайтов, которые занимает данный файл (1 килобайт = 1024 байта).
4. Даны целые положительные числа A и B (A > B). На отрезке длины
A размещено максимально возможное количество отрезков длины B (без наложений). Используя операцию взятия остатка от деления
нацело, найти длину незанятой части отрезка A.
5. Определить, является ли данное целое число четным.
6. Определить, верно ли, что при делении неотрицательного целого
числа а на положительное целое число b получается остаток, рав­ный одному из двух заданных чисел r или s.
7. Дано двузначное число. Найти сумму и произведение его цифр.
- 87 -
8. Дано двузначное число. Вывести число, полученное при переста-
(
)
++=
(
)
(
)
новке цифр исходного числа.
9. Дано натуральное число (n ≤99). Выяснить верно ли, что равно n2
кубу суммы цифр числа n.
10. Дано натуральное число n (n ≤ 100).
а) Сколько цифр в числе n?
б) Чему равна сумма его цифр?
в) Найти последнюю цифру числа n.
г) Найти первую цифру числа n.
д) В предположении, что n≥10, найти предпоследнюю цифру числа n.
Ввод и вывод данных, оператор присваивания
Все входные и выходные данные в заданиях этой группы явля­ются вещественными числами.
1. Дана сторона квадрата a. Найти его периметр P = 4·a.
2. Даны стороны прямоугольника a и b. Найти его площадь S = a·b и
периметр P = 2·(a + b).
3. Дан диаметр окружности d. Найти ее длину L = π·d.
4. Дана длина ребра куба a. Найти объем куба V = a3 и площадь его
поверхности S = 6·a2.
5. Даны длины ребер a, b, c прямоугольного параллелепипеда. Найти
его объем V = a·b·c и площадь поверхности S = 2·(a·b + b·c + a·c).
6. Найти длину окружности L и площадь круга S заданного радиуса
R: L = 2·π·R, S = π·R2.
7. Даны два неотрицательных числа a и b. Найти их среднее геомет-
рическое, то есть квадратный корень из их произведения:
bа ⋅
8. Даны два ненулевых числа. Найти сумму, разность, произведение
и частное их квадратов.
9. Даны катеты прямоугольного треугольника a и b. Найти его гипо-
тенузу c и периметр P:
22
bас +=
,
cbaP
.
10. Даны два круга с общим центром и радиусами R1 и R2 (R1 >
R2). Найти площади этих кругов S1 и S2, а также площадь S3
кольца, внешний радиус которого равен R1, а внутренний радиус равен R2:
π
11
,
π
2
RS ⋅=
RS ⋅=
2
22
,
- 88 -
SSS −=
.
213
Логические выражения: группа Boolean
Во всех заданиях данной группы требуется вывести логическое значение True, если приведенное высказывание для предложенных ис­ходных данных является истинным, и значение False в противном случае. Все числа, для которых указано количество цифр (двузначное число, трехзначное число и т.д.), считаются целыми положительными.
1. Дано целое число A. Проверить истинность высказывания: «Число
A является положительным».
2. Дано целое число A. Проверить истинность высказывания: «Число
A является нечетным».
3. Даны два целых числа: A, B. Проверить истинность высказывания:
«Справедливы неравенства A > 2 и B ≤ 3».
4. Даны два целых числа: A, B. Проверить истинность высказывания:
«Справедливы неравенства A ≥ 0 или B < –2».
5. Даны три целых числа: A, B, C. Проверить истинность высказыва-
ния: «Число B находится между числами A и C».
6. Даны два целых числа: A, B. Проверить истинность высказывания:
«Хотя бы одно из чисел A и B нечетное».
7. Даны три целых числа: A, B, C. Проверить истинность высказыва-
ния: «Хотя бы одно из чисел A, B, C положительное».
8. Дано целое положительное число. Проверить истинность высказы-
вания: «Данное число является четным двузначным».
9. Дано целое положительное число. Проверить истинность высказы-
вания: «Данное число является нечетным трехзначным».
10. Проверить истинность высказывания: «Среди трех данных це-
лых чисел есть хотя бы одна пара взаимно противоположных».
11. Дано трехзначное число. Проверить истинность высказывания:
«Все цифры данного числа различны».
Условный оператор: группа If
1. Петя встал утром в 7 часов, Коля - на 13 минут раньше него, Сере-
жа на 4 минуты позже Коли, а Саша встал на 10 минут позже Се­режи. Кто встал раньше, Петя или Саша?
2. У Сережи 145 рублей. Он решил купить 3 блокнота по 48 рублей.
Хватит ли денег на покупку?
3. Из куска ткани можно сшить 17 детских плащей, расходуя на каж-
дый 2 м ткани. Можно ли из этого куска сшить 8 плащей для взрослых, расходуя по 4 м ткани на каждый плащ?
- 89 -
4. В коробке 3 кг лимонов и апельсинов. Лимоны вынули и взвесили
отдельно. Их масса оказалась 1 кг 760 г. Каких цитрусовых больше и на сколько?
5. Валя взяла у подруги книгу на 3 дня. В первый день она прочитала
А страниц, во второй день прочитала в В раз больше, чем в пер­вый, в третий день она прочитала на С страниц меньше, чем во второй. Успела ли Валя прочитать книгу вовремя, если в книге 194 страницы? Решить задачу при следующих значениях переменных:
а) А = 28, В = 3, С = 25;
b) А = 30, В = 3, С = 16.
6. Мотоциклист должен прибыть в город через Т часов после выезда
из пункта, находящегося на расстоянии S км от города. Успеет ли он вовремя прибыть в город, если в первый час он проедет А км, а все оставшееся время будет ехать со скоростью В км/ч? Решить за­дачу при следующих значениях переменных:
a) Т = 4, S = 320, А = 75, В = 70; b) Т = 5, S = 300, А = 65, В = 60.
7. В театр пришло А зрителей. Из них В человек купили билеты по 30
рублей, остальные - по 20 рублей. Получит ли театр прибыль, если расходы на спектакль составили Z рублей? Решить задачу при сле­дующих значениях переменных:
a) А = 800, В = 300, Z = 15000; b) А = 600, В = 100, Z = 15000.
8. Расстояние между городами А и В равно S. Из города А в город В
выехал велосипедист со скоростью Vr, через Т часов вслед ему вы­ехал 2-й велосипедист со скоростью Vt. Догонит ли 2-й велосипе­дист 1-го, прежде чем тот доедет до города B? Решить задачу при следующих значениях переменных:
a) S = 50, Vr = 12, ,= 16, Т = 2;
b) S = 50, Vr= 12, Vt = 16, Т= 1.
9. Дано целое число. Если оно является положительным, то приба-
вить к нему 1; если отрицательным, то вычесть из него 2; если ну­левым, то заменить его на 10. Вывести полученное число.
10. Даны пять целых числа. Найти количество положительных и ко-
личество отрицательных чисел в исходном наборе.
11. Даны два числа. Вывести их на экран дисплея в порядке возрас-
тания.
- 90 -
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]