Добавил:
По своей натуре перфекционист. Поэтому люблю все аккуратно оформлять и упорядочивать, складывать по полочкам. Вот, не пропадать же добру, нажитому за четыре кропотливых семестра. Тут я выложил все мои ответы, курсовые, отчеты и некоторые ДЗ. Они могут вам помочь для получения зачета или сдачи экзамена. Если чего-то не нашли в папочках, то попытайте удачу в разделе НЕОТСОРТИРОВАННОЕ на моей страничке, там все 4 семестра разложены по папкам. ГРУППА КТ-43-15. Годы обучения 2015-2019. Коллекция будет пополняться. Что ж, удачки :З Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

VBA (Стеценко) / VBA_ЛБ_13v2

.pdf
Скачиваний:
45
Добавлен:
15.09.2017
Размер:
1.87 Mб
Скачать

Стеценко А. А.

41

debug.print s1

Р6. Выполните полученную программу в пошаговом режиме. Следите за значениями переменных по всплывающей подсказке. Объясните результат, выведенный в окно Immediate, и способ его получения.

Р7. Добавьте в программу инструкции, использующие встроенные функции Len, Right, InStr, Left, с тем чтобы переменная s2 содержала имя, а переменная s3 – отчество. Контрольный вывод – в окно Immediate.

Р8. Когда получите правильный результат, оформите подпрограмму с четырьмя формальными строковыми переменными, одна из которых – исходная строка, а три остальные – результаты разделения. У вас должно получиться нечто, аналогичное по структуре и действиям подпрограмме Раздел (листинг 19).

Листинг 19

Sub Раздел(ИсхСтрока As String, _

 

s1 As String,

s2 As String, s3 As String)

'Выделение трёх слов из строки ИсхСтрока

'

А. Стеценко,

13.04.2004.

 

Dim sloc As String

 

 

Dim PosBlank As Integer,

Dlina As Integer

 

sloc = Trim(ИсхСтрока)

 

 

Dlina = Len(sloc)

 

 

PosBlank = InStr(sloc, "

")

 

s1 = Left(sloc, PosBlank

- 1)

 

sloc = LTrim(Right(sloc,

Dlina - PosBlank))

 

Dlina = Len(sloc)

 

 

PosBlank = InStr(sloc, "

")

 

s2 = Left(sloc, PosBlank

- 1)

s3 = LTrim(Right(sloc, Dlina - PosBlank))

End Sub

Пояснения к программе Раздел

О том, что Раздел является подпрограммой, свидетельствует список формальных аргументов в скобках после имени Раздел. Все формальные аргументы – ИсхСтрока, s1, s2 и s3 – являются строковыми. Из заголовка подпро-

граммы Раздел не ясно, какие формальные аргументы являются исходными данными, а какие результатами. Из анализа текста подпрограммы следует, что аргумент ИсхСтрока впервые встречается в правой части в инструкции

sloc = Trim(ИсхСтрока)

Значит, аргумент ИсхСтрока должен быть к этому моменту известен, поэтому ИсхСтрока – исходное данное для подпрограммы Раздел, т.е. это вход-

ной аргумент. Напротив, аргументам s1, s2 и s3 присваиваются значения, поэтому они являются результатами, возвращаемыми в вызывающую программу.

42

Программирование в среде электронных таблиц Microsoft Excel

Инструкция

sloc = Trim(ИсхСтрока)

отсекает возможные пробелы в начале и в конце строки ИсхСтрока. Это стандартный приём начальной обработки строк.

Функция Len (length – длина) определяет длину строки (число символов в строке).

В инструкции

PosBlank = InStr(sloc, " ")

функция InStr ищет позицию первого пробела, заданного вторым аргументом, в строке sloc. В следующей инструкции в переменную s1 переписываются левые символы строки sloc до первого пробела:

s1 = Left(sloc, PosBlank – 1)

В инструкции

sloc = LTrim(Right(sloc, Dlina - PosBlank))

переменной sloc присваивается новое значение, а именно правая часть исходной строки после первого пробела, причем удаляются возможные повторные пробелы между первыми двумя словами исходной строки. Дальнейшие действия в программе повторяют поиск первого пробела, выделение символов слева и справа от него и записывание их в переменные s2 и s3.

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

Р9. Составьте программу проверки подпрограммы Раздел. Тест программы должен содержать: описание четырех строковых переменных, задание значения одной переменной, обращение к подпрограмме Раздел и вывод результатов в окно отладки (для справки можете воспользоваться программой tstРаздел, листинг 20).

Листинг 20

Sub tstРаздел()

'Проверка подпрограммы Раздел

Dim t1 As String, t2 As String, t3 As String, _ t4 As String

t1 = " Репин Илья Ефимович "

Раздел t1, t2, t3, t4 Debug.Print t2; t3; t4

End Sub

Стеценко А. А.

43

Пояснения к программе tstРаздел

Это простая программа, предназначенная для проверки правильности работы подпрограммы Раздел. В ней объявляются четыре строковые переменные

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

ские аргументы. Значения переменным t2, t3 и t4 присваиваются в подпрограмме Раздел.

Контрольные вопросы к работе VBA7

К1. Объясните, чем строковое (текстовое) данное отличается от числового. К2. Какие операции возможны со строковыми данными?

К3. На экране изображена цепочка цифр 123. Это строковое данное или числовое?

К4. Можно ли утверждать, что строки 456,0 и 456,00 отображают одно и то же число?

К5. Объясните назначение строковых функций Asc и Chr. Почему им даны такие имена? (Подсказка: вспомните значения слов ASCII и Character)

К6. Английское слово trim имеет несколько значений, одно из которых – снимать заусенцы. А что делают функции Trim, Ltrim, Rtrim?

К7. Принято говорить, что функция возвращает значение. Какое значение и куда возвращает функция?

К8. Какое значение возвращает функция InStr?

К9. Чему равно значение функция InStr, если первым аргументом является строка "абракадабра”, а вторым аргументом – символ "а"?

К10. Имя функции Len является сокращением английского слова length – длина. В каких единицах измеряется длина строки?

К11. Оказывают ли пробелы в начале и/или в конце строки влияние на её длину?

К12. Напишите обращение к функции Mid, чтобы из строки "ЯнварьФевральМартАпрель" получить строку "Март".

К13. Какое значение имеет а = Mid(b,i,k), если b="2004", i=3, k=1? К14. Из строк "Новый" и "Год" получите строку "Новый Год". К15. Как выполнить программу в пошаговом режиме?

К16. Как получить всплывающую подсказку со значением переменной при шаговом выполнении программы?

К17. Объясните назначение окна Immediate. Как вывести это окно на экран и как его закрыть?

К18. Объясните разницу в действии двух инструкций отладочной печати:

Debug.Print s1, s2

Debug.Print s1; s2

К19. Чему равно значение функции Chr(Asc(A))?

К20. Чему равно значение функции Chr(Asc(A) + 32)?

44

Программирование в среде электронных таблиц Microsoft Excel

К21. Чему равно значение функции Asc(1)? К22. Чему равно значение функции Chr(49)?

К23. Среди символов управления ASCII имеются символы CR (Carriage Return

– возврат каретки) и LF (Line Feed – перевод строки). А для чего предназначены встроенные в VBA константы vbCr, vbLf, vbCrLf?

Работа VBA8. Циклы и массивы (1)

Цель работы: закрепление навыков подготовки программ в стандартном модуле, ознакомление с применением массивов и циклов счетного типа и по членам коллекции объектов.

Введение

Массивы

Массив – это программная составная структура данных, элементами которой являются данные одного типа. Все элементы массива имеют одно имя и распознаются по индексу, определяющему место элемента среди других элементов. В следующем примере объявляется массив с именем Arr, имеющий 1000 элементов типа Long:

Dim Arr (999) As Long

Здесь Dim – ключевое слово описания данных; 999 – значение верхнего индекса, так что элементами массива являются Arr(0), Arr(1), …, Arr(999). По умолчанию индексы массива отсчитываются с 0, но программист может назначить любые граничные значения индексов:

Dim Arr2 (1 To 1000) As Long

Dim Count (-7 To 7) As Double

В приведённых инструкциях объявлены одномерный целочисленный массив Arr2 из 1000 элементов и массив типа Double из 15 элементов с индексами от -7 до +7.

Хотя правила Visual Basic позволяют задавать любые граничные значения индексов массивов, не следует злоупотреблять этой возможностью. Обратим внимание, что в языках С/С++ индексы массивов всегда отсчитываются с 0, чтобы уменьшить время, затрачиваемое на вычисление адресов элементов массивов.

По отношению к массивам существуют понятия "размер" и "размерность". Размер массива – это количество элементов в массиве. Размерность – это количество координат, определяющих элемент массива. Каждая координата задаётся своим индексом, поэтому размерность можно понимать как количество индексов, требующихся для идентификации элемента массива. Наибольшее распространение в программах получили одномерные массивы. Как показывает определение "одномерные", для идентификации элемента одномерных массивов требуется один индекс. Все приведённые примеры показывают объ-

Стеценко А. А.

45

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

Для массивов в Visual Basic определены функции LBound и UBound, возвращающие нижнее (LBound) и верхнее (UBound) значения индексов массива. Применительно к вектору (одномерному массиву) Arg обращения к этим функциям выглядят так:

Low =

LBound(Arg)

'Нижний индекс

High =

UBound(Arg)

'Верхний индекс

Visual Basic позволяет изменять размер массива во время выполнения программы. Для этой цели используется инструкция ReDim. В следующем примере вектор Х переопределяется на N элементов после того, как стало известно значение N.

Dim

X()

As

Double

'Предварительное описание вектора Х

Dim

N

As Long

 

 

 

. . .

 

 

'Какие-то действия, связанные

с

вычислением N

ReDim

X

(N

– 1)

'Т.к. нижний индекс

=

0.

Может возникнуть ситуация, когда необходимость изменить размеры массива обнаружилась после того, как часть элементов массива получила значения, которые требуется сохранить. В таком случае используется ключевое слово Preserve:

ReDim Preserve X(N – 1) 'Все элементы массива Х сохраняются

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

Циклы

Цикл – это программная управляющая структура, обеспечивающая многократное выполнение одной и той же последовательности инструкций. В любом языке программирования имеются специальные средства для реализации циклов – операторы (или инструкции) циклов. Одним из операторов цикла в Visual Basic является For…Next. Этот оператор записывается так:

For k = K1 To K2 Step K3

'Операторы тела цикла

Next k

Первая строка называется заголовком цикла. Переменную k называют счётчиком цикла: цикл должен выполниться столько раз, сколько значений может иметь счётчик цикла. К1 – первое значение счётчика k, К2 предполагаемое последнее значение k, К3 – шаг изменения k. Оператор For…Next работает по следующему алгоритму:

46

Программирование в среде электронных таблиц Microsoft Excel

Шаг 1. Присвоить счётчику цикла первое значение: k K1.

Шаг 2. [Проверка.] Если k K2 перейти к шагу 3, иначе перейти к шагу 6. Шаг 3. Выполнить операторы тела цикла.

Шаг 4. [Изменение счётчика.] Вычислить k k+K3. Шаг 5. Перейти к шагу 2.

Шаг 6. Завершить оператор цикла.

Если шаг К3 равен 1, он может не указываться:

For k = K1 To

K2

'Шаг = 1.

'Операторы

тела цикла

 

Next k

 

 

Циклы счётного типа исключительно удобны для работы с массивами и часто применяются именно для этой цели. В следующем примере подсчитывается количество отрицательных значений в векторе Y.

Dim Y()

As Single

Dim N

as Integer, i As Integer, Neg As Integer

. . .

 

 

ReDim

Y

(N – 1)

. . .

 

 

Neg =

0

 

For i

=

0 To N – 1

If

Y(i) < 0 Then Neg = Neg + 1

Next i

 

 

Используя свойство Cells, можно в цикле счётного типа обработать произвольный диапазон ячеек. В следующем примере (листинг 21) подсчитывается количество пустых ячеек в первом столбце диапазона "Регион".

Листинг 21 Подсчёт числа пустых ячеек (вариант 1)

Dim Diap As Range

 

Dim Pusto

As Long

'Счётчик пустых ячеек

Dim iR As

Long, jC As Long

'Координаты диапазона

Dim KolRow As Long

'Число строк в диапазоне

Dim p As Long

 

Set Diap = Range("Регион")

 

iR = Diap.Row

 

jC = Diap.Column

 

KolRows =

Diap.Rows.Count

 

Pusto = 0

 

 

For p = 0

To KolRows - 1

 

If IsEmpty(Cells(p + iR, jC)) Then Pusto = Pusto + 1 Next p

После объявления переменных определяются координаты диапазона – номер строки (iR) и номер столбца (jC) левой верхней ячейки диапазона. Для этого используются свойства Row и Column объекта Diap типа Range, сопоставленного диапазону "Регион" инструкцией

Стеценко А. А.

47

Set Diap = Range("Регион")

Переменной KolRows присваивается значение свойства Count коллекции

Rows объекта Diap:

KolRows = Diap.Rows.Count

В цикле For… Next сумма (p + iR) пробегает по всем строкам диапазона. Функция IsEmpty возвращает значение True, если её аргументом является пустая ячейка.

Подробные сведения об операторах циклов Visual Basic можно найти в литературе и в справочной системе, а здесь остановимся на операторе For Each…Next, цикле объектного типа. Заголовок этого оператора имеет вид

For Each var In Vars

Vars – это имя коллекции объектов, var – переменная объектного типа или типа Variant. Смысл приведённого заголовка цикла заключается в том, что переменная var должна пробежать по всем членам коллекции, представляя очередной член коллекции при очередном проходе по телу цикла. В следующем примере (листинг 22) решается та же задача подсчёта числа пустых ячеек в диапазоне, что и в предыдущем примере (листинг 21).

Листинг 22 Подсчёт числа пустых ячеек (вариант 2)

Dim Diap As Range, cell As Range

 

Dim Pusto As Long

'Счётчик

пустых ячеек

Set Diap = Range("Регион")

 

Pusto = 0

 

 

For Each cell In Diap.Cells

 

If cell.Column = Diap.Column

And _

IsEmpty(cell) Then Pusto

= Pusto + 1

Next cell

 

 

В инструкции If, составляющей тело цикла, сначала проверяется, находится ли текущая ячейка в том же столбце, в котором начинается диапазон, а затем проверяется, пустая ли она. Программа, как видим, стала заметно короче.

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

Выполнение

Р1. Откройте свою книгу и, полюбовавшись на приветствие, перейдите в окно VBA и в нижней части модуля “Списки” наберите текст программы

ИмяДиапазона (листинг 23).

Листинг 23

Sub ИмяДиапазона()

'Присвоение имени диапазону исходного списка

48

Программирование в среде электронных таблиц Microsoft Excel

'Принимается, что в группе может быть не более 50 студентов

Worksheets("Группа").Activate

Range("b2:b51").Name = "СписокГруппы"

End Sub

Р2. Выполните программу ИмяДиапазона в пошаговом режиме.

Р3. Перейдите в окно приложения, раскройте список в окне Имя и выберите имя “СписокГруппы”. Диапазон ячеек В2:В51 должен выделиться.

Р4. Перейдите в окно VBA, ещё раз проанализируйте программу ИмяДиапа-

зона, найдите и запомните синтаксис инструкции, присваивающей имя выделенному диапазону. В окне модуля “Списки” ниже программы ИмяДиапазона наберите текст программы Separate (листинг 24). Изучите текст программы, постарайтесь понять смысл всех декларативных и императивных инструкций (в этом Вам помогут комментарии). В инструкции выбора рабочего листа укажите имя, которое Вы дали, выполняя п. Р1 работы VBA7.

Листинг 24

Sub Separate()

'Чтение списка студентов,

'разделение строки на составляющие поля

А. Стеценко, 16.04.04. Dim Ячейка As Object

Dim NumCol As Integer, KolStud As Integer Dim GroupFio() As String

Dim Fam() As String, Imja() As String, Otch() As String Dim i As Integer

'Активизация рабочего листа

Worksheets("Группа").Activate

' Подсчёт числа непустых строк в диапазоне "СписокГруппы"

Range("СписокГруппы").Select KolStud = 0

For Each Ячейка In Selection.Cells

If Not IsEmpty(Ячейка) Then KolStud = KolStud + 1 Next Ячейка

'Переопределение рабочих массивов

ReDim GroupFio(1 To KolStud) ReDim Fam(1 To KolStud) ReDim Imja(1 To KolStud) ReDim Otch(1 To KolStud)

'Номер столбца диапазона "СписокГруппы" NumCol = Range("СписокГруппы").Column

'Ввод исходного списка в массив GroupFio

For i=1 To KolStud

GroupFio(i) = Cells(i + 1, NumCol).Value Next i

'Разделение строк массива GroupFio на составляющие

 

 

Стеценко А. А.

49

 

 

 

 

'

с использованием

подпрограммы Раздел

 

For

i = 1 To KolStud

 

 

 

Call Раздел(GroupFio(i), Fam(i), Imja(i), Otch(i))

 

Next i

 

 

'Вывод результатов на рабочий лист

 

'Вывод заголовков граф

 

Cells(i, NumCol + 1)

= "Фамилия"

 

Cells(i, NumCol + 2)

= "Имя"

 

Cells(i, NumCol + 3)

= "Отчество"

 

'Вывод результатов

 

 

For

i = 1 To KolStud

 

 

 

Cells(i + 1, NumCol + 1) = Fam(i)

 

Cells(i + 1, NumCol + 2) = Imja(i)

Cells(i + 1, NumCol + 3) = Otch(i)

Next i

End Sub

Р5. Убедитесь, что курсор находится в пределах программы Separate и дайте команду Run | Run Sub/UserForm. Эту команду можно дать, нажав клавишу F5 или щёлкнув по кнопке Run Sub/UserForm (найдите её по всплывающей подсказке).

Р6. Перейдите в окно приложения и внимательно рассмотрите результат работы программы Separate.

Пояснения к программе Separate

После заголовка и вводного комментария идут декларативные инструкции описания. Наряду с простыми переменными i, KolStud, NumCol описываются массивы GroupFIO, Fam, Imja, Otch без указания границ индексов. Это так называемые динамические массивы. Подобный приём описания “безразмерных” массивов используется в тех случаях, когда программа сама должна определить размеры (количество элементов) массивов.

Первый цикл это цикл For Each…Next по всем ячейкам диапазона, выделенного предыдущей инструкцией Range. Переменной цикла является объ-

ектная переменная Ячейка. VBA сам определяет тип объекта, связанного с переменной Ячейка, по типу, указанному после служебного слова In в заголовке цикла. В данном случае объектом является семейство ячеек выделенного диапазона. Функция IsEmpty возвращает True, если ячейка пустая, и False, если в ячейке имеется значение. Следовательно, Not IsEmpty(Ячейка) имеет значение True для непустых ячеек, и инструкция If…Then обеспечивает увеличение на 1 значения счётчика KolStud.

Инструкции ReDim переопределяют динамические массивы на известное количество элементов и устанавливают границы индексов массивов от 1 до

KolStud.

В инструкции

50 Программирование в среде электронных таблиц Microsoft Excel

NumCol = Range("СписокГруппы").Column

переменной NumCol присваивается номер столбца, содержащего диапазон “СписокГруппы”. Для этой цели используется свойство Column объекта Range. Кажется, что проще было бы указать номер столбца в явном виде и не определять его в программе. На это есть веские возражения. Программа никогда не пишется для однократного применения. В реальной жизни может оказаться, что в начале таблицы приходится добавлять или удалять столбцы, а программу желательно не переделывать. Программа должна приспосабливаться к возможным внешним изменениям.

Остальные три цикла в программе Separate – это циклы счётного типа For…Next. В первом из них данные из таблицы вводятся в массив GroupFio, во

втором с помощью подпрограммы Раздел заполняются векторы Fam, Imja и Otch, в третьем точно таком же цикле данные из векторов Fam, Imja, Otch выводятся на рабочий лист. Подобное разделение функциональных блоков в программе на блоки ввода, обработки и вывода является нормой. На первый взгляд может показаться, что, поскольку все три цикла одинаковы по заголовкам и выполняются за одно и то же число повторений, то их можно объединить в один и совместить в нем ввод, обработку (в данном случае – разделение одной строки на три составляющие) и вывод. Никогда не поддавайтесь искушению к такому совмещению. Не всегда ввод проходит гладко, но всегда требуется проверка правдоподобности, полноты и непротиворечивости вводимых данных. Обработка данных может быть довольно сложной и связанной с обращением к множеству подпрограмм. Наконец, очень редко ввод и вывод связаны с одной таблицей и с одним файлом. Если исходные данные и результаты размещаются на разных листах даже в одной книге, при совмещении трёх циклов в один основное время выполнения программы уйдет на переключение между листами ввода и вывода.

Контрольные вопросы к работе VBA8

К1. Определите понятие “тип данных”.

К2. Определите понятие “простая переменная”. К3. Определите понятие “массив“.

К4. Определите понятия “размерность массива” и “размер массива”.

К5. Какие массивы называются “векторами” и “матрицами”? К6. Сколько элементов содержится в массиве D(5)?

К7. Для чего предназначена директива Option Base 1? К8. Что может быть индексом массива?

К9. Для чего предназначены программные структуры “цикл”? К10. Может ли цикл продолжаться бесконечно долго?

К11. Какие Вы знаете условия окончания действий в цикле?

К12. Когда выполняется проверка условия окончания цикла For…Next: до выполнения каких-либо действий в цикле или после первого выполнения всех действий цикла?

Соседние файлы в папке VBA (Стеценко)
  • #
    15.09.201752.92 Кб19SergeevA.xlsm
  • #
    15.09.20171.87 Mб45VBA_ЛБ_13v2.pdf
  • #
    15.09.2017799 б16ВосГазСорт.dat
  • #
    15.09.2017799 б16ВоспламГаз.dat
  • #
    15.09.201724.18 Кб18ВосплГаз.xlsm