Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
59
Добавлен:
12.04.2015
Размер:
310.78 Кб
Скачать

Порядок составления и отладки программы в среде vba

Постановка задачи

Любая программа начинается с постановки задачи на программирование. Прежде чем засесть за компьютер и начать лихорадочно нажимать на клавиши программист должен провести не один час за уяснением содержания задачи, продумыванием сценария работы программы, составом ее программных блоков, алгоритмом их взаимодействия, прикинуть наброски экранных форм пользовательского интерфейса, определить для себя порядок кодирования (написания) программных модулей, возможные методы контроля правильности их работы и только потом, имея все эти материалы под рукой, нажать на кнопку <POWER> (включение) компьютера.

Условие задачи

Написать программный модуль, который бы, в выделенной прямоугольной области из клеток (ячеек) таблицы EXCEL, производил перестановку числовых данных в порядке возрастания.

Этап 1 (Уяснение задачи).

Итак – перестановка числовых данных по возрастанию. «Но ведь в EXCEL уже есть встроенные инструменты для сортировки»- скажут продвинутые пользователи? Да есть, но они переставляют (сортируют) данные либо целиком по столбцам, либо целиком по строкам. В задаче же требуется сортировать данные В ПРЯМОУГОЛЬНОЙ ОБЛАСТИ, выделенной пользователем, то есть они должны выстраиваться друг за другом как фишки на шахматной доске или в игре «15», увеличивая свои значения слева направо и затем переходя на новую строку.

Этап 2 (Разработка сценария функционирования программы)

Предлагается такая последовательность работы с программой: пользователь выделяет с помощью мыши (или другими любыми стандартными методами) на ЛЮБОМ листе EXCEL в ЛЮБОМ месте прямоугольную область ЛЮБОГО размера, содержащую числовые данные – рисунке 11а.

34

123

8

-12

0

1

0

5

1

5

6

8

9

-12

6

9

34

123

Рисунок 11а Рисунок 11б

Стандартной командой через меню СЕРВИС-МАКРОС-МАКРОСЫ-ВЫПОЛНИТЬ (или горячими клавишами Alt+F8) запускает нашу программу и все числа в выделенной области автоматически переставляются в порядке возрастания – рисунок 11б. Если в выделенной области встретились нечисловые данные (текст, даты, пустые ячейки и т.п.) то программа выдает сообщение об ошибке и указывает номер ячейки, в которой эта ошибка обнаружена.

После завершения работы программы область выделения автоматически снимается.

Этап 3 (Прочие особенности программы)

Программа простенькая. У нее не будет пользовательского интерфейса в виде экранных форм. Все события будут происходить на стандартном листе электронной таблицы EXCEL и заключаться они будут в том, что после запуска нашей программы она должна определить координаты начала выделенной области, количество строк и столбцов в ней, затем в цикле пройти по ячейкам этой области, считать их в память в свой внутренний массив, переставить по возрастанию, вывести уже упорядоченные данные обратно в таблицу EXCEL и снять выделение с таблицы. Можно было, конечно, не считывать данные во внутренний массив, а переставлять их прямо на листе EXCEL, однако это заняло бы больше времени, так как операции ввода/вывода из ячеек довольно медленные, а при перестановке данных придется довольно много раз тасовать одни и те же цифры.

Кодирование задачи

Теперь можно запустить EXCEL, и нажать клавиши Alt+F11. Запустится инструментальная среда разработки пользовательских приложений на VBA (рисунок 3). На ней могут присутствовать не все окна, показанные на рисунке 3 и даже может отсутствовать окно, где составляется текст программы, поэтому включите меню ВСТАВКА-МОДУЛЬ и получите пустое чистое окно для работы.

Любая программа на VBA состоит из отдельных процедур. Задача, которую надо Вам запрограммировать – вообще будет состоять из одной процедуры. Вам надо придумать для нее имя. Пусть Ваша процедура будет называться Poradok (это английскими буквами напечатано нечто близкое по произношению с русским словом Порядок. Придумывайте всегда такие названия, чтобы по ним не только Вы сами, но и другие могли уловить смысл и назначение данной процедуры). Тогда в окне модуля Вы должны напечатать:

Sub Poradok ( )

и нажать клавишу <Enter>.

После нажатия указанной клавиши интерпретатор языка VBA проанализирует введенную Вами строку на наличие ошибок. Обнаружив ключевое слово Sub интерпретатор «поймет», что Вы написали заголовок процедуры и автоматически подставит к нему строку, завершающую любую процедуру. На экране появится:

Sub Poradok()

End Sub

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

Текст большинства программных модулей начинается с описания переменных, которые используются в программе. Ваш модуль – не исключение. Как указывалось выше, Вам понадобится массив для хранения данных, взятых из выделенной области книги EXCEL. Заранее Вы не знаете какого размера будет эта область. Не знаете Вы и какие данные будут там (целые или действительные числа). Поэтому следует описать в программе массив неопределенного размера с неопределенными данными. На языке VBA описание такого массива выглядит так:

Dim Mass( ) As Variant

жирным шрифтом здесь выделены ключевые слова языка VBA, тонким – имена, придуманные программистом (то есть Вами). Вы решили назвать массив словом Mass, а в скобках, стоящих следом, ничего не написали, оставили их пустыми – это означает, что массив может изменять свою длину по желанию программиста, но в данный момент его длина не назначается (фактически сейчас он имеет нулевую длину). Ключевое слово Dim означает начало описания некоторой переменной, используемой в программе. Ключевое слово As означает, что переменной будет назначен конкретный тип данных, которые она должна хранить и этот тип описывается следующим ключевым словом, в данном случае – Variant, что означает «любой тип».

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

Dim i As Integer

Dim j As Integer

ключевое слово Integer означает, что переменные i и j хранят только целые числа.

Обратите внимание, что при наборе этих строк как только Вы ввели ключевое слово As и нажали пробел интерпретатор языка выводит окно подсказки (рисунок 12) с различными вариантами ключевых слов, разрешенных после слова As. Вам остается только выбрать нужное, нажав несколько первых букв от слова Integer. Кроме того, обратите внимание, что ключевые слова, которые интерпретатор языка понял закрашиваются синим цветом. Все остальные (“не родные” для языка VBA) слова – черные.

И еще, в качестве данных Вам понадобится ячейка, через которую Вы будете переставлять все числа при их упорядочении. Раз все числа будут храниться в массива типа Variant, значит и эта ячейка тоже должна быть типа Variant. Назовите эту ячейку, например, obmen и внесите в текст программы ее описание:

Dim obmen As Variant

Кроме того, нам потребуются ячейки для хранения координат начала выделенной области (назовем их X иY) и ячейки для хранения размеров области по высоте и ширине (назовем их H и W). Все ячейки типа Integer . Опишите их в программе:

Dim X As Integer

Dim Y As Integer

Dim H As Integer

Dim W As Integer

Теперь начинаем писать основной текст программы.

Первым делом надо написать участок кода, который находит на листе выделенный блок ячеек и определяет его параметры (начало, количество строк и столбцов). Но как же его написать, если Вы пока не знаете как в VBA обозначаются указанные объекты? Как обозначается выделенная область?

Посмотрите сначала нет ли нужной Вам информации в справочной системе EXCEL. Если нет, то рекомендую предварительно произвести автозапись создания интересующего Вас объекта на листе EXCEL или действий с ним и потом проанализировать полученный макрос…

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

Row – строка начала объекта;

Column – колонка (столбец) начала;

Rows.Count – количество строк в объекте (выделенной области);

Columns.Count – количество столбцов в объекте (выделенной области).

Конечно, поиск нужных свойств объектов VBA с помощью автозаписи макросов это не от хорошей жизни программиста. Лучше иметь полную документацию по объектам VBA под рукой. Но заграничные разработчики используемых нами пакетов не очень торопятся предоставить России нужную документацию. И их можно понять: мало кто в России использует лицензионное программное обеспечение. Поэтому российскому программисту приходится быть исключительно изобретательным и сообразительным при освоении современных программных продуктов.

Так, или иначе, найдя нужный объект и его свойства, Вы можете оформить строки программы следующим образом.

X = Selection.Row‘поместить в ячейку X номер начальной стро-

‘ки выде ленной области

Y = Selection.Column‘в ячейку Y - номер начального столбца выде-

‘ленной области

H = Selection.Rows.Count‘в ячейку H–число строк выделенной области

W = Selection.Columns.Count ‘в ячейку W – число столбцов выделенной

‘области

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

Redim Mass(H,W)

Здесь указано, что нужно создать в памяти машины двумерный массив с количеством строк H (по числу строк в выделенной области) и столбцов W (по числу столбцов в выделенной области), который Вам нужен для хранения данных.

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

For i = 1 to H

For j = 1 to W

Mass(i, j) = Cells(X+i-1, Y+j-1).Value

Next j

Next i

Как видите – организовано два вложенных цикла. Один – управляет движением по строкам (индекс i), другой – движением по столбцам (индекс j). Массив Mass заполняется, используя эти же индексы, а данные берутся из объектов Cells – так называются в VBA ячейки электронной таблицы. У объекта Cells в скобках указывается два индекса: номер строки ячейки и, через запятую, номер столбца ячейки. У нас в программе эти индексы рассчитываются через координаты выделенной области X и Y и текущие индексы i и j цикла. Понять эти формулы просто, если задуматься: какие же координаты имеют ячейки выделенной области на листе и как они должны меняться при переносе из них данных в массив Mass.

Тут есть один «подводный» камень. В исходном состоянии интерпретатор VBA отсчитывает индексы массивов, начиная с номера 0. Нам же надо, чтобы первый индекс массива начинался с номера 1. Чтобы интерпретатор VBA работал так, как нам надо, в самом начале текста программы следует установить команду:

Option Base 1

Следующий участок кода программы – перестановка чисел в массиве в порядке возрастания. Применяем стандартный алгоритм перестановки чисел. В виде строк программы он выглядит так:

For i = 1 To H ‘начинаем циклы, показывающие ячейку,

For j = 1 To W ‘с которой сравниваются все остальные (базовая

‘ ячейка)

K = i: L = j ‘индексы сравниваемой ячейки начинаются с базовой

For K = i To H ‘начнем циклы, показывающие ячейку,

For M = L To W 'которую сравнивают с базовой (целевая)

IF Mass(i, j) > Mass(K, M) THEN 'если число в базовой ячейке

obmen = Mass(i, j) 'больше числа в целевой,

Mass(i, j) = Mass(K, M) 'то эти числа

Mass(K, M) = obmen 'поменять местами

END IF

NEXT M

L = 1 ‘теперь индекс цикла по столбцам должен начатьсяс 1

NEXT K

NEXT j

NEXT i

Как видим нам дополнительно понадобилось еще три ячейки для реализации алгоритма перестановки – K, L, M (целые числа), поэтому добавим их описание в начале программы:

Dim K As Integer

Dim L As Integer

Dim M As Integer

В приведенном выше участке кода четыре вложенных цикла. Первые два цикла (индексы i, j) проходят по всему массиву один раз и выбирают ячейку, которая является объектом сравнения (базовая ячейка). Два внутренних цикла (индексы K и M) каждый раз перебирают все ячейки (целевые ячейки), начиная от текущего объекта сравнения и до конца массива Mass, сравнивая эти ячейки с объектом сравнения. Если оказывается, что в целевой ячейке число меньше, чем в базовой, то числа в этих ячейках меняют местами. И процесс перебора продолжается дальше.

Завершает нашу программу участок кода, который переносит упорядоченные данные из памяти машины (из массива Mass) обратно на лист книги EXCEL. Он выглядит так:

For i = 1 To H

For j = 1 To W

Cells(X + i - 1, Y + j - 1) = Mass(i, j)

Next j

Next i

Комментарии здесь, как говорится, излишни.

В результате всей этой нашей деятельности, предположим, что в окне модуля теперь имеется следующий текст:

Option Base 1

Sub Poradok()

Dim Mass() As Variant

Dim obmen As Variant

Dim i As Integer

Dim j As Integer

Dim X As Integer

Dim Y As Integer

Dim H As Integer

Dim W As Integer

Dim K As Integer

Dim L As Integer

Dim M As Integer

'Получить характеристики выделенной области

X = Selection.Row

Y = Selection.Column

H = Selection.Rows.Count

W = Selection.Columns.Count

'Заказать в памяти массив

ReDim Mass(H, W)

'Получить из выделенной зоны данные

For i = 1 To H

For j = 1 To W

Mass(i, j) = Cells(X + i , Y + j - 1)

Next j

Next i

'Переставить данные в порядке возрастания

For i = 1 To H

For j = 1 To W

K = i: L = j

For K = i To H

For M = L To W

If Mass(i, j) > Mass(K, M) Then

obmen = Mass(i, j)

Mass(i, j) = Mass(K, M)

Mass(K, M) = obmen

End If

Next M

Next K

Next j

Next i

'Вывести новый порядок данных на лист EXCEL

For i = 1 To H

For j = 1 To W

Cells(X + i - 1, Y + j - 1) = Mass(i, j)

Next j

Next i

End Sub

Обратите внимание, что для большей наглядности и удобочитаемости текста:

  1. все циклы напечатаны как бы «лесенкой» - заголовок FOR … каждого нового цикла чуть сдвинут относительно другого, а концы циклов NEXT стоят на одном уровне со своим заголовком. То же самое видно и по отношению к операторам IF … ELSE … END IF, SUB … END SUB и т.д. Теперь каждая такая пара образует хорошо видимый участок, называемый «блоком». Легко контролировать, что мы не забыли никаких концов от начал этих блоков и легко проверять где начинается и где кончается очередной блок;

  2. каждый новый участок кода, выполняющий отдельную законченную функцию, сопровождается комментариями (в VBA комментарии начинаются с одинарной верхней кавычки). Комментарии позволяют другим программистам легко разобраться в Вашей программе. Да и Вам самим они очень пригодятся. Могу спорить, что если Вы будете просматривать свою собственную программу, которую Вы делали месяц назад, и в ней не будет комментариев, то с удивлением обнаружите, что совершенно не помните, как же Вы ее программировали и какую цель имеют эти нагроможденные строчки кода.