VBA for EXCEL СОДЕРЖАНИЕ Введение в Visual Basic For Applications ...................................................................... 2 Создание макроса для Microsoft Excel/Visual Basic for Windows 95 ..................... 2 Объекты, свойства и методы VBA ............................................................................. 4 Типы данных .................................................................................................................... 8 Встроенные типы данных ........................................................................................... 8 Переменные и их объявление ................................................................................... 11 Объявление численных и строковых переменных ............................................. 11 Объявление переменных массива......................................................................... 12 Объявление и присваивание объектных переменных ........................................ 13 Арифметические и логические операции Visual Basic ...................................... 14 Использование встроенных функций Visual Basic ............................................. 14 Строковые функции................................................................................................... 15 Операторы ...................................................................................................................... 17 Оператор присваивания ............................................................................................ 17 Операторы условного перехода If - Then и If-Then-Else ....................................... 18 Оператор выбора Select Case .................................................................................... 21 Циклы .......................................................................................................................... 23 диалоговые окона .......................................................................................................... 33 Встроенные диалоговые окона ................................................................................. 33 Диалоговые окна приложения .............................................................................. 40 Диалоговые окна пользователя ................................................................................ 42 Элементы управления диалоговых окон .................................................................... 54 Работа с файлами........................................................................................................... 60 Файлы последовательного и произвольного доступа ............................................ 60 Чтение и запись последовательных файлов ........................................................ 61 Чтение и запись файлов произвольного доступа ................................................... 70 Реорганизация данных в файле произвольного доступа ................................... 75 Создание пользовательских объектов......................................................................... 78 Определение пользовательского объекта ............................................................... 78 Создание пользовательских свойств ....................................................................... 79 Коммуникации ............................................................................................................... 85 Технология DDE Что такое DDE ? .......................................................................... 85 Применение DDE. ...................................................................................................... 86 Открытие коммуникационного канала DDE. ......................................................... 88 Закрытие канала DDE. ............................................................................................... 88 Технология OLE ......................................................................................................... 93 1 VBA for EXCEL ВВЕДЕНИЕ В VISUAL BASIC FOR APPLICATIONS Если вы хорошо знакомы с программным продуктом Excel, то можно быть уверенным в том, что составление любого документа в Excel теперь не вызовет проблем. Ни одна задача не сможет поставить вас в тупик. Однако, если вы стремитесь к совершенству, то Visual Basic For Applications (VBA) – это то, что вам нужно. Visual Basic For Applications – это сочетание одного из самых простых языков программирования и всех вычислительных возможностей Excel. С помощью VBA вы сможете легко и быстро создавать разнообразные приложения, даже не являясь специалистом в области программирования. VBA содержит графическую среду, позволяющую наглядно конструировать экранные формы и управляющие элементы. VBA позволяет с легкостью решать многие задачи, о возможности выполнения которых средствами Excel вы раньше даже не подозревали. Создание макроса для Microsoft Excel/Visual Basic for Windows 95 Чтобы автоматизировать повторяющиеся действия, можно создать макрос. 1. В меню Сервис выберите пункт Запись макроса, затем команду Начать запись. 2. Чтобы присвоить название макросу, отличное от предлагаемого в Microsoft Excel по умолчанию, наберите требуемую последовательность символов в поле “Имя макроса”. 3. Чтобы создать краткое описание макроса, введите нужный текст в поле “Описание”. 2 VBA for EXCEL 4. Чтобы задать дополнительные характеристики макроса, нажмите кнопку “Параметры”, затем установите необходимые значения предлагаемых элементов управления. 5. Нажмите кнопку “OK”. 6. Выполните записываемые действия. 7. Прекратите запись макроса^ Сервис- макрос- Закончить запись Вывод исходного текста записанного макроса. Исходный текст макроса на языке программирования Visual Basic находится в отдельном модуле книги. 1. В меню Сервис выберите команду Макрос. 2. Введите в поле “Имя макроса/ссылка” название макроса. 3. Нажмите кнопку “Изменить”. Процедуры (макросы) имеют стандартное оформление: Sub имя_процедуры (список_параметров) Тело_процедуры End Sub Например, процедура Сигнал использует оператор Beep для синтеза звукового сигнала: Sub Сигнал Beep End Sub Использование относительных ссылок при записи макроса. По умолчанию, при записи макроса используются абсолютные ссылки, например, $A$1. Макрос, записанный с абсолютными ссылками, при запуске всегда обрабатывает те же ячейки, которые обрабатывались при его записи. Для того, чтобы с помощью макроса обрабатывать произвольные ячейки, следует записать его с относительными ссылками. Макрос, записанный с относительными ссылками, при запуске использует адреса, вычисленные относительно левой 3 VBA for EXCEL верхней ячейки текущей области. В меню Сервис выберите пункт Запись макроса, затем команду Относительные ссылки. Относительные ссылки будут использоваться до конца текущего сеанса работы в Microsoft Excel или до повторного выбора команды Относительные ссылки. Советы. 1. Перед началом записи макроса откройте необходимую книгу, выберите нужный лист и выделите требуемые ячейки или объекты. 2. Чтобы получить доступ к кнопке “Начать запись макроса”, выведите на экран панель инструментов “Visual Basic”. 3. Чтобы назначить клавиши для запуска макроса, нажмите кнопку “Параметры” в окне диалога Запись макроса. Назначенная комбинация может состоять из клавиши CTRL или клавиш CTRL+SHIFT и клавиши любого символа. Помните, что сделанные назначения клавиш перекрывают стандартные назначения в Microsoft Excel пока открыта книга, в которой записаны данные макросы. Модуль Visual Basic можно переименовать. Установите указатель на ярлычок модуля и дважды нажмите кнопку мыши. Объекты, свойства и методы VBA Одним из основных объектов VBA является объект. Объект – это то, чем вы управляете с помощью программы на языке VBA, например, диалог, рабочий лист, диапазон ячеек . Каждый объект обладает некоторыми характеристиками или свойствами. Например, диалог может быть видимым и не видимым в данный момент на экране. Можно узнать текущее состояние диалога с помощью свойства Visible. Другим примером свойства объекта может быть шрифт, используемый для отображения информации в ячейке (объекте) рабочего листа. Изменяя свойства, вы можете менять характеристики объекта. Объект содержит также список методов которые к нему применимы. Методы – это то, что вы можете делать с объектами. Например, показать диалог на экране или убрать его можно с помощью методов Show и Hide, соответственно. 4 VBA for EXCEL Таким образом, объект это программный элемент, который имеет своё отображение на кране, содержит некоторые переменные, определяющие его свойства, и некоторые методы для управления объектом. Объект является “кирпичиком” построения программы VBA. В VBA имеется много встроенных объектов, например: Range – диапазон ячеек (может включать только одну ячейку) Cells – ячейка Sheet – лист WorkSheet – рабочий лист DialogSheet – диалоговое окно. Большинство объектов принадлежит к группе подобных объектов. Эти группы называются наборами. Например, все рабочие листы рабочей книги образуют набор, называемый WorkSheets. Набор используется одним из двух способов: либо какое-либо действие совершается над всеми объектами набора, например, удалить, либо со ссылкой на набор выбирается конкретный объект для работы с ним. Второй способ реализован в следующей конструкции: WorkSheets (“Первый”), выбирающей рабочий лист Первый из рабочей книги. Другими примерами наборов являются: Sheets - лист DialogSheet - диалоговые окна DrawingObjects - графические объекты. Изменяя свойства, можно изменять характеристики объекта или набора объектов. Установка значений свойств – это один из способов управления объектами. Для установки свойств необходимо ввести имя объекта, затем поставить точку и за ней – имя свойства. Далее должен следовать знак равенства и значение свойства. Синтаксис установки значения свойства объекта выглядит следующим образом: Объект. Свойство = Выражение 5 VBA for EXCEL В приведённом ниже примере для свойства Value диапазона ячеек Начальные_данные устанавливается значение 0,1 (т.е. в ячейках этого диапазона будет записано число 0.1): Range (“Начальные_данные”). Value = 0.1 В следующем примере в ячейку А2 вставляется формула путём изменения свойства Formula (формула): Range (“А2”). Formula ”= СУММА (А1 : С1)” Некоторые свойства являются неизменяемыми, т.е. допустимыми только для чтения. Имеется в виду, что значение свойства можно узнать, но нельзя изменить. Например, для диапазона, состоящего из одной ячейки, свойства Row (строка) и Column (столбец) являются неизменяемыми. Другими словами, можно узнать, в какой строке и в каком столбце находится ячейка, но изменить её положение путём изменения этих свойств нельзя. Синтаксис чтения свойств объекта выглядит следующим образом: Переменная = Объект. Свойство В следующем примере переменной Процентная_ставка присваивается значение из ячейки А1 текущего рабочео листа: Процентная_ставка = Range (“А1”).Value или другим способом: Процентная_ставка = cells (1,1).Value Кроме свойств, как уже отмечалось выше, у объектов есть ряд методов, т.е. команд, применяемых к объекту. Например, у объекта – диапазон ячеек – имеется метод Clear, позволяющий очистить содержимое диапазона. Приводимый ниже пример показывает, как можно очистить диапазон Начальные_данные: Range (“Начальные_данные”). Clear А в примере Range (“А10 : В12”).Select, выбирается диапазон ячеек А10 : В12. Таким образом, синтаксис вызова объекта имеет следующий вид: 6 VBA for EXCEL Объект. Метод В Excel имеется много объектов, причем некоторые из них содержат другие объекты. Например, рабочая книга содержит рабочие листы, рабочий лист содержи диапазон ячеек и т. д. Объектом самого высокого уровня является Application (приложение). Если вы изменяете его свойства или вызываете его методы, то результат применяется к текущей работе Excel. Например, можно завершить работу в Excel, применив метод Quit (выход) к объекту Application: Application. Quit Как было отмечено, точка после объекта указывает на то, что далее следует имя свойства или метода. Но после точки можно указать и имя объекта для перехода от одного объекта к другому. Например, следующее выражение очищает вторую строку рабочего листа Май в рабочей книге Отчет: Application. Workbooks (“Отчет”). Worksheets (“Май”). Rows (2). Delete Определение имени приложения: Application. Name Если вспомнить, что строка содержит отдельные ячейки, свойства которых тоже можно устанавливать, то выражение становится ещё длиннее: Application. Workbooks (“Отчет”). Sheets (“Май”). Rows (2). Cells (1). Value = “Да” Таким образом ссылки на объекты могут быть слишком громоздкими. Если данный объект часто используется в программе, то разумно создать объектную переменную с помощью команды Set. Например, предыдущий пример можно записать в следующем виде: Dim R As Object Set R = Application. Workbooks (“Отчет”). Sheets (“Май”). Rows (2). Cells (1) R.Value = “Да” Приводимые выше примеры можно записать гораздо короче: Можно не писать имя объекта Application, т. к. это подразумевается по умолчанию; 7 VBA for EXCEL При работе с подобъектом уже активизированного объекта нет необходимости указывать содержащий его объект; VBA использует некоторые свойства и методы, которые возвращают объект, к которому они относятся. Использование последнего обстоятельства позволяет быстро указывать нужный объект. Так, в следующем примере устанавливается значение активной ячейки ActiveCells. Value = “Да” ActiveCells (активная ячейка), ActiveSheet (Активный лист), ActiveWorkBook (активная рабочая книга) и Selection (выбор – указывает на выбранный объект) являются примерами свойств, возвращающих объект. ТИПЫ ДАННЫХ Переменные и типы данных определяют, где и как данные хранятся в памяти компьютера. В языке со строгим контролем типов вы обязаны указывать тип каждой переменной перед ее использованием. Хотя Visual Basic не является языком со строгим контролем типов, он предоставляет возможность управлять использование памяти вашего компьютера более эффективно, задавая в явном виде типы всех ваших переменных. Определяя тип данных для величины, тем самым определяется соотношение между разрядностью, размером и используемой памятью. Встроенные типы данных В Visual Basic имеется одиннадцать встроенных типов данных, представленных в табл. 1. Таблица 1. Встроенные типы данных Visual Basic 8 VBA for EXCEL Тип данных Размер Разрядность Диапазон (байтов) (цифр) Boolean 2 1 True или False Integer 2 5 от -32768 до 32767 Long 4 10 от -2147483648 до 2147483647 Single 4 7 от -3,402823Е+38 до 1,401298Е-45 и от 1,401298Е-45 до 3,402823Е+38 Double 8 от -1,79769313486232Е+308 15 до -4,94065645841247Е-324 и от 4,94065645841247Е-324 до 1,79769313486232Е+308 Currency 8 от -922337203685477,5808 19 до 922337203685477,5807 Date 8 String 1+1 от 01.01.100 до 31.12.9999 от 0 до 65535 символов на символ Object Любой определенный объект 4 Определяется количеством и Array размером элементов Variant Определяется записанными Любой встроенный тип данных данными Тип данных Boolean использует два байта (16 бит) памяти. Этот тип данных имеет только два возможных значения: True (истина) или False (ложь), которые могли бы быть представленными одним битом, но в действительности тип Boolean хранится как Integer ("0"- False, "-1" - True). 9 VBA for EXCEL Тип данных Integer использует два байта памяти для хранения смещенного целого числа. Целое число без знака может принимать только положительное значение, а смещенное целое число может принимать как положительное, так и отрицательное значение. Тип данных Long - это целое число двойной длины, которое использует четыре байта, имеет двойное разрешение по сравнению с данными типа Integer и использует в два раза больше памяти. Тип данных Single представляет собой действительное число с плавающей точкой. Использовать этот тип данных нужно осторожно, особенно при вычислении денежных величин, так как он имеет только семь цифр разрешения. Если вы использовали два из этих разрядов для центов, оставляя таким образом только пять для долларов, то максимальное значение будет $34,028.23. При попытке записать число больше, чем это, произойдет ошибка переполнения. Тип данных Double - это Single двойного размера, с двойной разрешающей способностью, требующий вдвое больше памяти, и в восемь раз большим диапазоном чисел. Тип данных Currency - это специальное восьмибайтное число, в котором десятичная точка всегда располагается между четвертой и пятой цифрами справа. Этот тип специально создан для минимальных ошибок округления. При использовании типов данных с плавающей точкой ошибка округления может привести к получению величины, равной 4,999 999 999 вместо 5,0. Иногда эта разница бывает существенна. Тип Date предназначен для хранения дат и времени в восьми байтах памяти. Даты записываются в виде целых чисел дней от 01.01.1900, а время - как дробная часть дня. Таким образом, значение 34398.75 в формате Date означает 5 марта 1994 года и время 18:00. Используя этот тип данных имейте в виду, что хотя диапазон Visual Basic расширен от 01.01.100 до 31.12.9999, диапазон Excel всего лишь от 01.01.1900 до 31.12.2078. 10 VBA for EXCEL Тип данных String используется для хранения строк текста по одному байту памяти на каждый символ плюс один, чтобы отметить конец строки. Тип данных Object использует четыре байта памяти для хранения ссылки на любой объект Visual Basic. Тип данных Array в действительности не является отдельным типом данных. Он скорее определяет индексный список величин одного из других типов данных, т.е. массив. Тип данных Variant используется в Visual Basic как тип данных по умолчанию, т.е. если тип данных для хранения величины не указан, то используется тип данных Variant. Variant имеет возможность хранить практически любую величину и бывает полезен для коротких, простых программ. Переменные и их объявление Переменные - это поименованные области в памяти компьютера. После вычисления какого-либо значения его нужно записать в память, чтобы затем можно было к нему обращаться. Использование переменных дает Visual Basic возможность создавать прямое соответствие между областью памяти и заданным именем. Объявление численных и строковых переменных Объявляя переменную определенного типа, указывается, какой тип данных должен быть использован при записи значения переменной в память. Для объявления переменных служит оператор Dim, который включается в верхнюю часть процедуры, использующей эти переменные. Синтаксис оператора Dim: Dim <имя переменной> As <тип данных>, <имя переменной> As <тип данных>, ... , Примеры объявления переменных: Dim ProductNumber As Long, Product_Name As String Dim I As Long, aPicture Последний оператор объявляет переменную aPicture типа Variant. 11 VBA for EXCEL Пример описания переменных: Sub Макрос1() Dim ProductNumber As Long ProductNumber = Sheets("Лист1").Range("C5").Value ProductNumber = ProductNumber + 1 Sheets("Лист1").Range("A5").Value = ProductNumber End Sub Объявление переменных массива При объявлении переменной задается единичная поименованная область памяти, а при объявлении массива - список смежных областей памяти под одним именем. Для осуществления доступа к отдельному элементу массива, имя массива снабжают номером элемента массива (индексом), заключенным в круглые скобки. Примеры объявления массивов: Dim Sales (4 to 8) As Currency Оператор создает массив с именем Sales, содержащий данные типа Currency. Этот оператор задает как нижний, так и верхний предел индекса (по умолчанию индекс начинается с "0"). Таким образом, массив содержит пять элементов: Sales (4), Sales (5), Sales (6), Sales (7), Sales (8). Dim theCoords (3, 1 to 4) As Single Здесь создается двумерный массив чисел с плавающей точкой названный theCoords. Поскольку это объявление содержит два индексных диапазона, массив является двумерным. Диапазон первого индекса от 0 до 3, второго - от 1 до 4. Задание элементов двумерного массива требует указания двух индексов: theCoords (0,1) theCoords (0,2) theCoords (0,3) theCoords (0,4) theCoords (1,1) theCoords (1.2) theCoords (1.3) theCoords (1.4) theCoords (2.1) theCoords (2.2) theCoords (2.3) theCoords (2.4) 12 VBA for EXCEL Можно задавать массивы и большей размерности, хотя трудно вообразить, что будет представлять собой массив с размерностью больше 3. Чтобы сделать переменную доступной всем процедурам во всех модулях, она объявляется на уровне модуля, использовав вместо Dim ключевое слово Public. Объявление и присваивание объектных переменных Объектные переменные объявляются также, как и любые другие. Чтобы присвоить значение объектной переменной используется следующая конструкция: ключевое слово Set , имя переменной, знак равенства и формула, определяющая значение объекта. Например, приведенная ниже процедура создает объектную переменную, присваивает ей объект Rang, ссылающийся на ячейку В5, и затем использует эту объектную переменную для присваивания значения ячейке: Sub ObjVar () Dim Х As Object Set Х = ActivSheet.Range (“B5”) ( Или Set Х = Range (“B1:B10)”) } X.Value = 10 End Sub 13 VBA for EXCEL Арифметические и логические операции Visual Basic Основные математические действия производятся с помощью операций. В таблице представлены все математические и строковые операции в порядке убывания приоритета. Для обеспечения корректности вычисления операций в сложных формулах используют круглые скобки. Операци Название я ^ Возведение в степень - Отрицание * Умножение / Деление Равный приоритет \ Деление нацело Mod Вычисление остатка от деления + Сложение Равный - Вычитание приоритет & Конкатенация (строк) Р = principal*rate/(1 - (1/ (1+rate)^n)) Использование встроенных функций Visual Basic Рассмотренные выше операции дают возможность осуществлять основные математические действия, более сложные вычисления производятся с помощью встроенных функций. Visual Basic оперирует этими функциями подобно Excel, с тем отличием , что они всегда возвращают единичное значение. Функции Excel могут применяться к целым массивам чисел и возвращать массивы в качестве 14 VBA for EXCEL результатов. Чтобы обработать массив значений с помощью функции Visual Basic, нужно применить эту функцию к каждому элементу массива в отдельности. Математические функции Функция Описание Atn Возвращает арктангенс числа Sin Возвращает синус угла в радианах Cos Возвращает косинус угла в радианах Tan Возвращает тангенс угла в радианах Exp Возвращает Log Возвращает натуральный логарифм числа е^х (основание е=2.71828…) Sqr Возвращает квадратный корень числа Randomize Инициирует генератор случайных чисел Rnd Возвращает случайное число Abs Возвращает абсолютную величину числа Sgn Возвращает знак числа Fix Округляет число отсечением дробной части Int Округляет число до ближайшего меньшего целого Математические функции, приведенные в таблице, обычно требуют в качестве аргумента единичное значение, некоторым образом его трансформируют и возвращают также одно число. Тригонометрические функции Sin ( ), Cos ( ), Tan ( ) применяются к углам в радианах и преобразовывают их в соответствующую тригонометрическую величину. Строковые функции Функция StrComp Описание Сравнивает две строки 15 VBA for EXCEL LCase Преобразовывает строку в нижний регистр UCase Преобразовывает строку в верхний регистр Space Создает строку пробелов String Создает строку символов Len Определяет длину строки Instr Ищет подстроку Lset Выравнивает строку по левому краю Rset Выравнивает строку по правому краю Str Преобразовывает число в строку Val Преобразовывает строку в число Пример: В= «ЯнвФевМарАпрМайИюнИюлАвгСенОктНояДек» Lсase, после преобразований: B = «янвфевмарапрмайиюниюлавгсеноктноядек» Uсase, после преобразований: B = «ЯНВФЕВМАРАПРМАЙИЮНИЮЛАВГСЕНОКТНОЯДЕК» Len (B), после вычислений B = 36 Instr (B,"Июл"), после выполнения функции: B = 19 16 VBA for EXCEL ОПЕРАТОРЫ Оператор присваивания Оператор присваивания - это основа всех вычислений в VBA, так как любая рассчитанная величина должна стать переменной, чтобы ее можно было хранить. Знак «=» является оператором присваивания, который предписывает выполнить выражение, заданное в его правой части, и присвоить результат переменной, идентификатор которой расположен в левой части. В правой части располагается выражение в виде формулы, в качестве которой может выступать отдельная величина или выражение, состоящее из переменных, констант, операций и функций. Переменная, располагающаяся слева, может быть простой переменной, элементом массива или свойством объекта. Примеры операторов присваивания: Filename = " c:\vba\exampl.xls" Sales = Units * Prise Profit = Sales - Cost Coords (3,2) = 19.37 Selection.Values = 25 Rang("B1") . Formula = "=B4*B3-1" ActiveCell.FormulaR1C1 = "Таблица погашения ссуды" ActiveWindow . ScrollRow = 1 Первые три оператора присваивают значениям переменным, четвертый присваивает значение элементу массива, а все остальные присваивают значения свойствам. Таким способом нельзя присвоить значения только объектам - они требуют специального оператора присваивания. Например, приведенная ниже процедура создает объектную переменную, присваивает ей объект Rang, ссылающийся на 17 VBA for EXCEL ячейку В5, и затем использует эту объектную переменную для присваивания значений ячейке: Sub ObjVar () dim theRang as Object Set theRang = ActiveSheet.Range(‘B5’) theRang.Value = 10 EndSub Исключением является оператор присваивания « : = ». В отличие от ранее описанного оператора присваивания «=», он применяется только по отношению к параметрам процедуры. Sub Assistant (a, b) c=a+b Msgbox Cstr (c) End Sub Sub Main( ) Assistant a:= 1, b:= 3 End Sub В данном примере при вызове процедуры Assistant передача параметров осуществляется присвоением значений именам параметров с помощью оператора присваивания «:=». При выполнении данной процедуры переменной С присваивается значение суммы переданных параметров с использованием оператора присваивания «=». Операторы условного перехода If - Then и If-Then-Else Условный оператор If-Then-else обеспечивает передачу управления в программе в зависимости от выполнения условия. Синтаксис: If <условие> Then <блок_операторов_1> 18 VBA for EXCEL Else <блок_операторов_2> End If В условном операторе допустимо использование как блока операторов, так и любого из операторов. В операторе условия Опреатор_1 или Блок_операторов_1 выполняется если <условие> истинно, в противном случае выполняется Оператор_2 или Блок_операторов_2. Условие - это выражение логического типа. Результат выражения всегда имеет булевский тип. Выражение может быть простым и сложным. При записи простых условий могут использоваться все возможные операции отношения, указанные в таблице 1. Таблица 1. Логическое отношение. Операци Название я Выражени Результат е = равно А=В True, если А равно В <> не равно A<>B True, если А не равно В > больше A>B True, если А больше В < меньше A<B True, если А меньше В >= больше или A>=B True, если А больше или равно В A<=B True, если А меньше или равно В равно меньше или <= равно Сложные условия образуются из простых путем применения логических операций и круглых скобок. Список логических операций приведен в таблице 2. Ветвь Else в условном операторе является необязательной. Таким образом, возможен следующий синтаксис оператора условия: If <условие> Then <оператор или блок_операторов> End If Заметим, что в операторе условия после Then можно разместить блок операторов, для того, чтобы все они выполнялись, если условие истинно. В этом 19 VBA for EXCEL случае они должны располагаться в одну строчку и быть разделены двоеточием. Например, If A>10 Then A=A+1 : B =B+A : C=C+B End If Рассмотрим пример функции пользователя с использованием оператора условного перехода If-Then-Else. Function G(y) If y<=0 Then G = (1+y^2)/(1+y^4)^(1/2)_ Else G = 2*y +sin (y)^2/(2+y) End If End Function вычисляющей следующую функцию с двумя условиями: 1 y2 , y 0, 1 y4 g 2 2 y sin ( y ) , y 0. 2 y Заметим, что знак подчеркивания «_» в конце строки обозначает, что следующая строка является продолжением предыдущей. Пусть в ячейку А1 записано число 0,2 и вам нужно вычислить в ячейке В1 значение функции G при У=0,2. Для этого достаточно в ячейку В1 ввести формулу = G(А1). Тот же результат можно получить, если ввести в ячейку В1 следующую формулу = если (А<=0*; (1+А1^2)/(1+A1^4)^(1/2); 2*A1+sin(A1)^2/(2+a1)) В условном операторе может проверяться несколько условий. В этом случае условный оператор имеет вид: If <условие_1> Then <Блок_операторов_1> Else If <условие_2> Then <блок_операторов_2> Else If <условие_3> Then ... else <блок_операторов> 20 VBA for EXCEL End If В данном условном операторе выполняется блок_операторов_i, если истинно условие_i, в противном случае выполняется блок_операторов. Оператор выбора Select Case Оператор выбора Select Case удобно использовать, когда одна величина участвует во многих сравнениях для выбора одного из блоков кода. Наиболее часто используется, когда сравниваемая величина является целым числом селектором или индексом. Значение селектора или индекса выбирает тот блок кода, который будет выполняться. Синтаксис: Select Case <тестируемое _выражение> Case <условие_выбора_1> <блок_операторов_1> ... ... ... Case <условие_выбора_n> <блок_операторов_n> Case Else <блок_операторов_n> End Select После каждого оператора Case может находиться произвольное количество других операторов, и все они будут выполняться, если условие оператора Case истинно. При использовании одного оператора его можно поместить а одну строку с операторами Case. Так же как и в блочной структуре IF, можно использовать специальный оператор Case, определяющий любые величины, которые не совпадают ни с одним из других операторов Case. Для этого условие Case Else включается 21 VBA for EXCEL последним блоком перед оператором End Select. Все величины, не совпавшие ни с одним оператором Case, совпадут с оператором Case Else. Is является ключевым словом VBA, обозначающим тестируемое выражение в операторе Case. В операторе Case допустимы составные условия, например Case 4,7 to 8, Is >=16 Проверяет, принадлежит ли тестируемое выражение отрезку от 7 до 8 или равняется значению 4, или оно не меньше, чем 16. Пример перевода числового значения дня недели в строковое представление. Sub perevod() x = Sheets("Лист1").Range("e30").Value Select Case x Case 1 Sheets("Лист1").Range("e31").Value = "Понедельник" Case 2 Sheets("Лист1").Range("e31").Value = "Вторник" Case 3 Sheets("Лист1").Range("e31").Value = "Среда" Case 4 Sheets("Лист1").Range("e31").Value = "Четверг" Case 5 Sheets("Лист1").Range("e31").Value = "Пятница" Case 6 Sheets("Лист1").Range("e31").Value = "Суббота" Case 7 Sheets("Лист1").Range("e31").Value = "Воскресенье" Case Else 'is<=0, is>7 Sheets("Лист1").Range("e31").Value = "Не день недели" End Select End Sub 22 VBA for EXCEL Циклы Для сокращения размера кода, который необходимо написать для решения задачи используют повторяемые структуры известные под общим названием как циклы. Циклы бывают трёх типов: Вычисляемые Логически прерываемые Объектного типа Вычисляемый цикл предназначен для повторения одного блока кода заданное количество раз. Вычисляемые циклы применяются в тех случаях, когда заранее известно, сколько раз нужно выполнить блок кода. Например, если требуется форматировать десять последовательных ячеек таблицы, то можно применить вычисляемый цикл, позволяющий поочерёдно изменить формат каждой из ячеек. Рассмотрим два вычисляемых цикла: For .. Next и For Each .. Next. Вычисляемые циклы разделяются Visual Basic с помощью циклической структуры For-Next и For Each-Next. Цикл For… Next For переменная_цикла = начало To конец Step шаг . . блок кода . Exit For . . блок кода . Next переменная _цикла 23 VBA for EXCEL В данном случае переменная_цикла является именем переменной, которая считает количество шагов цикла. Переменные начало и конец определяют начальное и конечное значение переменная_цикла, а шаг – величину наращивания переменная_цикла после каждого выполнения цикла. Когда в программе встречается цикл For-Next, переменная_цикла получает значение начало, затем выполняется блок кода вплоть до оператора Next. Далее переменная_цикла увеличивается на величину шаг и сравнивается со значением конец. Если значение переменная_цикла больше, чем значение конец, то цикл прерывается и управление переходит к оператору, следующему за оператором Next. Если значение переменная_цикла меньше или равно значению конец, то блок кода цикла выполняется ещё раз. Так продолжается до тех пор, пока значение переменная_цикла не станет больше значения конец. Когда встречается оператор Exit For, цикл немедленно прерывается и управление переходит к оператору, следующему за оператором Next. Обычно оператор Exit For применяется для прекращения процесса поиска чего-нибудь, когда вы искали это циклически и нашли. Если зарезервированное слово Step и величина шаг опущены, то величина переменная_цикла наращивается на 1 после каждого шага цикла. Если величина конец меньше величины начало и величина шаг отрицательна, цикл считается по убывающей, а не по возрастающей. Использование счётчика цикла Счётчик цикла - это обычная переменная, доступная в любом месте цикла и используемая в блоке его кода для выбора различных величин или ячеек. Счётчиком цикла обычно является целое число, используемое в качестве индекса массива переменных или в качестве аргумента метода Cells для выбора ячейки таблицы. После завершения цикла значение счётчика больше значения конец (или меньше значения конец, если цикл считался по убывающей). Этот фактор удобно 24 VBA for EXCEL использовать, чтобы определить, завершился ли цикл нормально или был преждевременно прерван оператором Exit For. Особенность: Поскольку переменная цикла является обычной переменной, то её можно изменить в любом месте блока кода цикла. Однако изменений переменной цикла необходимо избегать: такие изменения легко могут привести к непредсказуемым результатам. Например, следующая конструкция будет выполняться всегда: Sub Beep For I = 1 To 10 I = I-1 Beep Next I End Sub В качестве примера рассмотрим процедуру, которая заполняет текущий выбор случайными числами, применяя два встроенных цикла For-Next для области ячеек в текущем выборе. Эту процедуру можно использовать и в целях подготовки некоторых ячеек для различных вычислений либо для заполнения области ячеек различными вычисляемыми значениями, полученными с помощью различных функций или формул – в зависимости от ваших потребностей. Dim numRows As Integer, numCols As Integer Dim theRow As Integer, theCol As Integer Sub StikRandom () ‘Определение размера текущего выбора. numRows = Selection.Rows.Count numCols = Selection.Columns.Count Randomize ‘Инициализация генератора случайных чисел. For theRow = 1 To numRows For theCol = 1 To numCols 25 VBA for EXCEL Selection.Cells (theRow, theCol).Value = Rnd Next theCol Next theRow End Sub Цикл For Each…Next Данный вид цикла называется объектным и предназначен для обработки элементов в выделенном наборе. Циклы объектного типа реализуются структурой For Each...Next. Процесс выполнения данного цикла аналогичен циклу For…Next. Однако, в качестве переменной цикла используется не счётчик, определяющий количество повторов, а объект из выделенного набора. В качестве набора может быть использована как область ячеек, так и массив. For Each <элемент> in <набор> <Тело цикла> Next <элемент>, где <элемент> и <набор> являются переменными типа Variant. В этом синтаксисе элемент представляет собой переменную типа Variant, что обеспечивает возможность содержать объект. Переменная набор является некоторым набором объектов. В процессе выполнения цикла объект выбирается из набора и помещается в переменную элемент, и это позволяет использовать переменную элемент в блоке кода цикла для осуществления необходимых действий с объектом. Аналогично циклу For...Next оператор Exit For прерывает цикл до его окончания. C использованием цикла For Each - Next, рассмотрим пример заполнения области случайным набором действительных чисел. Dim c Sub Oblast For Each C in Selection 26 VBA for EXCEL C.Value=RND * 10 Next C End Sub При условии заполненной некоторыми значениями области, в качестве примера рассмотрим процедуру, которая циклически обрабатывает содержимое этих ячеек, копирует эти значения в массив, определят среднее арифметическое элементов массива и отражает это значение в окне сообщения. Dim c Dim s As Long Dim Mas( ) as integer Dim nrow as integer Dim ncolumn as integer Sub Массив Nrow=Selection.Rows.Count Ncolumn=Selection.Columns.Count ReDim Mas (nrow,ncolumn) ‘заполнение массива соответствующими элементами For i=1 to nrow For j=1 to ncolumn Mas (i,j)=cells(i,j).Value Next j Next i ‘вычислим сумму элементов набора-массив S=0 For Each C in Mas S=S+C Next C 27 VBA for EXCEL MsgBox “Сумма=” & S ‘вывод результата суммы на экран в виде окна End Sub цикл Do - Loop. Цикл Do - Loop является наиболее универсальным из логически прерываемых циклов. существуют четыре конфигурации этого цикла: условие True в начале, условие True в конце, условие False в начале и условие False в конце. Ниже приведен синтаксис всех четырех конфигураций: ’ ’ Условие True в начале. ’ Do While условие ...блок кода Exit Do ’ Условие False в начале. ’ Do Until условие ...блок кода Exit Do ...блок кода Loop ...блок кода Loop ’ ’ Условие True в конце. ’ Do ...блок кода Exit Do ’ Условие False в конце. ’ Do ...блок кода Exit Do ...блок кода Loop Until условие ...блок кода Loop While условие. ’ ’ 28 VBA for EXCEL Цикл While и Until. Зарезервированные слова While и Until определяют логику условия, причем While указывает, что цикл будет выполняться до тех пор, пока условие принимает значение True, а Until указывает, что цикл будет выполняться до тех пор, пока условие не станет True. Отношение между While и Until можно выразить следующим образом: While условие = Until Not условие Применение оператора Exit Do. Оператор Exit Do предназначен для преждевременного прекращения цикла и обычно применяется в логической структуре (вроде оператора If), которая проверяет альтернативное условие прерывания цикла, например ошибку. Запись условия в начале цикла. Запись условия в начале или в конце цикла определяет, где это условие будет определяться. Когда условие определяется в начале цикла, цикл выполняется (или не выполняется), если условие исходно удовлетворено. Такой вид цикла удобно применять в тех случаях, когда когда цикл не должен выполняться до тех пор, пока условие не будет выполнено. Например, при чтении дискового файла можно использовать функцию EOF() для проверки очередной части файла в поисках маркера его конца. Если вы попытаетесь прочесть маркер конца файла, ваша программа остановится с ошибкой; таким образом, перед тем, как прочесть из файла какие либо данные, необходимо проверять очередную часть файла в поисках маркера конца файла. Чтобы сделать это, можно использовать нечто подобное 29 VBA for EXCEL Open “Myfile.txt” For Input As #1 ’ Открытие файла. Do Until EOF(1) ’ Проверка на конец файла. Input #1, A$ ’ Если нет, то чтение данных. . . ’ Код преобразования величины A$ . Loop Close #1 ’ Закрытие файла по концу работы. В этом фрагменте кода функция EOF() проверяет маркер конца файла. Если вы еще не дошли до конца файла, функция EOF() возвратит False и цикл выполниться, прочитав из файла строку и обработав ее. Если функция EOF() обнаружит маркер конца файла, то она возвратит True и цикл прервется. Запись условия в конце цикла. Запись условия в конце цикла означает, что цикл выполнится хотя бы один раз. Этот вид цикла применяеися в тех случаях, когда когда цикл должен быть выполнен хотя бы один раз, чтобы сформировать условие, которое затем будет проверятьсяю. Он используется в основном для поиска, например, конкретного значения в массиве. Так, следующая процедура находит в массиве первый положительный элемент: ’ Поиск первого положительного элемента массива. ’ Function FirstPos(theArray) As Single Dim J As Integer, Value As Single J = LBound(theArray) -1 ’Инициализация J ’Начало цикла Do J=J+1 Value = theArray(J) ’Наращивание J ’Выбор элемента массива 30 VBA for EXCEL Loop Until Value > 0 ’Проверка элемента FirstPos = Value End Function В этой процедуре theArray является переменной типа Variant, и следовательно, позволяет передать из таблицы массив. Функция Lbound() возвращает нижний предел индекса массива. Переменная J устанавливается не единицу меньше этого предела, так как в начале цикла она будет увеличена на 1, что и даст значение нижнего предела индекса массива. Цикл начинается оператором Do, затем наращивается переменная J и из массива выделяется элемент с соответствующим индексом. В конце цикла этот элемент проверяется, и если он положительный, то цикл прерывается, причем переменная Value равна положительному элементу массива, а переменная J - индексу этого элемента массива. Такая процедура предполагает, что один из элементов массива будет иметь положительное значение. Если это точно неизвестно, то необходимо проверять значение переменной J и прерывать цикл, когда J превысит верхний предел индекса массива. Иначе вы получите ошибку выполнения 9 «Subscript out of range». Что бы проверить переменную J, процедуру нужно модифицировать следующим образом: ’ ’ Поиск первого положительного элемента массива ’ Function FirstPos2(theArray) As Single Dim J As Integer, Value As Single J = LBound(theArray) -1 ’Инициализация J ’Начало цикла Do J=J+1 ’Наращивание J If J > UBound (theArraay) Then ’Превышение верхнего предела? 31 VBA for EXCEL Value = CVFrr (xlErrValue) ’Установка кода ошибки, если нет ни одного положительного элемента Exit Do ’Прерывание цикла End If Value = theArray(J) Loop Until Value > 0 ’Выбор элемента массива ’Проверка элемента FirstPos2 = Value End Function В этой версии процедуры значение переменной J после каждого наращивания сравнивается с верхним пределом индекса массива, полученном с помощью функции UBond(). Если переменная J превысит верхний предел, то переменной Value будет присвоен код ошибки #VALUE!, чтобы показать, что ни один элемент массива не соответствует заданному условию. В этом случае цикл будет прерван оператором Exit Do. Обратите внимание на то, что теперь функция возвращает значение типа Variant, - это позволяет передать код ошибки. 32 VBA for EXCEL ДИАЛОГОВЫЕ ОКОНА Встроенные диалоговые окона Передача данных программе и получение данных от программы зачастую представляет собой непростую задачу. В зависимости от конкретного применения программы создается код, реализующий пользовательский интерфейс, и эта часть программы является едва ли не самой важной. В профессионально разработанных программах объем кода, реализующего пользовательский интерфейс, занимает около 90 % общего объема кода, и только 10 % используется для обработки данных. Анализируя Excel или любую другую коммерческую программу, вы легко убедитесь в справедливости этого утверждения. Visual Basic представляет возможность применять диалоговые окна для получения данных от пользователя и для передачи ему информации. Кроме собственных встроенных диалоговых окон, Visual Basic может использовать все диалоговые окна Excel или Project. Выделяют следующие виды окон: Встроенные диалоговые окна сообщений; Встроенные диалоговые окна ввода данных; Диалоговые окна Excel. Применение функции MsgBox() Функция MsgBox() обеспечивает создание диалогового окна, подобного простому окну сообщения. Если окно сообщения всего лишь отображает сообщение для пользователя. то диалоговое окно требует от пользователя некоторых действий по вводу данных. Оно отображает строку текста, а затем ожидает, пока пользователь нажмет командную кнопку (их возможное число не ограничено). 33 VBA for EXCEL Создание простого окна сообщения Для создания простого окна сообщения применяется зарезервированное слово MsgBox, за ним следует текст, который будет отображен в виде сообщения. При создании простого окна сообщения используется функция в форме оператора. так как любое возвращенное значение будет проигнорировано и нет необходимости в передаче аргументов. Если требуется отобразить числа. используются функции Str() или Format() позволяющие преобразовать число в символьное представление. Функция Str() используется для преобразования числа (среднего квадратичного отклонения) в символьное представление. Результат преобразования объединяется с текстом и отображается функцией MsgBox() в виде окна сообщения. Добавление командных кнопок в окно сообщения для создания диалогового окна В полном варианте процедура MsgBox имеет три параметра. Командные кнопки позволят пользователю выбрать направление действий или вариант ответа на простой вопрос.Добавить командные кнопки можно используя необязательные аргументы функции MsgBox(). Коды этих команд передаются в качестве второго аргумента функции (первым аргументом является текст, отображаемый в диалоговом окне) или в качестве поименованного аргумента buttons. Список кодов и имен констант, допустимых в Visual Basic, приведен в табл. 1. Таблица 1 Код Константа Описание Коды командных кнопок 0 vbOKOnly 1 vbOKCancel OK 34 VBA for EXCEL 2 vbAbortRetryIgnore Abort, Retry и Ignore 3 vbYesNoCancel Yes, No и Cancel 4 vbYesNo Yes и No 5 vbRetryCancel Retry и Cancelтаблицы 1 Продолжение Коды активности по умолчанию vbDefaultButton Активная первая кнопка vbDefaultButton Активная вторая кнопка vbDefaultButton Активная третья кнопка 16 vbCritical Важное сообщение 32 vbQuestion Предупредительный 0 1 256 2 512 3 Коды пиктограмм запрос 48 vbExclamation Предупредительное сообщение 64 vbInformation Информационное сообщение Коды модальности окна 0 vbApplicationM Программное модальное vbSystemModal Системное модальное odal 4096 Если Вы хотите отобразить более одной кнопки, следует определить, которая из них будет активной по умолчанию. Командная кнопка, активная по умолчанию, автоматически считается нажатой, если пользователь после отображения диалогового окна нажал клавишу Enter. 35 VBA for EXCEL Кроме того, Вы можете решить будет ли диалоговое окно модальным. Если диалоговое окно не модальное, то пользователь может переключиться на другое окно, продолжив таким образом работу без закрытия диалогового окна. Если же диалоговое окно задано как модальное, то пользователь должен закрыть его, прежде чем продолжать работу с данной программой. Существуют два типа модальных диалоговых окон – программные модальные и системные модальные. Пользователь должен закрыть программное модальное окно, прежде чем продолжить работу с программой, отобразившей это окно; хотя в этом случае разрешается переключаться на другую программу, не закрыв данное диалоговое окно. Системное модально диалоговое окно требует, чтобы пользователь закрыл его прежде, чем делать что-нибудь еще. Чтобы код был более очевидным, следует использовать поименованные константы, а не числа. Можно использовать, например, любой из операторов MsgBox(): MsgBox prompt:= “Доброе утро, страна?”, _ buttons:=theCode MsgBox “Доюрое утро, страна?”, theCode Каждый из этих операторов, после записи на панели Immediat окна Debug, обеспечит создание диалогового окна. Получение значений от функции MsgBox Чтобы определить, какую командную кнопку нажал пользователь дляего закрытия, нужно использовать функциональную форму MsgBox() и проверить возвращенное функцией значение. Возможные значения, возвращаемые функцией, и соответствующие им константы Visual Basic приведены в табл. 2. Таблица 2 Код Константа Командная кнопка 1 vbOk OK 2 vbCancel Cancel 3 vbAbort Abort 36 VBA for EXCEL 4 vbRetry Retry 5 vbIgnore Ignore 6 vbYes Yes 7 vbNo No Запись заголовка в диалоговое окно Чтобы изменить заголовок, следует добавить в вызов функции MsgBox() еще один строковый аргумент, содержащий новый заголовок. При использовании формы списка аргументов, заголовок будет третьим аргументом; в противном случае используйте title :=”Текст заголовка”. Sub MakeDialog2() Dim theCode As Integer Dim theReply As Integer theCode = vbYesNo + vbDefaultButton2 + vbExclamation + vbApplicationModal theReply = MsgBox(prompt:="Вы действительно хотите это сделать?", Buttons:=theCode, _ Title:="Относительно того, что Вы собрались сделать") Select Case theReply Case vbYes theReply = MsgBox(prompt:="Вы нажали кнопочку Да") Case vbNo theReply = MsgBox(prompt:="Вы нажали кнопочку Нет") End Select End Sub Применение функции InputBox Эта функция создает диалоговое окно другого типа. Базовое окно ввода содержит окно редактирования, командную кнопку ОК и Cancel. Любой текст, записываемый в текстовое окно диалогового окна, будет возвращен функцией 37 VBA for EXCEL после того, как пользователь нажмет кнопку ОК, иначе будет возвращена пустая строка. Первый аргумент функции InputBox() – строка текста, применяемая в качестве запроса на ввод в диалоговом окне; второй – заголовок; третий – default – содержит любой текст по умолчанию, который Вы можете отобразить в окне редактирования при открытии диалогового окна. Функция не использует аргумент buttons. Все аргументы должны быть строками текста, и значение, возвращаемое функцией, также является строкой текста. Для того, чтобы использовать возвращенное функцией значение в качестве числа, нужно преобразовать его из символьного представления в двоичное с помощью функции Val(). Так, следующая процедура отображает два диалоговых окна: первое для ввода имени пользователя, а второе – для ввода возраста пользователя; затем вычисляет и отображает возраст пользователя в днях: Sub Age() Dim theReply As String, thePrompt As String Dim theTitle As String, theDefault As String Dim theAge As Single, OKFlag As Boolean Dim theName As String thePrompt=”Введите Ваше имя.” theTitle=”Персональный информационный диалог” theDefault=”Имя” ‘Цикл ожидания ввода имени пользователя. Do theReply=InputBox(thePompt, theTitle, theDefault) if theReply=”” Then Exit Sub theReply=Trim(theReply) ‘Удаление пробелов с двух сторон строки. ‘Проверка на строку пробелов или пробел в строке. If (theReply=””) Or (InStr(theReply,” “)<>0) Then 38 VBA for EXCEL MsgBox “Непонятно, попробуйте еще раз.”, , theTitle OKFlag=False Elsejf theReply-theDefault Then MsgBox “Ну, хоть что – нибудь напишите!” , , _theTitle OKFlag=False Else theName=theReply OKFlag=True End if Loop Until OKFlag thePrompt=”Привет, “&theReply&”, а лет Вам сколько?” ‘Цикл ожидания корректного числа. Do theReply-InputBox(thePrompt, theTitle) If theReply=”” Then Exit Sub theAge=Val(theReply) ‘Преобразование строки в число. If Not IsNumeric(theReply) Then MsgBox “Введите какое-нибудь число, пожалуйста, иначе не отстану!”, , _theTitle) OKFlag=False Else if (theAge<1) Or (theAge>120) Then MsgBox “Ого, сколько Вам стукнуло, честно врете!”, , theTitle OKFlag=False Else OKFlag=True End if Loop Until OKFlag MsgBox “Вам приблизительно “&Format(theAge*365, “#,###”)&”дней”, , _theTitle 39 VBA for EXCEL End Sub Применение диалоговых окон других типов Существует еще два типа встроенных диалоговых окон: GetOpenFilename и GetSaveAsFilename. Эти окна не открывают файл и не сохраняют его, а только позволяют указать его имя и путь. Команды, создающие такие диалоговые окна, являются не операторами Visual Basic, а методами Application. Операторы, создающие эти два типа диалоговых окон, имеют следующий синтаксис: (файловый_фильтр, theFilename=Application.GetOpenFilename индекс_фильтра, заголовок) theFilename=Application.GetSaveAsFilename (начальное_имя_файла, _файловый фильтр, индекс_фильтра, заголовок) Оба метода применяются к объекту Application и возвращают имя файла и путь, выбранные пользователем. Аргумент файловый_фильтр определяет, какие файловые фильтры перечисляются в выпадающем списке File Type диалогового окна. Всписке файлов диалогового окна появляются только те файлы, которые совпали с выбранным файловым фильтром. Файловый фильтр состоит из двух частей – текста и фильтра. Текст отображается в выпадающем списке File Type; а фильтр используется для выбора файлов из списка. Аргумент индекс_фильтра является целым числом, задающим в выпадающем списке File Type файловый фильтр поумолчанию. Аргумент заголовок аналогичен используемому для функции InputBox(). Аргумент начальное_имя_файла определяет начальное , заданное по умолчанию, имя файла, которое помещают в окно редактирования текста. Диалоговые окна приложения Программы на Visual Basic могут вызывать все диалоговые окна, существующие в Excel. Однако эти диалоговые окна действуют не так, как 40 VBA for EXCEL описанные выше, и возвращают программе на Visual Basic без изменений какойлибо таблицы или ячейки. Если Вы вызываете диалоговое окно Excel, то оно не возвращает значения программе Visual Basic, а осуществляет свои нормальные функции. Предуприждение: В связи с тем, что диалоговые окна приложения применяются к текущему отображаемому объекту, не отображайте диалоговое окно вне контекста: так как это приведет к ошибке выполнения. Для вызова диалогового окна приложения пользуйтесь набором Dialogs объекта Application. Для поиска доступных диалоговых окон и констант воспользуйтесь Object Browser, выбрав объект Constants из библиотеки Excel (нужные константы начинаются с xlDialog). Следующая процедура отображает диалоговое окно FormatNumber: Sub TestDialog2() Application.Dialogs(xlDialogFormatNumber).Show End Sub Чтобы выполнить эту процедуру, запишите ее на странице модуля, переключитесь на таблицу, укажите директиву Tools/Macro, выберите процедуру TestDialog2(), затем нажмите кнопку Run. Заключение Диалоговые окна являются основным средством организации обмена небольшими объемами данных между пользователями и выполняющейся программой. Две функции MsgBox() и InputBox() создают встроенные диалоговые окна, позволяющие управлять большинством простейших обменов данными. Методы GetOpenFilename() и GetSaveAsFilename() создают диалоговые окна, позволяющие создать имя файла, подлежащего открытию или сохранению. Кроме того, допустимыми являются диалоговые окна пользователя. Кроме встроенных диалоговых окон Visual Basic, можно отобразить любое из диалоговых окон программы Excel для осуществления их нормальных функций. 41 VBA for EXCEL Диалоговые окна пользователя 1. Добавление новой страницы диалога. Чтобы открыть новую страницу диалога нужно на названии открытого листа щелкнуть правой кнопкой мыши и в контекстном меню открыть команду «Добавить», после этого появится окно, в котором выбрать «Окно диалога». 2. Помещение объектов в бланк. Чтобы разместить нужный объект в диалоговом окне нужно в пиктографическом меню «Формы» выбрать объект, переместить его в бланк, щелкнув левой кнопкой мыши, растянуть прямоугольник. Чтобы переместить объект нужно выбрать его и перетащить за край на нужное место. Чтобы видоизменить объект надо выбрать его (щелкнуть мышкой) и установить нужный размер с помощью маленьких черных прямоугольников, которые появляются вокруг выбранного объекта. Примеры всех объектов, которые можно подключить к бланку, приведены: 3. Отображение диалогового окна пользователя. 42 VBA for EXCEL Существует несколько способов отображения диалогового окна, зависящих от потребностей: Отображение окна при активной странице диалога. Встать на диалоговое окно, щелкнуть правой кнопкой мыши, и в появившемся меню выбрать команду «Отобразить окно». Этот метод применяется в первую очередь для отладки диалогового окна и проверки его функционирования. Отображение окна из программы на Visual Basic. Применяется метод Show. Пример. DialogSheets("Диалог").Show, где «Диалог» - название листа диалога. 4. Подключение процедур к объектам диалогового окна пользователя. Чтобы к объекту подключить процедуру нужно, выбрав объект, щелкнуть правой кнопкой мыши и в контекстном меню открыть команду «Назначить макрос». В появившемся окне указать процедуру, которую хотите подключить к объекту, или выбрать команду «Создать» для создания заголовка новой процедуры. 5. Объекты диалогового окна пользователя. Чтобы определить настройку объекта нужно выбрать объект, щелкнуть правой кнопкой мыши и в появившемся контекстном меню открыть команду «Формат объекта». Чтобы сменить текст объекта – выбрать команду «Изменить текст». При изображении объектов в диалоговом окне пользователя, Visual Basic присваивает этим объектам имена по умолчанию (Label 2, Button 3). При выборе объекта его имя появляется в окне Name, расположенном в левом углу 43 VBA for EXCEL строки редактирования. Чтобы изменить имя объекта нужно, выбрав объект, записать новое имя в окне Name и нажать Enter. 5.1 Объект «Командная кнопка». Чтобы подключить командную кнопку нужно выбрать пиктограмму «Кнопка» на пиктографическом меню «Формы». Чтобы командная кнопка инициировала какие-нибудь действия, ее необходимо подключить к процедуре, для этого нужно выбрав командную кнопку, щелкнуть правой кнопкой мыши и в контекстном меню открыть команду «Назначить макрос». В появившемся окне указать процедуру, которую хотите подключить к кнопке, или выбрать команду «Создать» для создания заголовка новой процедуры. 5.2 Объект «Метка». Чтобы создать метку, нужно выбрать пиктограмму «Надпись», переместить ее на бланк, затем установить нужный размер. Выбрав метку, можно записать в нее текст, который хотите отобразить. (пример на листе Диалог1). Чтобы изменить текст метки программным путем, необходимо изменить свойство метки Caption. Пример процедуры, которая меняет текст метки Sub Смена_метки() DialogSheets("Диалог1").Labels("Метка 1").Caption = "Пример работы с меткой!" End Sub «Диалог1» - страница диалога, «Метка1» - имя метки. 44 VBA for EXCEL (пример работы процедуры – лист Диалог2) 5.3 Объект «Окно редактирования». Чтобы создать окно редактирования, нужно выбрать пиктограмму «Текстовое поле», переместить ее на бланк, затем установить нужный размер. Содержимое окна редактирования может меняться как пользователем, так и программным путем. Чтобы изменить содержимое окна редактирования программным путем, нужно применить процедуру, которая использует набор EditBoxes и свойство Text. Sub Окно_редактирования() DialogSheets("Диалог3").EditBoxes("Окно").Text = Sheets("Пример").Range("A1").Value End Sub После выполнения данной процедуры в окне редактирования появится информация, которая записана в ячейке «А1» на листе «Пример». (результат работы на листе Диалог3) Sub Окно_редактирования1() Sheets("Пример").Range("A1").Value=DialogSheets("Диалог3").EditBoxes("Окно"). Text End Sub После выполнения этой процедуры в ячейке «А1» на листе «Пример» будет записана информация, которая была введена в окно редактирования на странице «Диалог3». 45 VBA for EXCEL Чтобы определить такие свойства окна редактирования как тип вводимого значения (строка, целое число, число, ссылка, формула) многострочный текст и другие можно воспользоваться командой «Формат объекта ». 5.4 Объект «Групповое окно». Чтобы создать групповое окно, нужно выбрать пиктограмму «Рамка», переместить ее на бланк, затем установить нужный размер. Групповое окно должно быть изображено на бланке до того, как будут изображены кнопки, которые нужно объединить в группу. Чтобы задать строку текста, располагающуюся в верхней области границы окна, (программным путем) применяется свойство Caption Sub Групповое_окно() DialogSheets("Диалог4").GroupBoxes("ГРокно").Caption = "Групповое окно" End Sub (результат работы на листе Диалог4) 5.5 Объект «Контрольный индикатор». Чтобы вставить контрольный индикатор, нужно выбрать пиктограмму «Флажок», переместить ее на бланк, затем установить нужный размер и написать строку текста, которая обозначает действия индикатора. Чтобы определить включен или выключен контрольный индикатор, надо использовать набор CheckBoxes и свойство Value. Если индикатор включен, то свойство Value возвращает значение «1», если выключен, то «-4146» Sub Контрольный_индикатор1() 46 VBA for EXCEL Sheets("Пример").Range("A2").Value = DialogSheets("Диалог5").CheckBoxes("Флажок1").Value End Sub В результате выполнения этой процедуры в ячейке «А2» на листе «Пример» будет значение «1», если индикатор с именем «Флажок1» на листе «Диалог5» был включен, либо значение «-4146» в противном случае. (пример на листе «Диалог5») Чтобы определить строку текста, располагающуюся справа от индикатора, используют свойство Caption. Sub Контрольный_индикатор2() Sheets("Пример").Range("A3").Value = DialogSheets("Диалог5").CheckBoxes("Флажок1").Caption End Sub В ячейке «А3» после выполнения этой процедуры будет располагаться строка текста, расположенная справа от индикатора. 5.6 Объект «Кнопка выбора». Чтобы вставить кнопку выбора, нужно выбрать пиктограмму «Переключатель», переместить ее на бланк, затем установить нужный размер и написать строку текста. Чтобы определить включена или не включена кнопка выбора, надо использовать набор OptionButtons и свойство Value. Если кнопка включена, то свойство Value возвращает значение «1», если выключена, то «-4146» Sub Кнопка_выбора1() 47 VBA for EXCEL Sheets("Пример").Range("A4").Value = DialogSheets("Диалог6").OptionButtons("КНвыбора").Value End Sub Ячейка «А4» содержит значение «1» или «-4146», если кнопка выбора включена или выключена соответственно. Чтобы определить строку текста, располагающуюся справа от кнопки выбора, используют свойство Caption. Sub Кнопка_выбора2() Sheets("Пример").Range("A5").Value= DialogSheets("Диалог6").OptionButtons("КНвыбора").Caption End Sub (пример на листе «Диалог 6») 5.7 Объект «Окно списка». Пользователь не имеет возможности редактировать содержимое окна списка и может выбрать только один элемент из списка. Чтобы создать окно списка, нужно выбрать пиктограмму «Список», переместить ее на бланк, затем установить нужный размер. Чтобы добавить элементы в список можно воспользоваться одним из способов: 1) Выбрав окно списка, щелкнуть правой кнопкой мыши, вызвав, таким образом, меню, в котором открыть команду «Формат объекта». В строку «Формировать список по диапазону» записать ссылку на область таблицы, в ячейках которой находятся элементы списка. В строку «Помещать результат в ячейку» записать ячейку, в которую будет передаваться номер выбранного элемента. Пример. Пусть на листе «Пример» в ячейках записана следующая информация: 48 VBA for EXCEL В ячейке «А6» - зима, в «А7» - весна, в «А8» - лето, в «А9» - осень, а свойства списка (которые были вызваны командой «Формат объекта») содержат следующую информацию: «Формировать список по диапазону» Пример!$A$6:$A$9 «Помещать результат в ячейку» Пример!$A$10 Тогда в ячейке «А10» на листе «Пример» будет записан номер выбранного элемента, а список будет содержать значения: зима, весна, лето, осень. (пример на листе «Диалог 7») 2) Заполнить список можно, используя набор ListBoxes и свойство List. 3) Добавить элемент к списку можно, применив метод AddItem. Этот метод использует два аргумента – строку текста, которая вставляется в список, и индекс, определяющий место нового элемента в списке. Если индекс опущен, новый элемент будет добавлен в конец списка. Пример процедуры, в которой использованы два последних метода. Sub Добавление_в_окно_списка() DialogSheets("Диалог8").ListBoxes("ОКНОсписка").List = Array("зима", "весна", "осень") DialogSheets("Диалог8").ListBoxes("ОКНОсписка").AddItem "лето", 3 End Sub Процедура «Добавление_в_окно_списка» присваивает свойству List массив времен года, чтобы поместить эти названия в окно списка. Затем применяется метод AddItem, позволяющий вставить «осень» на место третьего элемента списка. В результате выполнения данной процедуры в списке с именем 49 VBA for EXCEL «ОКНОсписка» на листе «Диалог8» будут находиться названия: зима, весна, осень, лето. (пример на листе «Диалог8») Предупреждение: Если сначала заполнить список, используя 1 метод, то изменение даже одного элемента с помощью свойства List (2 метод) разрывает связь между окном списка и областью таблицы. После применения свойства List и ли метода AddItem в списке останутся только те элементы, которые были помещены в него этими свойством и методом. Применять свойство List без разрыва связей можно только для просмотра содержимого списка. Чтобы удалить элементы из списка используется метод RemoveItem, использующий два аргумента – индекс и счетчик. Индекс определяет номер элемента списка, с которого начинается удаление, а счетчик – количество элементов, подлежащих удалению. Если счетчик опущен, то по умолчанию он принимается равным 1. Sub Удаление_из_окна_списка() DialogSheets("Диалог9").ListBoxes("ОКНОсписка").RemoveItem Index:=1, Count:=1 End Sub Процедура «Удаление_из_окна_списка» удаляет первый элемент окна списка. (пример лист «Диалог9») Чтобы удалить все элементы списка применяется метод RemoveAllItem или RemoveItem с индексом, равным 1, и счетчиком, превышающим количество элементов списка. Чтобы определить номер элемента из списка пользователя, применяется свойство Value окна списка. Это свойство содержит номер элемента, выбранного из списка. Sub Выбор_номера_элемента_в_окне_списка() 50 VBA for EXCEL Sheets("Пример").Range("A13").Value = DialogSheets("Диалог8").ListBoxes("ОКНОсписка").Value End Sub После выполнения процедуры «Выбор_номера_элемента_в_окне_списка» в ячейке «А13» на листе «Пример» будет номер элемента, выбранного в окне списка с именем «ОКНОсписка». Чтобы увидеть сам элемент, нужно выбрать его из свойства List с помощью свойства Value. Sub Выбор_элемента_в_окне_списка() With DialogSheets("Диалог8").ListBoxes("ОКНОсписка") Sheets("Пример").Range("A12").Value = .List(.Value) End With End Sub Окно списка с именем «ОКНОсписка» находится на листе диалога «Диалог8», ячейке «А12» на листе «Пример» присваивается содержимое текущего выбранного элемента в окне списка. Объект «Выпадающее окно». Выпадающее окно практически аналогично окну списка, за исключением того, что окно списка размещает список в прокручиваемом окне, а выпадающее окно создает выпадающий список. Доступ к выпадающему окну осуществляется с помощью набора DropDowns. Чтобы создать выпадающее окно, нужно выбрать пиктограмму «Поле со списком», переместить ее на бланк, затем установить нужный размер. Чтобы поместить элементы в список, можно использовать команду «Формат объекта» (заполнить строки «Формировать список по диапазону» и «Помещать результат в ячейку»). Чтобы увидеть элемент выпадающего окна, нужно выбрать его из свойства List с помощью свойства Value, используя набор DropDowns. Sub Выбор_элемента_в_выпадающем_окне() 51 VBA for EXCEL With DialogSheets("Диалог10").DropDowns("ОКНО") Sheets("Пример").Range("A18").Value = .List(.Value) End With End Sub Окно списка с именем «ОКНО» находится на листе диалога «Диалог10», ячейке «А18» на листе «Пример» присваивается содержимое текущего выбранного элемента в выпадающем окне. Чтобы определить номер элемента в выпадающем окне, применяется свойство Value выпадающего окна. Это свойство содержит номер элемента, выбранного из списка. Sub Выбор_номера_элемента_в_выпадающем_окне() Sheets("Пример").Range("A19").Value = DialogSheets("Диалог10").DropDowns("ОКНО").Value End Sub После выполнения процедуры «Выбор_номера_элемента_в_выпадающем_окне» в ячейке «А19» на листе «Пример» будет номер элемента, выбранного в выпадающем окне с именем «ОКНО». Комбинированный объект «Окно список-редактирование». Комбинированное окно список-редактирование объединяет окно списка и окно редактирования. Эти два окна связываются таким образом, что если выбрать элемент в окне списка, то он автоматически появится в окне редактирования, где этот элемент можно изменить. В комбинированном окне список-редактирование окно списка и окно редактирования являются двумя отдельными окнами с различными именами и отдельными свойствами. Доступ к свойствам каждого окна осуществляется независимо, с помощью методов доступа к окнам списка и окнам редактирования, описанных выше. Объект «Линейка прокрутки». Чтобы создать линейку прокрутки, нужно выбрать пиктограмму «Полоса прокрутки», переместить ее на бланк, затем установить нужный размер. 52 VBA for EXCEL Чтобы получить доступ к линейке прокрутки, надо использовать набор ScrollBars. Чтобы получить число, определяющее положение ползунка на линейке прокрутки, используют свойство Value. Sub Линейка_прокрутки1() Sheets("Пример").Range("A21").Value = DialogSheets("Диалог12").ScrollBars("Прокрутка").Value End Sub В ячейке «А21» на листе «Пример» после выполнения этой процедуры будет значение ползунка линейки прокрутки с именем «Прокрутка». Свойства Min и Max , управляющие диапазоном значений, возвращаемых свойством Value, доступны как из программы, так и с помощью команды «Формат объекта». Пример установления максимального и минимального значения линейки прокрутки программным способом. Sub Линейка_прокрутки2() DialogSheets("Диалог12").ScrollBars("Прокрутка").Max = 15 DialogSheets("Диалог12").ScrollBars("Прокрутка").Min = 1 End Sub Объект «Спиннер». Чтобы создать спиннер, нужно выбрать пиктограмму «Счетчик», переместить ее на бланк, затем установить нужный размер Доступ к спиннеру осуществляется с помощью набора Spinners. Обычно свойство спиннера Value связано со свойством Text окна редактирования. Пример организации спиннера с окном редактирования. 53 VBA for EXCEL Sub Спиннер() DialogSheets("Диалог13").EditBoxes("Поле").Text= DialogSheets("Диалог13").Spinners("Счетчик").Value End Sub Данную процедуру подключают к спиннеру с помощью команды «Назначить макрос». ЭЛЕМЕНТЫ УПРАВЛЕНИЯ ДИАЛОГОВЫХ ОКОН При создании пользовательской формы из листа или листа диаграммы существует возможность добавления к листу кнопок, флажков и других элементов управления. Элементы управления позволяют предложить пользователю выбор параметров или дать возможность запуска макросов для автоматизации задач. Для создания таких элементов управления, как кнопка, группа флажков, поле со списком или полоса прокрутки используется панель инструментов Формы. Кнопке можно поставить в соответствие существующий макрос или с помощью флажков или переключателей вывести данные в виде списка или изменить данные на листе. Элементы управления, расположенные на панели инструментов Элементы управления, называются элементами ActiveX. Элементы ActiveX можно добавить к форме, созданной с помощью редактора Visual Basic. При добавлении элемента ActiveX на лист создается макрос, который сохраняется непосредственно вместе с элементом управления, а не только запускается при его выборе. При настройке элементов ActiveX можно изменять некоторые их свойства. У элементов ActiveX существует также множество различных макрокоманд или событий, которые могут появиться при их использовании, например, отображение вида указателя, когда он находится на элементе управления. 54 VBA for EXCEL Элементы ActiveX используются для создания форм и окон диалога для пользовательских программ Visual Basic. Панель инструментов Элементы управления содержит элементы ActiveX и специальные элементы управления, созданные другими приложениями. Элементы ActiveX используют макросы, написанные специально для них. Также они используются для управления различными событиями, появляющимися при использовании элемента управления. При добавлении элементов управления можно изменять их свойства. Свойствами определяется внешний вид данного элемента управления, ячейка или диапазон ячеек, на которые он ссылается, и его состояние (например, установлен или снят флажок по умолчанию). 55 VBA for EXCEL 1. СПИСОК ЭЛЕМЕНТОВ ACTIVEX, НАХОДЯЩИХСЯ НА ПАНЕЛИ ИНСТРУМЕНТОВ ЭЛЕМЕНТЫ УПРАВЛЕНИЯ. Флажок. Включает или выключает действие определенного параметра. Одновременно может быть установлено несколько флажков на листе. Текст. Поле, в которое можно ввести текст. Кнопка. Кнопка, при нажатии на которую выполняется макрокоманда. Переключатель. Кнопка, используемая для выбора только одного параметра из группы. Список. Поле, содержащее список элементов. Поле со списком. Текстовое поле с раскрывающимся списком. Можно ввести или выбрать нужное значение из списка. Выключатель. Кнопка, остающаяся нажатой после нажатия на нее. Чтобы отжать такую кнопку, нужно нажать ее еще раз. Счетчик. Кнопка, которая может быть вложена в ячейку или текстовое поле. Стрелка вверх служит для увеличения значения, а стрелка вниз — для уменьшения. Полоса прокрутки. Элемент управления, прокручивающий список значений при нажатии стрелок прокрутки или перемещении бегунка. Чтобы прокрутить 56 VBA for EXCEL страницу значений, достаточно переключаться между бегунком и стрелкой прокрутки. Надпись. Текст, добавляемый к листу или форме, с тем, чтобы обеспечить сведения об элементе управления, листе или форме. Рисунок. Элемент ActiveX, позволяющий внедрить рисунок в форму. Группа. Рамка и надпись, объединяющая связанные между собой элементы ActiveX, такие как переключатели или флажки. Добавление элементов activex с панели инструментов элементы управления Чтобы добавить элементы управления с панели инструментов Элементы управления необходимо произвести следующие действия: 1. Открыть лист, к которому следует добавить элемент ActiveX. 2. Если панели инструментов Элементы управления на экране нет, то установить указатель на пункт Панели инструментов в меню Вид, а затем выберите команду Элементы управления. 3. Нажать кнопку, соответствующую добавляемому элементу управления. 4. На листе с помощью мыши придать элементу управления нужный размер. 5. Чтобы установить свойства для элемента управления, необходимо щелкнуть его правой кнопкой мыши, а затем выбрать команду Свойства в контекстном меню 6. Чтобы добавить макрос к элементу управления, нужно щелкнуть его правой кнопкой мыши, а затем выбрать команду Исходный текст в контекстном меню. Для возврата в Microsoft Excel из редактора Visual Basic следует выбрать команду Закрыть и вернуться в Microsoft Excel в меню Файл. 7. Чтобы выйти из режима конструктора и сделать доступным элемент ActiveX, нужно нажать кнопку выхода из режима конструктора . 57 VBA for EXCEL Свойства элементов управления Свойства элемента управления для полосы прокрутки: Текущее значение. Отражает текущее положение бегунка на полосе прокрутки. Минимальное значение. Отражает самое верхнее возможное положение бегунка на вертикальной полосе прокрутки и самое левое на горизонтальной. Максимальное значение. Отражает самое нижнее возможное положение бегунка на вертикальной полосе прокрутки и самое правое на горизонтальной. Шаг изменения. Представляет собой величину изменения положения бегунка при нажатии на одну из стрелок полосы прокрутки. Шаг изменения по страницам. Представляет собой величину изменения положения бегунка при нажатии клавиши мыши между бегунком и одной из стрелок полосы прокрутки. Связь с ячейкой. Означает ячейку, в которой выдается текущее значение, соответствующее положению бегунка. Это значение может использоваться в формуле для вывода результата, основанного на положении бегунка. Свойства элемента управления для счетчика аналогичны свойствам для полосы прокрутки, кроме свойства Шаг изменения по страницам, которого нет у счетчика. Свойства элемента управления для списка: Диапазон для формирования списка. Ссылается на список значений на листе. Из этого диапазона берутся значения для списка. Связь с ячейкой. Означает ячейку, в которой выдается значение, представляющее собой выбранный элемент списка. Это значение может использоваться в формуле для вывода результата, основанного на выбранном элементе списка. Например, если список связан с ячейкой C1 и диапазоном 58 VBA for EXCEL для формирования списка являются ячейки D10:D15, то следующая формула возвращает значение из диапазона D10:D15 на основе выбора в списке: =INDEX(D10:D15,C1) Возможный выбор. Указывает способы выбора элементов в списке. При установке возможности выбора Набора значений или Списка значений ячейка, указанная в поле Помещать результат в ячейку, игнорируется. Свойства элемента управления для поля со списком: Поле со списком - это раскрывающийся список. Диапазон для формирования списка. Ссылается на список значений на листе. Из этого диапазона берутся значения для раскрывающегося списка. Связь с ячейкой. Означает ячейку, в которой выдается значение, представляющее собой выбранный элемент списка. Это значение может использоваться в формуле для вывода результата, основанного на выбранном элементе списка. Количество строк списка. Указывает количество строк, которое нужно отобразить в раскрывающемся списке. Свойства элемента управления для флажков: Значение. Определяет состояние флажка по умолчанию: Установлен, Снят или Не определено. Связь с ячейкой. Зависит от состояния флажка. Если флажок установлен, то в ячейке, указанной в поле Связать с ячейкой, выдается логическое значение ИСТИНА. Если флажок снят, в ячейке выдается значение ЛОЖЬ. Если состояние флажка не определено, выдается ошибка #Н/Д. Свойства элемента управления для переключателей: Значение. Определяет состояние переключателя по умолчанию: Установлен или Снят. 59 VBA for EXCEL Связь с ячейкой. Зависит от состояния переключателя. Так как переключатель используется для выбора только одного параметра из группы, следует поместить связанные между собой переключатели в группу, а затем связать каждый из них с одной и той же ячейкой листа с помощью поля Связать с ячейкой. Когда переключатель установлен, в ячейке, с которой он связан, выдается его номер. Этот номер может использоваться в формуле для вывода результата, основанного на выбранном параметре. Например, при создании личной формы с переключателями Полный рабочий день и Неполный рабочий день, оба переключателя были связаны с ячейкой C1. Согласно следующей формуле, если установлен первый переключатель, на экран выводится «Полный рабочий день», а если второй, то «Неполный рабочий день». =IF(C1=1,"Полный рабочий день","Неполный рабочий день") РАБОТА С ФАЙЛАМИ Файлы последовательного и произвольного доступа Чтение и запись последовательных файлов Чтение и запись файлов произвольного доступа Реорганизация данных в файле произвольного доступа Файлы последовательного и произвольного доступа В Visual Basic существуют два основных типа дисковых файлов – последовательного и произвольного доступа. Собственно, таких типов – три, если считать таблицы, которые в Visual Basic также используются для хранения данных. Однако в Visual Basic отсутствует возможность прямо читать из файлов таблиц или писать в них; можно только записывать данные в открытую таблицу, а затем сохранять ее с помощью Excel. 60 VBA for EXCEL Способы, которыми записываются данные в файлы последовательного и произвольного доступа, значительно отличаются друг от друга. Файлы последовательного доступа читаются и пишутся последовательно, от начала файла до его конца. Текстовые файлы, такие как README, встречающиеся в большинстве прикладных программ, являются файлами последовательного доступа. Для того, чтобы получить доступ к определенной части информации в последовательном файле, необходимо начать от начала файла и читать последовательно, запись за записью, до тех пор, пока не будет найдена требуемая информация. Файлы произвольного доступа основаны на записях постоянной длины, что позволяет читать и писать информацию произвольно, в любом порядке. Последовательный файл можно либо читать, либо писать, а файл произвольного доступа – читать и писать одновременно. Ограничением файлов произвольного доступа является фиксированная длина записи. Однако это ограничение позволяет Visual Basic быстро обнаружить запись на диске. Например, для чтения восьмой записи файла Visual Basic пропускает семь полных записей, а затем читает следующую. Если бы записи не имели фиксированной длины, то пришлось бы поддерживать отдельный индекс, определяющий, где кончается одна запись и начинается другая. Чтение и запись последовательных файлов Последовательный файл является наиболее общим типом файла. Любой файл, который читается в память целиком, должен быть последовательным. Большинство неформатированных текстовых файлов являются последовательными – так же. Как и большинство файлов программ. В Visual Basic текстовые файлы также представляют собой файлы последовательного доступа. Данные в этих файлах записаны также в форме строк символов ANSI. 61 VBA for EXCEL Открытие файла Прежде чем Visual Basic сможет что-либо сделать с дисковым файлом, необходимо открыть этот файл и подключить к нему файловое число. Файловые числа – это небольшие целые числа. Которые связываются с файлом при его открытии. Команды чтения и записи используют файловые числа для указания файла, в который надо писать или из которого надо читать. Для открытия последовательного файла используется оператор Open, имеющий следующий синтаксис: Open имя_файла For режим As файловое_число Аргумент имя_файла является строкой, содержащей имя и путь файла, который необходимо открыть. Если файл находиться в текущей директории, то достаточно указать только его имя. Если файл находиться не в текущей директории, то для него необходимо указывать полный путь. Аргумент режим определяет тип файла, который необходимо открыть, и способ открытия файла. Режим должен принимать одно из литеральных значений: Input, Output, Append (для последовательных файлов) или Random (для файлов произвольного доступа). Кроме того, в особых ситуациях может применяться режим двоичного доступа. Режим Input открывает файл для чтения, а режим Output – для записи. Оба режима открывают файл последовательного доступа с его начала. Режим Append открывает файл с конца – с тем, чтобы при записи новых данных не пришлось переписывать все записи от начала файла. Попытки открыть несуществующий файл с режимом Input приведут к ошибке; если открыть несуществующий файл с режимами Output и Append, то файл будет создан. Аргумент файловое_число определяет число, которое присваивается файлу. Обычно первому файлу присваивают 1, второму – 2 и т.д. если файл закрывается, то освободившееся файловое число может быть использовано повторно; нельзя 62 VBA for EXCEL открыть файл, используя файловое число, которое уже присвоено открытому файлу. Если неизвестно, какое файловое число является допустимым в данный момент, то для присвоения некоторой переменной допустимого файлового числа можно воспользоваться функцией FreeFile. Затем эта переменная используется в качестве оператора Open, а также операторов чтения и записи файла. Так, следующие строки кода открывают последовательный файл для чтения: FileNum1 = FreeFile Open “myfile.txt” For Input As FileNum1 В данном примере функция FreeFile использована для выбора следующего допустимого файлового числа, а затем файл с именем MYFILE.TXT открывается с начала для чтения. Закрытие файла После завершения работы с файлом, его необходимо закрыть с помощью оператора Close. В качестве аргумента оператора Close используется файловое число, указывающее на то, какой файл нужно закрыть. Ниже приведен синтаксис оператора Close: Close #файловое_число Если опустить аргумент файловое_число, то Visual Basic закроет все открытые файлы. Печать в файл Если файл открыт, то для записи в него данных можно использовать оператор Print. Данные, записываемые оператором Print, представляют собой текст, подобный тому, который выдается на принтер. 63 VBA for EXCEL Если печатается некоторый текст, то этот текст записывается в файл. Если печатается число, то это число помещается в файл. Если печатается переменная, то в файл помещается значение этой переменной. Если поместить в строку для печати несколько элементов, разделенных запятыми, то они будут напечатаны в блоках, заполненных пробелами и разделенных фиксированными табулостопами через каждые 14 символов: Print 1, 2, 3, 4 1 2 3 4 Print “Один”, “Два”, “Три”, “Четыре” Один Два Три Четыре Однако если вместо запятых использовать символ (;), то напечатанные элементы не будут содержать пробелов: Print 1; 2; 3; 4 1 2 3 4 Print “Один”; “Два”; “Три”; “Четыре” ОдинДваТриЧетыре Примечание: Если разделить символом (;) числа в операторе Print, то напечатанная строка будет содержать по два пробела между числами. Эти пробелы появляются в результате того, что оператор Print преобразовывает каждое число в строку текста, добавляя к нему ведущий и конечный пробелы, что в результате и дает два пробела между числами. Для управления печатью следует использовать функцию Format (). Функция Format () получает два аргумента, а возвращает отформатированную строку. Первым аргументом является переменная, содержащая число, которое 64 VBA for EXCEL нужно напечатать, а второй аргумент содержит строку форматирования, определяющую форму, в которой нужно напечатать число. строка форматирования подобна тому, что используется в Excel для форматирования содержимого ячеек. Символ Значение символа (#) Используется в качестве цифровых заполнителей (,) Указывает на то, что каждые три символа отделяются запятой (.) Указывает положение десятичной точки (0) Указывает позицию обязательного символа Для печати в дисковый файл после зарезервированного слова Print необходимо записать символ (#), файловое число и запятую: Print #файловое число, список_аргументов где файловое_число определяет открытый файл, а список_аргументов содержит то, что необходимо напечатать. Пример 1 “Работа оператора Print” Open “c:\Мои документы\Myfile_1.txt” For Output As 1 Print #1, “Общий привет” Print #1, 5 a = 5 Print #1, a Print #1, 1, 2, 3, 4 Print #1, 1; 2; 3; 4 Print #1, “Один”, “Два”, “Три”, “Четыре” Print #1, “Один”; “Два”; “Три”; “Четыре” 65 VBA for EXCEL Print #1, a Print #1, a, Format(a, “#,###.00”), Format(a, “#.0”) a = 0.1234 Print #1, a, Format(a, “#,###.00”), Format(a, “0.00”), “#,###.00”), Format(a, “0.00”), Format(a, “00.00”) a = 1234. Print #1, a, Format(a, Format(a, “00.0”) Close #1 Запись в файл При использовании оператора Print данные, записываемые в дисковый файл, формируются в пригодную для чтения форму, подобную текстовому документу. Однако если предполагается чтение этих данных программами на Visual Basic, то их следует записывать не оператором Print, а оператором Write. Оператор Write работает подобно оператору Print, но сохраняет существовавшие кавычки и разделяет выводимые данные запятыми. Эти запятые и кавычки упрощают в Visual Basic определение конца одного элемента данных и начала другого. Пример 2 “Работа оператора Write” FNum = FreeFile Open “c:\Мои документы\Myfile_2.txt” For Output As FNum Write #FNum, “Общий привет” Write #FNum, 5 a = 5 Write #FNum, a Write #FNum, 1, 2, 3, 4 Write #FNum, 1; 2; 3; 4 Write #FNum, “Один”, “Два”, “Три”, “Четыре” Write #FNum, “Один”; “Два”; “Три”; “Четыре” Write #FNum, a 66 VBA for EXCEL Write #FNum, a, Format(a, “#,###.00”), Format(a, “#.0”) a = 0.1234 Write #FNum, a, Format(a, “#,###.00”), Format(a, “0.00”), Format(a, “00.00”) a = 1234. Write #FNum, a, Format(a, “#,###.00”), Format(a, “0.00”), Format(a, “00.00”) Close #FNum Можно увидеть различия в результатах работы операторов Write (рис. 1.2) и Print (рис.1.1). Оператор Write отделяет каждый элемент данных запятой и заключает каждую строковую величину в кавычки. Строки, возвращенные функцией Format (), также заключаются в кавычки. Использование кавычек и запятых для разделения отдельных элементов данных значительно упрощает применение оператора Input. Без них было бы практически невозможно определить, где кончается один записанный элемент и начинается следующий. Чтение из файла Для чтения данных из файла применяются операторы Input и Line Input. Первый аргумент каждого из этих операторов является символ (#) и файловое число, затем следует запятая, отделяющая указатель файла, подлежащего чтению. Далее следуют аргументы – имена переменных, которым присваиваются прочитанные из файла значения. В операторе Input переменные, следующие после запятой, определяют порядок и количество данных, которые будут прочитаны из файла. Пробелы и табуляторы, расположенные в начале строки, игнорируются. Если переменная должна принимать числовые значения, то Visual Basic пытается прочесть из файла число. Первый непустой символ рассматривается как начало числа, и Visual Basic продолжает чтение числа. Если переменная является строковой, то Visual Basic читает эту строку, начиная с первого непустого символа, и прекращает чтение, если встречает запятую или конец строки. Если первый 67 VBA for EXCEL непустой символ является символом (“), то первым символом, прочитанным в строку, будет первый символ после символа (“) и чтение будет продолжено до тех пор, пока не встретиться второй символ (“) или конец строки, т.е. будут прочитаны все символы, заключенные в кавычки, включая запятые. Операторы Write и Input спроектированы для совместной работы в целях записи данных в файл и последующего их чтения. Оператор Line Input является дополнением оператора Input. Оператор Line Input присваивает единичному строковому аргументу все символы, обнаруженные в единичной строке файла. Строковому аргументу – переменной присваиваются все символы, включая начальные пробелы, запятые и кавычки. Оператор Line Input применяется для чтения в программу точной копии содержимого строки файла. Единичными символами, не пересылаемыми оператором Line Input, являются символы возврата каретки и перевода строки, рассматриваемые как конец строки. Текст макроса: Sub Макрос_3() Open "c:\Мои документы\Myfile.txt" For Input As 100 Open "c:\Мои документы\Myfile_3.txt" For Output As 101 'Чтение первой строки файла в три отдельные переменные. 'Первая строковая переменная получает текст, расположенный от начала строки до первой запятой, 'вторая - текст, расположенный между первой и второй запятыми, 'третья - текст, расположенный после второй запятой конца строки. Input #100, b$, c$, D$ Print #101, b$ Print #101, c$ Print #101, D$ 68 и до VBA for EXCEL 'Чтение второй строки файла 'Так как эта прочитать строка одним заключена оператором в кавычки, Input в то одну ее можно строковую переменную Input #100, b$ Print #101, b$ 'Чтение третьей строки файла 'В данном случае сроковая переменная получит данные, заключенные в кавычки (но без символа(")) 'а числовая переменная - число. Если опять прочесть из файла строковую переменную, то она получит оставшуюся часть строки Input #100, b$, a Print #101, b$ Print #101, a Input #100, b$ Print #101, b$ 'Чтение четвертой строки файла 'Вся строка, включая запятые и кавычки, передается в строковую переменную Line Input #100, b$ Print #101, b$ 'Чтение пятой строки файла 'Чтение чисел в три числовые переменные(пробелы числами воспринимаются как разделители) Input #100, e, f, g Print #101, e Print #101, f Print #101, g 69 между VBA for EXCEL 'Чтение шестой строки файла 'Чтение чисел в две числовые переменные(пробелы между числами игнорируются) Input #100, e, f Print #101, e Print #101, f 'Чтение седьмой строки файла 'Данную строку можно прочитать с единичной строковой переменной в качестве аргумента оператора Input. 'Начальные пробелы будут проигнорированы, переменная получит текст, начиная с первого непустого символа и до первой запятой. 'Здесь гораздо удобнее применять оператор Line Input: он позволит прочесть все от начала строки до ее конца. Input #100, b$ Print #101, b$ Line Input #100, b$ Print #101, b$ 'Чтение восьмой строки файла 'Чтение строки оператором Line Input. строка, включая пустые пробелы в начале. Line Input #100, b$ Print #101, b$ Close #100 Close #101 End Sub Чтение и запись файлов произвольного доступа 70 В результате - VBA for EXCEL Файлы произвольного доступа рассматриваются как последовательность записей постоянной длины, причем каждая запись является независимой от всех других записей файла. Длина записи определяется в операторе Open, а тип данных, указанный пользователем, определяет ее содержимое. Файлы произвольного доступа используются в основном для хранения двоичных представлений чисел, а не текстов. Применение двоичных чисел экономит пространство файла по сравнению с символьным представлением тех же чисел. Кроме того, двоичные числа загружаются в память компьютера значительно быстрее, так как не требуют преобразования перед использованием. Открытие файла Открытие файла произвольного доступа подобно открытию файла последовательного доступа оператором Open, с двумя существенными отличиями: аргумент режима всегда равен Random, а в конце оператора находится аргумент Len=длина_записи. Для открытия файла произвольного доступа используется следующий оператор Open: Open имя_файла For Random As файловое_число Len=длина_записи где имя_файла – строка, содержащая имя и путь файла, подлежащего открытию; файловое_число – номер, который вы хотите присвоить файлу; длина_записи – длина записи произвольного доступа в байтах. Примечание: Оптимальная длина записи должна быть кратной размеру дискового сектора, либо делить указанный размер нацело. Большинство дисковых накопителей имеют сектора размером 512 или 1024 байтов; следовательно, оптимальная длина записи должна быть степенью 2, 71 VBA for EXCEL например 32, 64, 128, 256 и т.д. Такая длина является целесообразной потому, что компьютер записывает и считывает данные секторами одинаковой длины. Хотя программа может запросить чтение из дискового файла всего одного байта, компьютер на самом деле прочитает в буфер памяти один или более секторов. Когда ваша программа читает данные из дискового файла, то она фактически читает их из буфера. Когда программа прочитывает весь буфер, компьютер читает в этот буфер следующие несколько секторов из файла. Аналогичным образом данные записываются в дисковый файл: сначала они записываются в буфер памяти, а когда он заполняется, то записываются на диск. Чтобы понять, почему степень 2 является оптимальной длиной записи, предположим, что размер дискового сектора – 512 байтов, а длина записи файла – 260 байтов. При такой длине записи большинство записей этого файла будут расположены в двух секторах, и для чтения из дискового файла такой записи потребуется прочесть два сектора. Например, запись 2 использует байты с 261 по 512 первого сектора и с 1 по 8 – второго. Применение вместо 260-байтных записей 256-байтных обеспечит упаковку в один сектор двух полных записей, что позволит для ввода записи читать всего один сектор. Так, следующие операторы открывают файл произвольного доступа для чтения или записи: FileNum1 = FreeFile Open “myfile.txt” For Random As FileNum1 Len = 256 Этот блок кода открывает файл произвольного доступа MYFILE.TXT с записями длиной 256 байтов. Функция FreeFile выбирает свободный номер файла. 72 VBA for EXCEL Примечание: Двоичные файлы подобны файлам произвольного доступа, с тем отличием, что длина записи двоичного файла всегда равна одному байту и величина, записываемая на диск, всегда помещается в смежные байты. Закрытие файла произвольного доступа Файл произвольного доступа, так же как и последовательный файл, закрывается оператором Close: Close # файловое_число где файловое_число – номер файла, указанный при открытии этого файла. Применение оператора Type для определения записи Оператор Type, применяемый для объявления типа, определяемого пользователем, может применяться также для объявления содержимого переменных типа запись, используемых для работ с файлом произвольного доступа. Оператор Type, используемый для объявления переменных типа запись, подобен применяемому для объявления типа, который определяется пользователем, за исключением того, что при объявлении переменных типа запись вы не используете тип Variant и учитываете, что все строковые переменные должны иметь постоянную длину. Максимальная длина записи, определенной оператором Type, должна быть не больше длины записи, объявленной оператором Open. Однако, если вы будете использовать типы меньшей длины, чем объявлено при открытии файла, то при сохранении каждой записи на диске разность между длиной записи и длиной типа будет расходоваться впустую. В приведенном ниже примере оператор Type определяет запись длиной в 256 байтов для работы с базой данных личных контактов. Каждая строка имеет постоянную длину, что в обычном операторе Type не требуется. 73 VBA for EXCEL Type DBEntry 'Определяет структуру записи базы данных. Name As String * 25 Address As String * 25 City As String * 15 State As String * 2 Zip As String * 10 Phone As String * 20 Net As String * 10 NetAddr As String * 25 Referral As String * 25 Notes As String * 97 RecNo As Integer End Type 'Размер типа 256 байтов. Чтобы узнать длину типа, определяемого пользователем, необходимо либо сложить длины всех переменных, входящих в указанный тип, либо объявить переменную указанного типа, а затем применить к ней функцию Len(). Вывод данных в запись В отличие от файлов последовательного доступа для сохранения данных в файлах произвольного доступа операторы Print или Write не применяются. Вместо них применяется оператор Put. Этот оператор имеет три аргумента – файловое число (номер, присвоенный файлу при открытии), номер записи и переменную типа запись: Put #файловое_число, номер_записи, переменная Get #файловое_число, номер_записи, переменная Так, следующий оператор Put сохраняет содержимое переменной theDB(1) в третьей записи файла, открытого с файловым числом 1: 74 VBA for EXCEL Put #1, 3, theDB(1) Если вы опустите номер записи в операторе Put, то будет использован номер, следующий за тем, который был использован в последнем из предыдущих операторов Get, Put или Seek. Ввод данных из записи Оператор Get имеет такой же синтаксис, как и оператор Put. Он также имеет три аргумента – файловое число, номер записи и переменную типа запись, получающую данные из записи на диске: Реорганизация данных в файле произвольного доступа При необходимости реорганизовать данные в последовательном файле потребуется сначала прочесть его, затем реорганизовать данные, а потом переписать файл на диске в соответствии с новой организацией. Файлы произвольного доступа предоставляют для этих целей дополнительную возможность – использование индекса, что позволяет реорганизовывать индекс, а не сам файл. Чтобы создать индекс, вначале создается массив целых чисел, в котором каждый элемент содержит один (свой) номер записи файла произвольного доступа. Затем этот массив, позволяющий определить номер записи, используется для получения доступа к записи файла произвольного доступа. Такая организация хранения записи файла называется индексированные записи. Например, если переменная I содержит номер требуемой записи, а переменная типа запись называется RecVar, то обычный доступ к файлу произвольного доступа обеспечивается следующим оператором Get: 75 VBA for EXCEL Get #fileNum, I, RecVar Если массив индексов называется theIndex(), то метод доступа изменяется таким образом: Get #fileNum, theIndex(I), RecVar Первоначально каждый элемент массива theIndex() содержит свой собственный номер: TheIndex(1) = 1 TheIndex(2) = 2 TheIndex(3) = 3 Результат использования такого массива для доступа к записям файла идентичен прямому доступу к записям. Предположим, вам потребовалось упорядочить записи в алфавитном порядке, для чего необходимо поменять местами вторую и третью записи. Вы можете физически поменять местами записи на диске либо просто изменить значения в массиве индексов следующим образом: TheIndex(1) = 1 TheIndex(2) = 3 TheIndex(3) = 2 Применяя массив индексов для доступа к файлу, вы будете получать записи в соответствии с указанным порядком, а не в порядке их физического расположения на диске. Индексированные записи очень удобны для группирования и повторного использования удаленных записей. Для удаления записи переместите ее номер в 76 VBA for EXCEL конец массива индексов, а затем оставшиеся индексы переместите на один элемент вверх. Следующий индексный номер определяется на границе использованных и свободных записей. Если нужно записать новую запись, то, прежде чем ее разместить, следует проверить, имеет ли массив индексов записи, пригодные для повторного использования. При работе с индексированными записями нужно решить, что делать с индексом. Его можно сохранить в отдельном последовательном файле или разместить в виде нескольких записей в начале файла произвольного доступа. 77 VBA for EXCEL СОЗДАНИЕ ПОЛЬЗОВАТЕЛЬСКИХ ОБЪЕКТОВ Определение пользовательского объекта Программный пользовательский объект в Visual Basic привязан к модулю. Имя модуля является именем объекта, и применяется для доступа к свойствам объекта. Если объекты стандартные, то следует начинать с класса объекта, а затем, использовав порождающую функцию вроде метода ADD, можно создавать объекты этого класса. В Visual Basic класс создать нельзя: следовательно, необходимо создавать временный пользовательский объект. Однако после того, как вы его создадите, доступ к нему ничем не будет отличаться от доступа к любому другому объекту. Для того чтобы создать пользовательский объект, начните с нового модуля. Не используйте существующий модуль, поскольку объединение обычных процедур модулю с пользовательским объектом приведет к ошибке. Для присвоения имени создаваемого пользовательского объекта воспользуйтесь директивой Edit/Sheet/Rename или дважды щелкните мышью на корешке модуля. Для объявления глобальных переменных модуля как частных используйте в заголовке модуля оператор Private, а не Dim. Таким образом, вы защитите все данные объекта от доступа внешних процедур. Единственным способом доступа к данным, сохраненным в модуле, является доступ к его свойствам и методам. Любые процедуры, входящие в состав этого модуля, могут использоваться только процедурами, входящими в его состав, и также должны быть объявлены как частные. Кроме того, в заголовок процедуры можно поместить оператор Option Private Module, что сделает свойства и методы данного объекта доступными только из текущего проекта, но не из модулей и процедур, не входящих в данный проект. 78 VBA for EXCEL Создание пользовательских свойств Свойства создаются с помощью процедур Property. Существуют три типа указанных процедур: Property Let, Property Get, Property Set. Процедуры Property Let управляют вводом данных в объект, что определяет эти свойства как получающие данные. Эти процедуры появляются в правой части формул. Процедуры Property Get управляют выводом данных из объекта и появляются в правой части формул. Процедуры Property Let и Property Get могут иметь одно и то же имя. В этом случае выбор используемой процедуры определяется направлением передачи данных. Процедуры Property Set подобны процедурам Property Let, но передают не значения, а объекты. Использование процедуре Property Get с результатом, объявленным как Object, позволяет передавать объекты из пользовательского объекта. Процедуры Property Let Процедуры Property Let позволяют присваивать свойствам значения. С помощью этих процедур можно создавать свойства, получающие и накапливающие данные. Свойства, объявленные процедурами Property Let, всегда появляются в левой части формулы и могут получать значения, являющиеся результатом вычислений по данной формуле. Объявление процедуры Property Let в основном идентично объявлению подпрограммы, с тем отличием, что вам следует использовать зарезервированные слова Property Let вместо Sub. Процедура Property Let имеет следующий синтаксис: 79 VBA for EXCEL Property Let имя_свойства (аргументы) ‘ Некоторые операторы. Exit Property ‘ Другие операторы. End Property Имя процедуры имя_свойства является именем свойства; для указания контейнера данного свойства используется имя модуля, содержащего эту процедуру. В списке аргументов должен быть хотя бы один аргумент, позволяющий получить значение данного свойства. Если у вас несколько аргументов, то самый правый из них предназначен для получения значения данного свойства. Любые другие аргументы передаются заключенными в круглые скобки и подключенными к имени свойства. В зависимости от ваших потребностей синтаксис данной процедуры может быть расширен (более подробную информацию можно посмотреть в интерактивной подсказке). Например, следующая процедура, находящаяся в модуле BankAccount, объявляет свойство Deposit: Property Let Deposit (ByVal Received As Currency) Index = Index + 1 theDeposit (Index) = Received End Property Чтобы использовать это свойство в другой процедуре, применяют оператор подобный следующему: BankAccount.Deposit =250 В результате выполнения данного оператора число 250 будет передано процедуре Deposit, которая сохранит его в переменной Received. Обратите 80 VBA for EXCEL внимание на то, что эти свойства не требуют использования литеральных значений (вроде 250), - вместо этого можно использовать любую переменную или формулу, позволяющую рассчитать значение данного свойства. Обратите внимание также на то, что данный аргумент объявлен как ByVal, следовательно, данные, переданные процедуре, были скопированы, что защитило переменную в вызывающей процедуре от изменений. Процедура Deposit наращивает глобальную переменную Index и сохраняет переданный депозит в глобальном массиве theDeposit. Чтобы изменить значение предыдущего депозита, нужно создать другую процедуру, принимающую кроме нового значения депозита еще и индекс, который указывает на то, какой из депозитов должен быть изменен. Вы можете написать эту процедуру так: Property Let Deposits (anIndex As Long, ByVal Received As Currency) the Deposit (anIndex) = Received End Property Чтобы использовать данное свойство в операторе можно написать нечто подобное: BankAccount.Deposits (10) = 250 Этот оператор передает переменной anIndex значение 10, а переменной Received – значение 250. Затем эти две переменные используются для изменения значения десятого элемента массива в theDeposit(). Процедуры Property Get Процедуры Property Get представляют собой дополнение процедур Property Let. Они предназначены для передачи данных из объекта. Синтаксис процедур 81 VBA for EXCEL Property Get в основном идентичен синтаксису функций, в которых данные передаются из функции в ее имени: Property Get имя_свойства (аргументы) As тип ‘ Некоторые операторы. Exit Property ‘ Другие операторы. End Property Аргументы и тип имеет те же значения, что и для функции. Так же, как и функции, оператор в теле данной процедуры должен присвоить передаваемое значение переменной, имя которой является именем процедуры. Именно это значение процедура и вернет вызывающей программе. Обратите внимание на то, что аргументы передаются процедуре, а результат возвращается в имени процедуры в качестве значения процедуры в качестве значения свойства. Так процедура Property Get Balance () As Currency Balance = theBalance End Property возвращает значение остатка на счете из объекта CheckBook. Для доступа к этой процедуре из другой процедуры можно использовать оператор CashAvail = CheckBook.Bakance 82 VBA for EXCEL После вызова процедуры Balance текущее значение остатка на счете будут присвоено имени процедуры, а затем передано переменной CashAvail вызывающей программы. Процедуры Property Let и Property Get могут иметь одно и тоже имя, что позволит указать процедур, обменивающуюся данными в обоих направлениях. Поскольку значения свойства Balance обычно является вычисляемой величиной, то это свойство имеет лишь одну процедуру Property Get, определяющую это свойство как доступное только для чтения. Свойство Deposits может как читаться, так и измениться, а следовательно имеет кроме описанной выше процедуры Property Let и соответствующую процедуру Property Get: Property Get Deposits (anIndex As Long) As Currency Deposits = theDeposit (anIndex) End Property Для использования данного свойства может применяться оператор: aDeposit = BankAccount.Deposits (10) Этот оператор, позволяет значение десятого депозита и присвоить его переменной aDeposit. Процедуры Property Let и Property Get можно использовать в одной формуле. В этом случае Visual Basic определяет порядок вызова процедур, задавая, таким образом, направление передачи данных. Например, оператор BankAccount.Deposits (27) = BankAccount.Deposits (27) + 125 позволяет добавить к двадцать седьмому депозиту 125. Этот оператор в начале вызывает процедуру Property Get для получения предыдущего значения данного 83 VBA for EXCEL депозита, затем добавляет к этому значению 125, после чего передает новое значение процедуре Property Let, которая сохраняет это новое значение в объекте BankAccount. Процедуры Property Set Процедуры Property Set в основном идентичны процедурам Property Let, за исключением того, что передают объекты, а не значения. Процедура Property Set имеет следующий синтаксис: Property Set имя_свойства (аргуметы) ‘ Некоторые операторы. Exit Property ‘ Другие операторы. End Property Список аргументов аналогичен списку в процедуре Property Let. Самый правый аргумент предназна для получения объекта от вызывающей процедуры и должен быть типа Variant или объявлен As Object. Все остальные аргументы переедаются самой процедуре. Например, объект CheckBook может отображать список операций в таблице. Чтобы выполнить указанные действия объект в начале должен получить количество операций, которые перечислены в списке, а затем – объектную ссылку на область ячеек таблицы. Для того чтобы подготовиться к печати этого списка можно написать процедуру подобную процедуре Property Set PrintRange (startIndex As Long, numTrans As Long, - aPrintRange As Object) theStartIndex = startIndex theNumTrans = numTrans Set thePrintRange = aPrintRange 84 VBA for EXCEL End Property Обратите внимание на использование сохраняющего Set, объект aPrintRange в переменной объектного типа в thePrintRange. Эта процедура могла бы и сама сформировать такой список, однако вы можете создать метод, формирующий этот список, используя данные, которые переданы этой процедуре. Для вызова указанной процедуры можно использовать оператор подобный следующему: CheckBook.PrintRange (12, 10) = Sheets (“Sheet1”)/Range (“B5”) В этом операторе переменной startIndex передается значение 12, переменной numTrans – 10, а ссылка на область В5 таблицы Sheet1 передается как объект aPrintRange. Эти три значения сохраняются в глобальных переменных процедуры Property Set. Для возврата объекта вызвавшей программе используется процедура Property Get, в которой возвращаемое значение задано типа Object. КОММУНИКАЦИИ Технология DDE Что такое DDE ? Динамический обмен данными, или DDE,обеспечивает простейший канал передачи сообщений между двумя программами ,работающими под управлением Windows. Канал DDE - это связь, служащая для передачи информации. Обычно по этому каналу передаётся текст, но некоторые программы могут передавать 85 VBA for EXCEL также графику. В Visual Basic for Application по каналу DDE может передаваться только текст или числа. Во всех коммуникациях на базе DDE участвуют две программы: сервер DDE и клиент DDE. Сервер DDE - это программа , содержащая данные, которые необходимы программе-клиенту. Программа-клиент инициирует обмен по коммуникации на базе DDE , запросив данные от сервера. Обычно информация направляется от сервера к клиенту. Однако существуют директивы DDE, позволяющие передавать данные и от клиента к серверу. Кроме того, данные, посылаемые серверу, могут быть директивами, которые указывают серверу на необходимость выполнить некоторые действия, например открыть файл. Следует воздерживаться может зациклиться. устанавливать двухстороннюю связь, система Связи DDE работают в двух "температурных" режимах - горячем и холодном. Горячие связи DDE автоматически обновляют данные клиента при изменении связанных данных на сервере. Холодные связи обновляют данные только в том случае, когда серверу посылается директива DDERequest. Visual Basic for Application автоматически управляет только холодными связями. Горячие связи необходимо организовывать программным путём. Применение DDE. Чтобы использовать DDE , вначале нужно установить коммуникационный канал между двумя программами. Чтобы установить этот канал и определить, что будет по нему передаваться, потребуются 3 элемента информации: программа, тема и элемент. Значение этих 3 элементов зависит от той программы , с помощью которой вы пытаетесь осуществить коммуникацию, и используемых этой программой способов обработки данных. Программа - это имя программы-сервера , с которой вы хотите связаться. Программы , подлежащие DDE, зарегистрированы в операционной системе 86 VBA for EXCEL Windows. Имя такой программы не обязательно является тем именем , которое отображается в окне Program Manager. Имена программ, зарегистрированных в системе Windows, приведены в табл. Таблица. Зарегестрированые имена программ, поддерживающих DDE Программа Word for Windows Зарегистрированное имя WinWord Excel Excel Project Project Access MSAccess FoxPro FoxPro Windows Program Manager ProgMan Visual Basic for Windows имя_программы* *Для интерпретированной программы имя_программы является именем окна Project этой программы ; для компилированной программы имя_программы - это имя исполняемого файла без расширения .EXE. Тема - это имя документа , содержащего необходимые данные, а элемент - некий логический элемент этого документа . Для Excel тема - это имя таблицы, а элемент - область ячеек. Для программы на Visual Basic for Windows тема - это имя бланка, а элемент - элемент управления в этом бланке , содержащий необходимые данные . Для Word тема - это имя документа , а элемент - либо закладка , либо селектор Word Basic вроде \ StartOfDoc, указывающий на начало документа (Word Basic это встроенная в текущую версию Word средство программирования на Basic). Для получения перечня всех возможных тем и элементов обратитесь к документации на программу , которую вы хотите использовать, или посмотрите интерактивную подсказку данной программы. 87 VBA for EXCEL Открытие коммуникационного канала DDE. Чтобы открыть канал DDE с другой программой , эта программа в первую очередь должна быть запущена. Для запуска используйте операторы Shell и AppActivate. Будьте осторожны при использовании оператора Shell: эта команда запускает программу не синхронно и следующий оператор вашей программы может выполниться прежде , чем начнёт работать вторая программа. После команды Shell потребуется пауза , которая позволит пропустить время инициализации и старта указанной программы. Для инициализации связи между двумя выполняющимися программами используется метод DDEIniate, который имеет следующий синтаксис: канал = DDEInitiate(программа, тема) Аргументы программа и тема являются строками. Чтобы определить, какие значения аргументов используются, обратитесь к документации на программу. Этот метод возвращает номер канала, используемый в других командах Visual Basic для идентификации данного коммуникационного канала. При выполнении метода устанавливается соединение DDE между Visual Basic for Applications и другой программой. Закрытие канала DDE. После завершения использования канала DDE его необходимо закрыть с помощью метода DDETerminate, имеющего следующий синтаксис: DDETerminate(канал) 88 VBA for EXCEL В данном случае канал - это номер канала, полученный от метода DDEInitiate. Получение информации от сервера. Чтобы запросить данные от сервера по открытому коммуникационному каналу, используется метод DDERequest, имеющий следующий синтаксис: Переменная = DDERequest(канал, элемент) Аргумент канал является номером канала , возвращённым методом DDEInitiate, а элемент указывает на определённую часть необходимых данных. Переменная представляет собой имя переменной, принимающей указанные данные. Эта переменная должна быть типа Variant. В качестве примера создайте в Excel страницу диалога, которая использует DDE для получения строки текста из Word. В Word выделите предложение , укажите директиву Edit/Bookmark и назовите полученную закладку BookMark1. Затем переключитесь в Excel и запишите в модуле три приведённые ниже процедуры . Замените в этих процедурах ссылку на документ 26VBAOR.DOC ссылкой на один из ваших документов. Option Explicit Dim ChannelNum As Integer Dim Results ‘ ‘Установление связи DDE с Word и получение предложения. ‘ Sub OpenChannel() ‘Запуск Word и открытие документа 26VBAOR.DOC 89 VBA for EXCEL ‘Замените имя документа и путь на атрибуты одного из ваших документов ‘ ChannelNum = DDEInitiate (“WinWord”, “I:\BHV_VBA\26BAOR.DOC”) ‘Отображение номера канала в диалоговом окне. DialogSheets(“DDEDialog”).EditBoxes(“DDEChannelBox”).Text = _ChannelNum End Sub ‘ ‘Получение данных. ‘ Sub GetData() Results = DDERequest (ChannelNum, “BookMark1”) ‘Запрос данных. ‘Отображение данных в диалоговом окне. DialogSheets (“DDEDialog”). EditBoxes (“DDEDataBox”). Text = Results End Sub ‘ ‘Закрытие связи. ‘ Sub CloseChannel ( ) DDETerminate (ChannelNum) End Sub Создайте страницу диалога, назовите её DDEDialog; добавьте к ней три командные кнопки, две метки и два текстовых окна. Назовите текстовое окно, расположенное под меткой «Результат», DDEDataBox, а второе текстовое окно – DDEChannelBox. Для подключения командной кнопки “Открыть DDE” к процедуре OpenChannel, командной кнопки “Принять данные” – к процедуре GetData и командной кнопки “Закрыть DDE” – к процедуре CloseChannel используйте директиву Tools/Assign Macro. 90 VBA for EXCEL На пиктографическом меню Forms нажмите пиктограмму Run Dialog, затем на бланке нажмите командную кнопку “Открыть DDE”. Нажатие этой кнопки инициирует выполнение процедуры OpenChannel, которая открывает канал к программе Word for Windows (WinWord), затем запрашивает документ 26BAOR.DOC и отображает номер канала в окне DDEChannelBox. Нажатие командной кнопки “Принять данные” инициирует выполнение процедуры GetData, запрашивающей содержимое закладки BookMark1. Если текст закладки будет обнаружен, то он отобразится в окне DDEData. С Для закрытия канала DDE нажмите командную кнопку “Закрыть DDE”. Передача информации серверу. Чтобы послать информацию серверу, используется метод DDEPoke. Этот метод имеет следующий синтаксис: DDEPoke (канал, элемент, данные) Аргумент элемент указывает текст на сервере , который подлежит замене, а аргумент данные содержит текст, заменяющий текст на сервере. Единственной проблемой при использовании этого метода является то, что аргумент данные должен быть областью таблицы и не может быть простой строкой. Возможно, в будущих версиях Excel эта проблема будет устранена. Для примера, добавьте процедуру, посылающую программе Word некоторый текст, который заменяет текст, маркированный как закладка BookMark1. Вначале добавьте к бланку командную кнопку “Послать данные”. Затем подключите эту кнопку к следующей процедуре: ‘ ‘Пересылка данных. ‘ 91 VBA for EXCEL Sub PokeChannel ( ) ‘Копирование данных из диалогового окна в ячейку таблицы. Sheets (“Sheet1”). Cells(1, 1). Formula = _ DialogSheets(“DDEDialog”) . EditBoxes(“DDEDataBox”). Text ‘Создание ссылки на ячейку таблицы. Set Result = Sheets(“Sheet1”). Cells(1, 1) ‘Пересылка ссылки на ячейку связанной программе для замены текста, маркированного как ‘BookMark1. Application.DDEPoke ChannelNum, “BookMark1”, Result End Sub На пиктографическом меню Forms нажмите пиктограмму Run Dialog, затем на бланке нажмите командную кнопку “Открыть DDE” для подключения к Word. Для копирования текущего содержимого закладки BookMark1 в текстовое окно “Результат” нажмите командную кнопку “Принять данные”. В верхней части экрана расположено окно Word for Windows , на котором видна строка текста, маркированная как BookMark1. В нижней части экрана расположено окно Excel с диалоговым окном “Тестер DDE ” , на котором в текстовом окне “Результат” виден тот же текст. Теперь текст находящийся в приемном окне "Результат" можно редактировать. Чтобы этот отредактированный текст заменилзаменил собой текст , маркированый как BookMark1 ,нажмите кнопку "Послать данные". Процедура PokeChannel1 сначала копирует содержимое текстового окна в ячейку А1 таблицы Sheet1 . Затем это значение загружается как объект в переменную Result. Запомните , что метод DDEPoke должен должен получить в качестве в качестве аргумента не строку , а ссылку на область ячеек , содержащих этот текст . Затем метод DDEPoke передаёт этот текст в Word , где он заменяет собой текст , 92 VBA for EXCEL маркированный как BookMark1 . Для закрытия связи нажмите командную кнопку "Закрыть DDE". Передача директив серверу. Кроме передачи программе некотрох данных , связь DDE позволяет предать и директивы. Дитективы , которые вы хотите передать прогремме , должны быть на командном языке той программы , которой вы их передаёте. Чтобы передать директивы подключённой программе , используется метод DDEExecute , имеющий следующий синтаксис : DDEExecute ( канал , командная_строка) Аргумент канал является номером канала DDE , а аргумент командная_строка строкой, содержащей директиву для подключенной программы. Перешлите программе Word директиву File/Print Preveiw. Для этого добавьте кдиалоговому окну "Тестер DDE" командную кнопку "ПредПросмотр" и подключите ее к следующей процедуре: Sub PreveiwIt () ' Пересылка связанной програме директивы предварительного просмотра. DDExecute ChannelNum , "[FilePrintPreview]" End Sub. Обратите внимание на то , что директива FilePrintPreview заключена в квадратные скобки . Если вы опустите скобки , то Word вставит эту директиву как текст в точку вставки а не выполнит её как директиву. Технология OLE 93 VBA for EXCEL OLE имеет значительно больше возможностей, чем DDE. Если DDE просто обеспечивает обмен данными между программами, то OLE позволяет передавать объекты. Существуют 2 различных типа OLE: Linking and Embedding (Связь и внедрение) и OLE Automation(Автоматизация OLE). С помощью Linking and Embedding вы внедряете объекты одной программы в документы другой. Внедряемые объекты создаются копированием объекта в одной программе, а затем вклеиванием связи с этим объектом в другую программу. После этого объект можно редактировать в породившей его программе. Программа, отображая внедренный объект, не должна ничего знать о том, как он создается и ли изменяется, - она только отображает этот объект. OLE Automation позволяет одному объекту управлять другой программой посредством доступа к ее объектам и методам. При использовании OLE Automation Объекты и методы подключенной программы становятся расширением языка Visual Basic. Применение OLE Automation Прежде чем использовать объекты и методы другой программы, вы должны все узнать об этих объектах. Если данная программа содержит библиотеку объектов, зарегистрированную в системе и доступную, вы можете использовать Object Browser для ознакомления с объектами и методами, включенными в эту библиотеку. Если программа не разрешает доступ к библиотеке, то вы должны обратится к документации на программу - чтобы ознакомится с доступными объектами и методами. Для получения объектов программы с помощью Object Browser необходимо зарегистрировать эту программу в Excell. Вначале укажите директиву Tools/ References для отображения диалогового окна References. Затем включите контрольный индикатор, соответствующий данной программе, в окне списка Avalaible References. После того, как программа зарегистрирована, все ее объекты становятся доступными Visual Basic. 94 VBA for EXCEL Теперь вы можете использовать Object Browser для изучения объектов другой программы. Кроме того, Object Browser отображает имя, под которым зарегестрирована в системе данная программа. Предупреждение Имя, используемое в целях регистрации программы для коммуникаций OLE, отличается от имени используемого для DDE. Это объясняется тем, что связывается OLE с программой, а DDE - с объектами из библиотеки ee oбъектов. Объекты другой программы могут иметь те же имена, что и объекты в вашей программе; следовательно, для доступа надежнее пользоваться полными именами. Например если вы запустите MS Excell VBA и выполните оператор APPlication.Name то получите имя Excell. Но если вы выполните оператор Msproject. APPlication.Name то получите имя Project. Для доступа к любому объекту, находящемуся вне текущей программы, используете полную ссылку, что не только даст возможность уверенно получить нужный объект, но и повысить читабельность вашей программы. Создание и открытие объектов. Для программ, управляемых посредством OLE Automation , существуют 2 метода создания новых объектов или открытия уже существующих объектов: Createobject() и GetObject(). В общем случае объектами, к которым вы получаете доступ с помощью указанных методов, являются документы подключенных программ. Для полностью OLE - согласованных программ, таких как Excell, открытие или создание новых файлов осуществляется методами связанных объектов а не методами Create object() и GetObject(). Для частично OLE согласованных программ вроде Word обеспечивается с помощью методов. Метод Createobject имеет синтаксис 95 создание связей с документами VBA for EXCEL Set объектная_переменная = Createobject(класс) где объектная_переменная представляет собой любую переменную типa Object или Variant, а класс является классом создаваемого объекта. Аргумент класс состоит из двух частей, разделенных точкой: Регистрационное_Имя.Объект где Регистрационное_Имя - имя под которым программа зарегестрирована в системе, а Объект - тип создаваемого объекта. Для Excell тип объекта может принимать значения Application, Sheets и Charts, для Word - Basic. Так следующий оператор запускает Excell и создает новую таблицу: Set Xlsheet = createObject(«Excell.Sheet») Если Excell уже запущен и рабочая папка уже открыта, то оператор добавит новую таблицу к открытой рабочей папке. Если Excell не запущен, то оператор запускает Excell с новой рабочей папкой. Следующий оператор запускает Word и возвращает объект, на который можно ссылаться как на Word Basic: Set WordSheet = createObject(«Word.Basic») Примечание: Поскольку программа Word не полностью OLE - согласованна, то ссылкой является Word Basic, а не конкретный документ. Word Basic встроен в Word средством программирования на . Большинство директив Word Basic доступны связанной программе. Эти директивы пересылаются программе Word как методы объекта Word Basic. Фактически Word интерпретирует эти директивы, применяя их к текущему документу как к объекту. Метод GetObject открывает существующий объект. Метод имеет синтаксис: Set объектная_переменная = GetObject(Имя_файла,класс) где объектная_переменная и класс имеют те же значения что и для метода. Имя_файла - путь и имя файла для открытия объекта. Если расширение файла позволяет определить класс объекта, то аргумент класс можно опустить. Метод не запускает программу если она не запущена на момент выполнения метода. 96 VBA for EXCEL Например следующий оператор открывает таблицу COST.XLS в директории PROJ диска D: Set Xlsheet = GetObject(«D:\PROJ\COST.XLS», «Excell.Sheet») Примечание : Экспериментируя с объектами OLE и программами, вы можете столкнуться с одной проблемой - разрушение системы. При проверке вашей новой программы вы будете сталкиваться с ее крахом до тех пор пока не устраните последнюю ошибку. Каждый из этих крахов будет оставлять связь, которая будет мешать корректной работе системы. В таком случае дальнейшая работа Windows будет невозможной и придется перегрузить Windows для устранения путаницы. Примечание : Поскольку связи OLE подвержены ошибкам, вы должны уметь определять, какая из процедур обработки ошибок необходима для предотвращения вашей программы из-за ошибок связи OLE. Процедура обработки ошибок может попробовать повторно установить связь или завершить процедуру - в зависимости от того, какая директива явилась причиной ошибки. Если вы попытаетесь установить связь повторно, то используйте счетчик, который позволит избежать зацикливания. 97