Глава 5 Использование ADO
Понятие ADO
ADO (Microsoft ActiveX Data Objects) — это набор библиотек, содержащих COM-объекты. Основное их назначение — реализация прикладного программного интерфейса для доступа к базам данных и использование в клиентских приложениях. ADO использует библиотеки OLE DB, предоставляющие низкоуровневый интерфейс для доступа к данным. OLE DB, со своей стороны, обеспечивают доступ к данным с помощью СОМ-интерфейсов.
OLE DB и ADO являются частью универсального механизма доступа к данным Microsoft (Microsoft Universal Data Access), который обеспечивает высокопроизводительный доступ к различным источникам информации (включая реляционные и нереляционные базы данных), в том числе к данным, хранящимся на мэйнфреймах, данным электронной почты и файловой системы, текстовым, графическим и др. Для многих современных приложений, которые используют различную информацию, характерно подобное разнообразие ее источников. Более того, вполне очевидно, что могут появляться новые форматы данных и способы их хранения. Поэтому разумным требованием к универсальному механизму доступа к ним могла бы стать возможность поддержки не только существующих в настоящее время их форматов и источников, но и форматов данных, которые будут созданы в будущем.
Назначение универсального механизма доступа к данным фирмы Microsoft — предоставить доступ к перечисленным их источникам с помощью единой модели доступа.
Рассмотрим основные компоненты архитектуры универсального механизма доступа к данным Microsoft и обсудим их более детально.
О Microsoft ActiveX Data Objects (ADO) — представляет собой программный интерфейс для доступа к данным из приложений. С точки зрения программирования, ADO и его расширения являются упрощенным высокоуровневым объектно-ориентированным интерфейсом к OLE DB.
П OLE DB — это низкоуровневый интерфейс для доступа к данным. ADO применяет OLE DB, но можно использовать OLE DB и напрямую, минуя ADO.
? Open Database Connectivity (ODBC) — стандартный способ доступа к реляционным базам данных. Этот компонент универсального механизма доступа оставлен с целью обеспечения совместимости с прежними версиями программного обеспечения. В современных приложениях применению ODBC-драйверов предпочитают использование OLE DB-провайдеров.
Для доступа к источнику данных с помощью OLE DB требуется, чтобы на компьютере, где используется клиентское приложение, был установлен OLE DB-провайдер для данной СУБД. OLE DB-провайдер представляет собой динамическую библиотеку DLL, загружаемую в адресное пространство клиентского приложения и используемую для доступа к источнику данных. Для каждого типа СУБД нужен собственный OLE DB-провайдер, так как провайдеры базируются на функциях клиентских API (Application Programming Interface, программный интерфейс приложения), разных для различных СУБД.
ADO представляет собой высокоуровневый программный интерфейс для доступа к OLE DB-интерфейсам. Он позволяет манипулировать данными с помощью любых OLE DB-провайдеров, входящих как в состав Microsoft Data Access Components, так и в состав программных продуктов, разработанных сторонними производителями. ADO содержит набор объектов, используемых для соединения с источником информации с целью чтения, добавления, удаления или модификации предоставляемых им данных.
П Объект connection применяется для установки связи с источником данных. Он представляет единственную сессию. Этот объект позволяет изменить параметры соединения с базой данных, а также начать или завершить транзакцию. Используя объект connection, можно выполнять команды (например, SQL-запросы) с помощью метода Execute. Если команда возвращает набор данных, то автоматически создается объект Recordset, который возвращается в результате выполнения этого метода.
П Объект Error используется для получения сведений об ошибках, возникающих в процессе выполнения приложения.
П Объект command представляет собой команду, которую можно выполнить в источнике данных. Команда может содержать SQL-предложение или вызов хранимой процедуры. В последнем случае для определения параметров процедуры может быть использована коллекция Parameters объекта Command.
П Объект Recordset — это набор записей, полученных из источника данных, и может быть использован для добавления, удаления, изменения, просмотра записей. Данный объект может быть открыт непосредственно ИЛИ создан С ПОМОЩЬЮ объектов Connection ИЛИ Command.
? Объект Field — это колонка в наборе данных, представленных объектом Recordset. Объект может быть использован для получения значений конкретного поля таблицы, его модификации, извлечения метаданных, таких как имя колонки и тип данных.
О Объект Record — представляет одну запись внутри объекта Recordset и может быть использован для работы с гетерогенными и иерархическими данными (добавлен в библиотеку ADO 2.5, являющуюся составной частью операционной системы Windows 2000).
? Объект stream представляет двоичные данные, связанные с объектом Record. Например, если объект Record представляет собой файл, то его объект stream должен содержать данные внутри этого файла (добавлен в ADO 2.5).
Соединение с источником данных
Для установки связи с источником данных используется объект Connection. Рассмотрим два варианта создания соединения — явного (листинг 5.1) и неявного (листинг 5.2).
Шинг 5.1. Создание явного соединения
// Создание объекта установки связи с источником данных Connection = Новый СОМОбъект("ADODB.Connection");
// Подключение к источнику данных Попытка
Connection.Open(СтрокаПодключения);
Исключение
Сообщить(ОписаниеОшибки()) ;
Возврат;
КонецПопытки;
// Создание объекта выполнения команды Command = Новый СОМОбъект("ADODB.Command");
// Указание активного соединения
Command.ActiveConnection = Connection,-
// Определение текста команды
Command.CommandText = "SELECT * FROM titles";
// Определение типа команды
Command.CommandType = 1;
// Создание объекта набора записей
RecordSet - Новый СОМОбъект("ADODB.RecordSet"};
// Выполнение и получение набора данных
RecordSet = Command.Execute();
// Перебор данных
Пока RecordSet.EOF() = 0 Цикл
Сообщить(RecordSet.Fields(0).Value);
RecordSet.MoveNext();
КонецЦикла; ¦
// После того как набор записей уже не нужен, его следует закрыть
RecordSet.Close();
Connection.Close();
і Листинг 5.2. Создание неявного соединения
// Создание объекта выполнения команды
Command = Новый СОМОбъект{"ADODB.Command");
// Указание активного соединения без использования объекта Connection
Command.ActiveConnection = СтрокаПодключения;
// Определение текста команды
Command. CommandText = "SELECT * FROM titles";
// Определение типа команд Command.CommandType = 1;
// Создание объекта набора записей
RecordSet = Новый СОМОбъект("ADODB.RecordSet");
/ / Выполнение и получение набора данных
RecordSet.Open(Command);
/ / Перебор данных
Пока RecordSet.EOF() = 0 Цикл
Сообщить(RecordSet.Fields(0).Value);
RecordSet.MoveNext();
КонецЦикла;
II После того как набор записей уже не нужен, его следует закрыть
RecordSet.Close () ;
Connection.Close();
Из приведенных примеров видно, что основное отличие явн о го соединения от неявного заключается в том, что в последнем случае не используется объект Connection. Для получения более структурированного и понятного кода рекомендуется использовать явное соединение.
В обоих примерах для описания источника данных использовалась строковая переменная Строкаподключения. Значение данной переменной можно формировать вручную, либо с помощью программы связи с данными. Программа связи с данными используется для создания и управления подключениями между локальным компьютером и хранилищами данных OLE DB. Запустить программу связи с данными можно двумя способами — вручную и программно.
 |
Рис. Диалог программы связи сданными |
Для ручного запуска достаточно создать пустой текстовый файл с расширением UDL и в любом файловом менеджере запустить его. Этом случае откроется диалог (рис. 5.1), в котором настраиваются параметры соединения, а после нажатия кнопки ОК сформировавшаяся строка соединения запишется в созданный UDL-файл.
Пример программного запуска утилиты настройки связи с данными приведен в листинге 5.3.
j Листинг 5.3. Запуск программы Ьвязи с данными |
// Программа для формирования и редактирования строки соединения
DataLinks = Новый СОМОбъект("DataLinks");
// Объекту Connection устанавливаем введенное значение строки соединения
Connection.Connectionstring = СтрокаПодключения,-// Открываем диалог программы связи с данными DataLinks.PromptEdit(Connection);
// Возвращаем новое значение строки соединения СтрокаПодключения = Connection.Connectionstring;
Сообщить(СтрокаПодключения);
Важно отметить, что при программном запуске утилиты связи с данными все манипуляции со строкой соединения происходят через объект Connection. Данная особенность еще раз говорит в пользу того, что лучше использовать явное соединение с источником данных (см. листинг 5.1).
Например, для доступа к базе данных Microsoft SQL Server строка соединения будет выглядеть следующим образом:
''Provider=SQLOLEDB.l; Password=erpg; Persist Security Info=True; User ID=mav; Initial Catalog=Northwind; Data Source=MAVCOMP"
Если же строка соединения записана во внешнем UDL-файле, то строка соединения будет выглядеть иначе:
"File Name=C:\DataLinks\MyDataLink.udl"
Рассмотрим основные свойства строки соединения.
П Provider — названия поставщика OLE DB.
? User ID — имя пользователя.
О Password — пароль пользователя.
О Persist Security Info — признак сохранения пароля в строке соединения (True/False).
? Initial Catalog — используемая база данных.
? Data Source — название источника данных (например, имя сервера, имя файла и т. п.);
П File Name — полное имя UDL-файла.
Все остальные свойства зависят от конкретного OLE DB-провайдера.
Продолжая рассматривать пример, приведенный в листинге 5,1, стоит остановиться на объекте connection. Это самый важный объект ADO, отвечающий за связь между приложением и базой данных. У него очень много методов и свойств, и одно из них, connectionstring, описанное ранее. Оно определяет собственно строку инициализации ODBC-соединения.
Рассмотрим основные свойства объекта Connection.
О connectionTimeout — задает время в секундах, в течение которого ожидается установление ODBC-соединения. По умолчанию равно 15. Конкретное значение имеет смысл устанавливать в том случае, когда сервер, вследствие своей загруженности или высокого трафика, не успевает обрабатывать запросы. Если установить значение равное 0, то сервер будет ждать установления соединения бесконечно долго.
П commandTimeout — задает время в секундах, в течение которого ожидается исполнение запросов. По умолчанию равно 30.
О Connectionstring — строка инициализации ODBC-соединения.
П DefaultDatabase — база данных по умолчанию для данного соединения.
П state — определяет состояние соединения (о — закрыто, 1 — открыто). Рассмотрим основные методы объекта Connection.
П open — метод открывает доступ к базе данных и имеет три необязательных параметра:
• Connectionstring — строка соединения с источником данных, причем если параметр connectionstring не задан, то используется свойство connection.Connectionstring;
• UserlD — имя пользователя;
• Password — пароль (обычноUserlD и Password задаются непосредственно в Connectionstring, поэтому их можно не задавать).
П close — разрывает связь с базой данных, при этом закрываются также все объекты типа Recordset, связанные с данным объектом, однако память, отведенная под объект connection, не освобождается, т. е. в дальнейшем можно снова выполнить команду open для повторного доступа к базе данных.
? Execute — метод исполняет SQL-запрос или хранимую процедуру и возвращает объект типа Recordset, причем возможно задание трех параметров:
• cominantText — строка, содержащая SQL-запрос, имя таблицы, хранимой процедуры или прочий исполняемый текст;
• RecordsAffected — переменная, в которую возвращается количество записей в результате исполнения запроса;
• options — определяет тип параметраCommandText (полезен для оптимизации исполнения запроса) и может иметь значения:
О 1 — SQL-запрос или другое текстовое выражение;
О 2 — таблица;
О 4 — хранимая процедура;
О 8 — тип параметра неизвестен.
Примечание
Важно отметить, что объект Recordset, созданный с помощью этого метода, доступен только для чтения и его сканирование может производиться только вперед по записям. Для того чтобы иметь возможность вставлять или изменять записи, а также двигаться вперед и назад по ним, необходимо непосредственно создать этот объект и задать некоторые его свойства до исполнения соответствующего запроса.
Выполнение SQL-запросов и хранимых процедур
Ранее было сказано, что выполнить SQL-запрос или хранимую процедуру можно с помощью метода Execute объекта Connection, но наиболее правильно для этих целей использовать специализированный объект — command. Это связано с тем, что объект command специально предназначен для обработки параметров SQL-операторов, а также хранимых процедур и при возврате объекта Recordset минимизирует количество информации, которой обмениваются поставщик данных и приложение.
Объект Command описывает команду (запрос или оператор), которая обрабатывается источником данных. Благодаря этому объекту обеспечивается простота и эффективность работы с запросами или хранимыми процедурами. С помощью объекта command можно определить SQL-строку, хранимую процедуру или имя таблицы.
Как и многие другие объекты модели ADO, объект command может быть создан либо с помощью объекта Connection (листинг 5.1), либо независимо от него (листинг 5.2).
После того как объект command будет создан и подключен к поставщику данных, его можно использовать для выполнения процедур и SQL-операторов, которые будут либо воздействовать на данные в источнике данных, либо возвращать объект Recordset.
193
Рассмотрим пример добавления новой записи в таблицу базы данных (листинг 5.4).
Листинг 5.4. Добавление новой записи в таблицу базы данных
НИНМННИИННННННННННИННННИННІЯНННЯЯНННННННІННЯННЯНННННННННІ
ТекстЗапроса'= "
I INSERT
I INTO Users(Parantld. IsFolder, FlC
f Login, Password, Description)
I VALUES (" + 2 + "," + 1 + ", '" + Пользователь.Наименование + "','" + Пользователь.Логин + "','pass','Произвольное описание')";
Command = СоздатьОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = ТекстЗапроса;
Command.CommandType = 1;
// Выполнение запроса
RecordSet = Command.Execute();
Примечание
Отдельно на тексте запроса останавливаться не будем, так как подразумевается, что читатель знаком с языком SQL
Рассмотрим основные свойства объекта Command.
? ActiveConnection — данное свойство определяет соединение, с которым работает объект Command, и содержит строку, описывающую соединение либо указывающую на открытый в данный момент объект connection. В первом случае создается новое соединение, предназначенное специально для объекта Command и объекта Recordset, который также создается.
? CommandText — это свойство определяет SQL-оператор, имя хранимой процедуры либо имя таблицы, с которой будет работать объект command. Как правило, оно содержит вы зовы хранимых процедур или SQL-операторов, кроме этого может включать и специфические команды, поддерживаемые поставщиком данных.
? Command Timeout — данное свойство предназначено для определения интервала времени ожидания объектом Command результатов обращения к поставщику данных. По истечении этого периода объект command отменяет попытку установить соединение и генерирует сообщение об ошибке. Стандартное значение данного свойства равно 30 секундам. Однако оно может быть и больше, если предполагается, что процесс загрузки данных поставщиком занимает много времени.
О commandType — данное свойство используется для оптимизации процесса обработки объекта command поставщиком данных. При указании конкретного типа команды, определенной свойством CommandText объекта command, поставщик данных освобождается от распознавания типа выполняемой команды. Аналогично аргументу Option метода Execute объекта connection, данное свойство может принимать следующие значения:
• 1 — SQL-запрос или прочее текстовое выражение;
• 2 — таблица;
• 4 — хранимая процедура;
• 8 — тип параметра неизвестен.
О state — свойство возвращает множество значений сумм одной или нескольких констант objectstateEnum. Эти константы описывают — является ли объект Command открыт, закрыт, в соединении и т. п. Возможные значения:
• о — объект закрыт;
• 1 — объект открыт;
• 2 — соединяется;
• 4 — выполняется;
• 8 — выбран.
Рассмотрим основные методы объекта command.
? Execute — метод исполняет SQL-запрос или хранимую процедуру. Возвращает объект типа Recordset.
? CreateParameter — данный метод используется для создания новых объектов Parameter, которые добавляются в семейство Parameters объекта command до того, как будет выполнен запрос. Объект Parameter описывает параметр, передаваемый в SQL-оператор или хранимую процедуру, которая указана В СВОЙСТВе CommandText объекта Command.
Рассмотрим более подробно использование параметров, передаваемых в хранимые процедуры. Для передачи параметров процедуре необходимо выполнить следующие действия.
1. Вызвать метод CreateParameter И создать новый объект Parameter.
2. Добавить Объект В семейство Parameters объекта Command.
3. Воспользовавшись методом Execute объекта command, получить объект Recordset.
Рассмотрим пример выполнения перечисленных действий (листинг 5.5).
і Листинг 5.5. Передача параметров хранимой процедуре
// Создание нового объекта Command Command = Новый СОМОбъект("ADODB.Command");
// Организация связи с поставщиком данных для объекта Command Command.ActiveConnection = Connection;
// Задание хранимой процедуры
Command.CommandText = "SP_GET_AUTHOR_INFO";
// Применение метода CreateParameter объекта Command для // создания нового объекта Parameter, который будет / / использован при выполнении хранимой процедуры.
Parameter = Command,CreateParameteri”@USERNAME", 200, 1, 12, "MAV");
// Добавление в семейство Parameters объекта Command нового параметра Command.Parameters.Append(Parameter);
// Получение объекта Recordset Recordset = Command.Execute();
Метод CreateParameter применяется следующим образом:
CreateParameter(Name, Type, Direction, Size, Value).
Рассмотрим параметры этого метода.
П Name — строковое значение, определяющее имя создаваемого параметра.
? Туре — тип параметра, передаваемого в объект command. Хотя тип значения параметра, передаваемого методу CreateParameter, является вариантным, включение этого необязательного аргумента часто влияет на операцию, выполняемую поставщиком данных. Все возможные значения перечислены в табл. 5.1.
О Direction — если вам не приходилось использовать хранимые процедуры, то вам не известен тот факт, что они могут как принимать параметры, так и возвращать их. Например, если применяется хранимая процедура для вычисления значений, получаемых при обмене валюты, она будет возвращать результат вычислений в выходном параметре. Данный аргумент определяет способ использования параметров хранимой процедуры: для ввода данных, для вывода значений, или же и для того и для другого. Все возможные значения перечислены в табл. 5.2.
П size — если объекту Parameter передаются данные переменной длины, то прежде чем добавить этот объект в семейство Parameters, нужно задать значение его свойства size, иначе произойдет ошибка.
? value — этим аргументом устанавливается значение параметра, передаваемого объекту Connection (ADO позволяет задавать для данного аргу-
мента длинные двоичные значения). Например, если требуется получить значение, возвращаемое хранимой процедурой — необходимо добавить параметр С именем Return: ReturnParameter =
Command. CreateParameter ( "Return", 3, 4 ) • Соответственно результат, возвращенный хранимой процедурой, будет находиться в свойстве BeturnParameter.Value.
Таблица 5.1. Типы параметров, используемые в объектах ADO
Константа ADO
adBiglnt
adBinary
adBoolean
adBSTR
adChar
adCurrency
adDate
adDBDate
adDBTime
adDBTimeStamp
adDecimal
adDouble
adEmpty
adError
adGUID
adIDispatch
adlnteger
adlUnknown
adLongVarBinary
adLongVarChar
Значение Описание
Таблица 5.1 (окончание)
Константа ADO Значение
adVarBinary
Описание
Длинное строковое значение (только для объекта Parameter)
Десятичное число фиксированной точности
Значение одинарной точности с плавающей точкой
2-байтовое целое со знаком
1 -байтовое целое со знаком
8-байтовое целое без знака
4-байтовое целое без знака
2-байтовое целое без знака
1 -байтовое целое без знака
Переменная, определяемая пользователем
Двоичное значение (только для объекта Parameter)
Строковое значение (только для объекта Parameter)
Вариантная переменная OLE-автоматизации
Символьная строка Unicode, заканчивающаяся символом Null (только для объекта Parameter)
Символьная строка Unicode, заканчивающаяся символом Null
Таблица 5.2. Допустимые значения аргумента Direction метода Crea teParameter
КонстантаАРО Значение Описание
adParamUnknown 0
adParamlnput 1
adParamOutput
adParamlnputOutput 3
adParamReturnValue 4
Назначение параметра не определено
Входной параметр (по умолчанию) — используется для передачи информации в хранимую процедуру
Выходной параметр — применяется для получения данных из хранимой процедуры посредством SQL-параметра OUTPUT
Входной и выходной параметр — используется как для передачи информации в хранимую процедуру, так и для получения от нее значений
Возвращаемое значение — применяется для перехвата кода завершения хранимой процедуры
Обращение к результатам запроса
Ранее очень часто встречалось использование объекта Recordset. Объект типа Recordset представляет таблицу — результат запроса к базе данных. Экземпляр объекта создается командой:
Новый СОМОбъект("ADODB,RecordSet"> .
Для перемещения по строкам, или записям, таблицы, объект использует курсор, указывающий на текущую запись. При открытии объекта курсор указывает на самую первую запись. Для удобства работы можно разбивать таблицу на страницы, варьируя их размер. По умолчанию, если не задано свойство CursorType, перемещаться по записям можно только вперед.
Для того чтобы определить список полей таблицы, используется коллекция Fields объекта Recordset. Каждый элемент коллекции представляет собой объект типа Field. Чтобы вывести список полей таблицы, можно использовать следующий код (листинг 5.6).
Листинг 5.6. Вывод списка полей, входящих в Recordset
...___________________................ ...... ____________________
// Создание объекта выполнения команды Command = Новый СОМОбъект("ADODB.Command");
// Указание активного соединения Command. ActiveConnection = Connection;
// Определение текста команды
Command.CommandText = "SELECT * FROM titles”;
// Определение типа команды
Command.CommandType = 1;
// Создание объекта набора записей RecordSet = Новый СОМОбъект ("ADODB. RecordSet") ; // Выполнение и получение набора данных RecordSet = Command.Execute ();
// Перебор полей RecordSet
Для НомерКолонки = 0 По RecordSet.Fields.Count-1 Цикл
Сообщить("Имя колонки” + RecordSet.Fields.Item(НомерКолонки).Name); КонецЦикла; .
Использовать данный прием очень удобно в том случае, когда заранее неизвестен состав полей выборки.
Рассмотрим следующий пример, в котором демонстрируется вывод всех значений полей всех записей, причем состав полей, как и в предыдущем примере, заранее неизвестен (листинг 5.7).
.kLiJ'-CLi
: Листинг 5.7. Выборка результата запроса
// Перебор записей выборки
Количествополей = RecordSet.Fields.Count;
Пока RecordSet,EOF О = 0 Цикл // Перебор полей выборки
Для ПомерКолонки = 0 По КоличествоПолей-1 Цикл
ИмяПоля = RecordSet.Fields.І1;ет.(НомерКол0нки) .Name; Значение = RecordSet.Fields(ИмяПоля).Value;
Сообщить("Поле: " + ИмяПоля + = + Значение);
КонецЦикла;
// Переводим курсор на следующую запись
RecordSet.MoveNext();
КонецЦикла;
Для большего понимания данного примера и возможностей объекта
RecordSet рассмотрим свойства данного объекта.
О ActiveConnection — объект типа Connection, к которому привязан данный Recordset.
О source — строка-источник запроса, т. е. SQL-выражение, имя таблицы или хранимой процедуры.
? Filter — фильтр, т. е. та часть SQL-запроса, которая находится в составе
WHERE.
П CursorType — тип курсора. Значениями свойства, которые можно изменять только до открытия объекта, могут быть:
• о — является значением по умолчанию (Forwardonly-курсор) и позволяет перемещаться только вперед по записям таблицы (является наиболее оптимальным в тех случаях, когда нужно провести лишь единственный проход по записям);
• — определяет подобие динамическому курсору (Keyset-курсор) за исключением того, что вы не можете видеть записи таблицы, добавленные другими пользователями базы данных;
• 2 — позволяет любые перемещения по таблице, а также добавление, изменение и удаление записей, которые видны всем пользователям базы данных (Динамический курсор);
• з — позволяет производить поиск по таблице и создавать отчет (Статический курсор — копия таблицы), причем добавления, изменения и удаления, проведенные другими пользователями, невидимы (полезен, например, при постраничном выводе таблицы с возможностью перемещаться вперед или назад по страницам).
О state — определяет состояние объекта:
• о — закрыт;
• 1 — открыт/
П BOF — логическая величина (истина или ложь). Определяет факт того, что курсор находится перед первой записью таблицы.
П EOF — логическая величина. Определяет, что курсор находится за последней записью таблицы.
П Edi.tMode — определяет состояние редактирования текущей записи (проведен ли метод update для сохранения текущих изменений). Свойство может принимать следующие значения:
• о — показывает, что редактирование не проводилось;
• 1 — показывает, что данные в текущей записи редактировались, но изменения еще не сохранены;
• 2 — показывает, что текущая запись добавлена с помощью метода AddNew, но до сих пор не сохранена.
П RecordCount — определяет количество записей в таблице (доступно, ТОЛЬКО еСЛИ CursorType = 3).
П AbsoiutePosition — перемещает курсор на новую запись под данным номером. Должен иметь значение в интервале от 1 до RecordCount (доступно, ТОЛЬКО еСЛИ CursorType = 3).
П Bookmark — закладка в виде числа. Никак не связана с номером записи.
_Примечание_^
Можно при сканировании по таблице запомнить значение Bookmark в некоторой временной переменной, а затем вернуться обратно на данную запись (доступно, только если CursorType = 3).
О Pagesize — задает число записей таб; іи цы на странице. По умолчанию равен (доступно, только если CursorType = з).
П Pagecount — определяет количество страниц. Автоматически пересчитывается при изменении Pagesize (доступно, только если CursorType з);
П AbsolutePage — перемещает курсор на начало данной страницы (доступно, только если CursorType = 3).
Помимо перечисленных свойств, объект Recordset имеет ряд методов.
Ш Open — исполняет запрос и открывает таблицу-результат. Общий формат вызова: RecordSet.Open;Scurse.- ActiveConnection, CursorType), причем необязательные параметры Source, ActiveConnection И CursorType здесь обозначают то же, что и соответствующие свойства объекта Recordset. Кроме того, параметр ActiveConnection может быть не только объектом типа Connection, но и просто строкой инициализации — ConnectionString.
О Close — закрывает объект.
О Requery — заново пересчитывает таблицу. Эквивалентен последовательному исполнению методов close и Open.
О clone — возвращает объект типа Recordset (копию исходного объекта). Полезен в случаях, когда нужно использовать одновременно несколько записей из одной таблицы.
? MoveFirst, MoveLast, MoveNext, MovePrevious — перемещают курсор на первую, последнюю, следующую или предыдущую запись таблицы соответственно.
? Move — перемещает курсор на новое положение. Общий формат вызова: Recordset.Move(NumRecords, Start), причем NumRecords здесь — КОЛИчество записей, на которые нужно переместить курсор. Положительное значение означает перемещение вперед, отрицательное — назад по записям. Параметр start определяет точку отсчета, откуда нужно переместить курсор.
^ Примечание ^
Может быть либо закладкой, либо одним из возможных значений: о — значение по умолчанию, точка отсчета — текущая запись; 1 — отсчет идет от первой записи таблицы; 2 — отсчет идет от последней записи таблицы.
? AddNew — добавляет запись. Можно сначала добавить запись, затем определить значение полей. А можно это сделать и одной командой: RecordSet.AddNew(Fields, Values). Здесь Fields — ИМЯ ИЛИ Массив имен полей, которые нужно определить, values — значение или массив значений этих полей (чтобы сохранить добавленную запись, необходимо ВЫПОЛНИТЬ МеТОД Update).
О Delete — удаляет текущую запись или группу записей в зависимости от параметра. Формат записи: Recordset,Delete(AffectRecords>, где параметр Af fectRecords может принимать одно из возможных значений:
• 1 — (значение по умолчанию) удаляет только текущую запись;
• 2 — удаляет записи, удовлетворяющие свойству Filter, которое должно быть задано заранее.
? update — сохраняет изменения в текущей записи. Изменения в записи можно произвести предварительно или непосредственно в команде: Recordset. Update (Fields, Values). Параметр Fields определяет здесь имя или массив имен полей, которые нужно определить, параметр values — значение или массив значений этих полей. Если курсор перемещен с добавленной или измененной записи, сервер автоматически выполнит метод Update.
П Cancel Update — отменяет любые изменения или добавления записей, проведенные до использования метода update.
Работа со структурой базы данных (ADOX)
Для работы со структурой базы данных существует технология ADO Extensions for Data Definition and Security (ADOX). ADOX — представляет собой набор объектов, позволяющих манипулировать метаданными в базах данных и управлять объектами, отвечающими за безопасность.
ADOX предоставляет более универсальный способ манипуляции метаданными, не требующий знания SQL для того, чтобы получить структуру базы данных или даже создать новые объекты.
Примечание
Обратите внимание на то, что ADOX работает далеко не со всеми базами данных— его функциональность ограничена Microsoft Access и Microsoft SQL Server, а также несколькими другими СУБД.
ADOX обладает собственной объектной моделью, состоящей из следующих объектов:
П Catalog — представляет всю схему базы данных;
П Table — представляет таблицу в базе данных;
П Column — представляет колонку в таблице;
П index — представляет индекс внутри таблицы;
? Key — представляет первичный или внешний ключ;
П Group — представляет группу пользователей;
П user — представляет индивидуального пользователя базы данных внутри группы;
О Procedure — представляет хранимую процедуру внутри базы данных;
П view — является представлением (view) внутри базы данных.
Иерархия объектов ADOX начинается с объекта catalog. Этот объект содержит коллекции таблиц, представлений, процедур, пользователей и групп
203
и может быть использован для открытия существующей базы данных (с помощью объекта ADO Connection), а также для создания новой. Имея объект catalog, можно работать с таблицами, процедурами и представлениями. Например, просматривая коллекцию Tables, можно узнать, какие таблицы имеются в базе данных, а также получить более детальные сведения о таблицах, изучив коллекции Columns, indexes и Keys объекта Table. Изучая свойства объектов базы данных, можно получить сведения о метаданных и, в частности, сохранить их в отдельном файле или куда-либо перенести. Используя коллекции users и Groups, можно манипулировать правилами доступа к данным, создавая отдельных пользователей или группы пользователей базы данных.
Чтение структуры базы данных
Рассмотрим пример вывода информации о таблицах, представлениях и процедурах базы данных (листинг 5.8).
’Листинг 5.8. Вывод информации о таблицах, представлениях и хранимых процедурах
// Начальная инициализация
Catalog = Новый СОМОбъект("ADOX.Catalog");
Catalog.ActiveConnection = СтрокаПодключения;
// Выводим таблицы
Дл.^р^ерТаблицы = 0 По Catalog.Tables.Count-1 Цикл ИмяТаблицы = Catalog.Tables.Item(НомерТаблииы).Name;
Сообщить("Таблица: " + ИмяТаблицы);
КонецЦикла;
// Проверка текущего источника данных на поддержку коллекции Views Попытка
КоличествоПредставлений = Catalog.Views.Count;
ПредставленияДоступны = Истина;
Исключение
ПредставленияДоступны = Ложь;
КонецПопытки;
Если ПредставленияДоступны Тогда // Выводим представления
Для НомерПредставления = 0 По Catalog.Views.Count-1 Цикл
ИмяПредставления = Catalog.Views.ІДет(НомерПредставления).Name; Сообщить("Представление: " + ИмяПредставления);
КонецЦикла;
КонецЕсли;
// Выводим процедуры
Для НомерПроцедуры = 0 По Catalog.Procedures.Count-1 Цикл ИмяПроцедуры = Catalog.Procedures.Item(НомерПроцедуры).Name;
Сообщить("Процедура: " + ИмяПроцедуры);
КонецЦикла;
В приведенном примере имеются три цикла для просмотра коллекций Tables, views и Procedures объекта Catalog. Отметим, что перед циклом просмотра коллекции views следует выполнить проверку того, доступны ли представления для текущего источника данных с помощью конструкции Попытка...Исключение...КонецПопытки. Это делается, чтобы избежать ошибок и исключительных ситуаций, которые могут возникнуть, если ADOX не поддерживает коллекцию views для текущего источника данных.
Коллекция Tables содержит один или более объектов Table, свойствами которых являются коллекции columns, indexes и Keys, и их также следует просмотреть (листинг 5.9).
Листинг 5,9. Вывод информации о полях, индексах и ключах таблиц
// Начальная инициализация
Catalog = Новый СОМОбъект("ADOX.Catalog");
Catalog.ActiveConnection = СтрокаПодключения;
// Выводим таблицы
Для НомерТаблииы = 0 По Catalog.Tables.Count-1 Цикл Table = Catalog.Tables.Item(НомерТаблицы);
ИмяТаблицы = Table. Name;
Сообщить("Таблица: " + ИмяТаблицы);
// Выводим поля таблицы
Если Table.Columns.Count > 0 Тогда
Для НомерПоля = 0 По Table. Columns. Count-1 Цикл Column = Table.Columns.Item(НомерПоля);
ИмяПоля = Column.Name;
ТипПоля = Column. Type;
ДлинаПоля = Column,DefinedSize;
Сообщить ("Имя поля; " + ИмяПоля) ;
Сообщить ("Тип поля: " + ТипПоля) ;
Сообщить("Длина поля: " + ДлинаПоля);
КонецЦикла;
КонецЕсли;
// Выводим индексы таблицы
Если Table.Indexes.Count > 0 Тогда
Для НомерИндекса = 0 По Table.Indexes.Count-1 Цикл Index = Table.Indexes.Item(НомерИндекса);
ИмяИндекса = Index.Name;
Сообщить ("Имя индекса: " + ИмяИндекса)
КонецЦикла;
КонецЕсли;
//. Выводим ключи таблицы
Если Table.Keys.Count > 0 Тогда
Для НомерКлюча = 0 По Table.Keys.Count-1 Цикл Key = Table.Keys.ІРет(НомерКлюча) ;
ИмяКлюча = Key.Name;
Сообщить("Имя ключа: " + ИмяКлюча);
КонецЦикла;
КонецЕсли;
КонецЦикла;
В данном примере в цикле выборки полей таблицы свойство column.туре возвращает число, соответствующее типу, определенному в табл. 5.1. Ниже будет приведен полный список свойств объекта column.
? Attributes — содержит характеристики поля.
? DefinedSize — содержит максимальный размер поля.
? NumericScale — содержит сведения о положении десятичной точки для числового поля.
О Parentcatalog — указывает на имя каталога, к которому принадлежит поле. П Precision — содержит максимальную точность данных в поле.
? RelatedCoiumn — для ключевых полей содержит имя связанного поля.
П Sortorder — указывает порядок сортировки в данных для поля.
? туре — содержит тип данных, хранящихся в поле.
Объект index содержит следующие свойства.
? clustered — указывает, является ли индекс кластерным.
О indexNuiis — указывает, как обрабатываются значения Null.
D PrirnaryKey — указывает, реализует ли данный индекс первичный ключ.
П unique — указывает, должен ли быть уникальным ключ, реализованный в данном индексе.
И наконец, рассмотрим список свойств объекта Key.
В DeleteRule — указывает, каким образом обрабатывается удаление записи, содержащей первичный ключ.
? RelatedTable — для внешнего ключа указывает имя связанной таблицы.
О туре - содержит тип ключа.
О UpdateRule — указывает, как производится обновление записи, содержащей первичный ключ.
Создание баз данных и их объектов
Первый шаг при создании новой базы данных — создание нового экземпляра объекта Catalog. Это позволяет определить не только тип создаваемой базы данных (с помощью OLE DB-провайдера), но и местоположение файла базы данных. В листинге 5.10 показано, как это можно сделать для базы данных Microsoft Access.
; Листинг 5.10. Создание новой базы данных
207
Следующий пример (листинг 5.11) показывает, как можно реализовать эту последовательность действий.
Листинг 5.11. Создание новых полей в базе данных
// Создать новый экземпляр объекта Table Table = Новый СОМОбъект("ADOX.Table");
// Имя новой таблицы
ИмяТаблицы = "NewTable" ;
Table.Мате = ИмяТаблицы;
Добавление новой таблицы Catalog.Tables.Append(Table);
// Создать новый экземпляр объекта Column // Имя новой колонки
ИмяПоля = "NewColumn";
// Добавление нового поля (3-adlnteger)
Catalog.Tables(ИмяТаблицы).Columns.Append(ИмяПоля, 3);
Теперь рассмотрим работу с индексами и ключами. Для того чтобы создать ключ, используется объект ADOX.Key. Под объектами Key подразумеваются первичные (Primary key) И внешние (Foreign key) КЛЮЧИ.
Приведем пример созданий внешнего ключа (листинг 5.12).
Листинг 5.12. Создание внешнего ключа
НННМНВВН___яШШШШ_____________ВШИ___IlilfflllM!___ИИННІ___I_____ШшШШВЯЛ
ForeignKey = Новый СОМОбъект("ADOX.Key");
ForeignKey.Name = "CustOrder";
ForeignKey.Type = 1; // adKeyForeign
// Далее указывается ссылка на связанную таблицу
ForeignKey. RelatedTable = "Customers";
// Определяем имя ключевого поля
ForeignKey.Columns.Append("CustomerId");
// Определяем имя поля в связанной таблице
ForeignKey.Columns("CustomerId").RelatedColumn = "Customerld";
// Определяем правила контроля за каскадными обновлениями
ForeignKey.UpdateRule = adRICascade;
// Добавляем ключ в коллекцию ключей
Catalog.Tables("NewTable").Keys.Append(ForeignKey);\
В данном примере свойство ForeignKey, Туре может принимать следующие значения:
? 1 (adKeyPrimary) — первичный ключ;
? 2 (adKeyForeign) — внешний КЛЮЧ;
? 3 (adKeyUnique) — уникальный КЛЮЧ.
Свойство ForeignKey.UpdateRule может принимать следующие значения:
? о (acRiNone) — никаких действий каскадно не производится (используется по умолчанию);
? 1 (adRiCascade) — произвести каскадное обновление поля;
О 2 (adRiSet-.Nu-l) — значение внешнего ключевого поля выставляется в Null;
? з (adP.iSetDefault) — значение внешнего ключевого поля выставляется в значение по умолчанию.
Подобным же образом осуществляется работа с управлением индексами.
Примечание_
Можно особо отметить следующую особенность — у таблицы есть коллекция индексов, а уже у каждого индекса есть коллекция полей, входящих в этот индекс. Для простых индексов, состоящих из одного поля, в коллекции колонок содержится одна колонка, для составных индексов в коллекции колонок индекса содержатся колонки, входящие в этот индекс.
Приведем пример добавления к таблице составного индекса, состоящего из двух полей: Fieldl И Filed2 (ЛИСТИНГ 5.13).
.....
«ВІЯ
ИІЗІШ
мнп|—нмншшншнмнинвтгатгмш—ИИНИЮЯД—
Листинг 5.13. Создание составного индекса
. ... .... . . —' ....:—, .. .. Ш '
Index = Новый СОМОбъект("ADOX.Index");
// Зададим параметры индекса
Index.Name = "Indexl"
Index.Columns.Append("Fieldl") Index. Columns. Append (" Field2 ") // Добавляем индекс в коллекцию
Catalog.Tables("NewTable").Indexes.Append(Index);
Удаление объектов базы данных
Для удаления объектов базы данных используется метод Delete. Приведем пример удаления индекса, ключа, поля и таблицы (листинг 5.14).
Листинг 5.14. Удаление объектов базы данных
ИмяТаблицы = "NewTable";
// Удаление индекса
Catalog.Tables(ИмяТаблицы).Indexes.Delete(ИмяИндекса); // Удаление ключа
Catalog.Tables(ИмяТаблицы).Keys.Delete(ИмяКлюча);
// Удаление поля
Catalog.Tables(ИмяТаблицы).Columns.Delete(ИмяПоля);
// Удаление таблицы Попытка
Catalog.Tables.Delete(ИмяТаблицы);
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
В данном примере удаление таблицы взято в операторные скобки попытка... Исключение...КонецПопытки для исключения системных ошибок, связанных с невозможностью удаления таблицы. Подобная ошибка может появиться при попытке удалить таблицу, содержащую внешний ключ. Вообще говоря, удаление любых объектов баз данных рекомендуется обрамлять конструкцией Попытка...Исключение...КонецПопытки.
Доступ к данным Microsoft Excel через OLE DB
Достаточно часто требуется сформировать отчет и вывести его не только на печать, но и выгрузить в таблицу Microsoft Excel. Также иногда возникает необходимость импортировать данные Excel в систему "1С:Предприятие". Этого можно добиться двумя способами, либо используя технологию OLE Automation, описание и примеры использования которой рассматривались в главе 4, либо через объекты ADO.
Использование технологии ADO, при работе с таблицами Microsoft Excel, практически ничем не отличается от доступа к другим источникам данных. Для подключения к Excel можно использовать код:
Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\file.xls;
Extended Properties="Excel 8.0;HDR=NO;".
Параметр HDR здесь обозначает наличие заголовка в первой строке таблицы, причем YES — определяет присутствует заголовока; NO — нет.
Для выгрузки данных в таблицы Microsoft Excel необходимо создать файл с расширением XLS. Это можно сделать вручную, либо программно с помощью технологии ADOX. Рассмотрим пример создания файла Microsoft Excel через объекты ADOX (листинг 5.15).
1
Л
—аящяяя гта др f г ¦у *у у rt у
StaUSiS
Листинг 5.15. Создание MS Excel файла средствами ADOX
. , —. НЯНЯН і -----------------, ij.LlL.i ...Н^вНВЕ& tUu Л,
// Определение имени файла и строки соединения
ИмяФайла = "C:\ExcelDemoFile.xls",-
СтрокаПодключения = "Provider=Microsoft, Jet. 0LED3. 4 . ОData Source=" a
Extended Properties=""Excel 8.0;HDR=NO;.
ИмяФайла +
// Начальная инициализация
Catalog = Новый СОМОбъект("ADOX.Catalog") ;
Catalog.ActiveConnection = СтрокаПодключения;
// Создание новой таблицы
Table = Новый СОМОбъект("ADOX.Table");
// Имя таблицы
Table,Name = "TestTable";
Для Ном = 1 По 5 Цикл
// Создание новой колонки
Column = Новый СОМОбъект("ADOX.Column");
// Имя колонки
Column. Name = "Col" + Ном;
// Тип данных колонки Если Ном = 2 Тогда
Column.Туре = 202; // adVarWChar
Иначе
Column,Туре =5; // adDouble КонецЕсли;
// Присоединение колонки к таблице
Table.Columns.Append(Column);
Column = Неопределено;
КонецЦикла;
// Присоединение созданной таблицы (листа) к книге Excel
Catalog.Tables.Append(Table);
В данном примере создается файл C:\ExcelDemoFile.xls, в который добавляется лист с именем TestTable и инициализируются пять колонок. Свойство Туре объекта column определяет тип колонки. Для источника данных Microsoft Excel это свойство может принимать всего шесть значений, описанных в табл. 5.3.
Таблица 5.3. Допустимые значения свойства туре объекта column для MS Excel |
Константа ADO |
Значение |
Описание |
adDouble |
5 |
Значение с плавающей точкой двойной точности |
adDate |
7 |
Дата |
adCurrency |
6 |
Денежная сумма (8-байтовое целое со знаком, кратное 10 000) |
adBoolean |
11 |
Булево значение |
adVarWChar |
202 |
Символьная строка Unicode, заканчивающаяся СИМВОЛОМ Null |
adLongVarWChar |
203 |
Длинное строковое значение |
|
После того как файл Excel создан, можно выполнять действия по добавлению данных в какой-либо лист книги Excel. Данные действия можно выполнять двумя способами, либо через метод AddNew объекта Recordset (листинг 5.16), либо через SQL-запросы, используя конструкцию INSERT (листинг 5.17).
щ| птннншщ
Листинг 5.16. Запись данных в лист MS Excel средствами ADO
_ ______________________________— — .............................................—...................
// Создание соединения ADO для работы с книгой Excel
ConnectionExcel = Новый СОМОбъект("ADODB.Connection");
ConnectionExcel.Open(СтрокаПодключения);
// Создание объекта набора записей
RecordsetExcel = Новый СОМОбъект("ADODB.Recordset”);
RecordsetExcel.Open("Select * from TestTabie", ConnectionExcel, 1, 3);
Для Ном = 1 По 10 Цикл
// Добавление новой записи
RecordsetExcel.AddNew();
RecordsetExcel.Fields(0).Value = 11;
RecordsetExcel.Fields(1).Value = "Строка №" + Ном;
RecordsetExcel.Fields(2).Value = 2.30; RecordsetExcel.Fields(3).Value = Ном; RecordsetExcel.Fields(4).Value = Ном * 2.2;
/ / Обновление изменений в книге Excel
RecordsetExcel.UpDate();
КонецЦикла;
// За крыв а ем сое дин ени е
ConnectionExcel.Close();
ConnectionExcel = Неопределено;
В данном примере метод AddNew добавляет очередную строку в лист Excel. Важно отметить, что в один лист невозможно добавить более 65 000 строк — это ограничение приложения Microsoft Excel. Еще одна важная особенность добавления информации в ячейки листа заключается в том, что Excel не поддерживает автопреобразование типов значений ячеек. То есть, если с помощью свойства туре объекта Column для колонки соответствующей ячейки был определен числовой тип, то при попытке записать в эту ячейку строку — возникнет ошибка. Так же нельзя использовать для записи колонки, которые не были созданы, т. е. если было создано всего пять колонок, то можно записывать информацию только в первые пять колонок, хотя при открытии таблицы в приложении Microsoft Excel пользователю будут видны большое количество колонок.
Рассмотрим пример добавления записей, используя SQL-запросы (листинг 5.17).
Г-------------------
т,.......у........................
г~--,-------------------„---------
—----------------—--------,
Листинг 5.17. Запись данных в лист MS Excel через SQL-запросы
// Создание объекта установки связи с источником данных Connection = Новый СОМОбъект("ADODB.Connection");
// Подключение к источнику данных Попытка
Connection.Open(СтрокаПодключения)
Исключение
Сообщить(ОписаниеОшибки()) ; Возврат;
КонецПопытки;
// Создание объекта выполнения команды
Command = Новый СОМОбъект("ADODB.Command");
// Указание активного соединения
Command.ActiveConnection = Connection;
// Определение текста команды
Command.CommandText = "INSERT INTO TestTable VALUES (20, 'Новая строка',
33.3, 44.4, 55.5)";
// Определение типа команды
Command.CommandType = 1;
// Выполнение запроса
Command.Execute();
// Закрываем соединение
Connection.Close(); Command = Неопределенен
Данный пример аналогичен примеру, приведенному в листинге 5.4, за исключением того, что в конструкции запроса INSERT нельзя указать имена колонок.
Для чтения данных из листа Excel необходимо выполнить ряд стандартных действий. Пример такой выборки приведен в листинге 5.18.
,1 Листинг 5.18. Чтение данных MS Excel средствами ADO
_... .. ..._ ...... .___________________
// Чтение данных
// Создание объекта установки связи с источником данных
Connection = Новый СОМОбъект("ADODB.Connection");
// Подключение к источнику данных Попытка
Connection.Open(СтрокаПодключения);
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
// Создание объекта выполнения команды Command = Новый СОМОбъект("ADODB.Command"); // Указание активного соединения
Command.ActiveConnection = Connection;
// Определение текста команды
Command.CommandText = "select * from TestTable";
// Определение типа команды
Command.CommandType = 1;
// Создание объекта набора записей
RecordSet = Новый СОМОбъект("ADODB.RecordSet");
// Выполнение и получение набора данных RecordSet = Command.Execute () ;
// Перебор данных
Пока RecordSet.EOF() = 0 Цикл
Сообщить("Строка: " + Recordset.Fields(1).Value);
Сообщить("Число: " + Recordset.Fields(4).Value);
RecordSet.MoveNext();
КонецЦикла;
// После того как набор записей уже не нужен, его следует закрыть
RecordSet.Close();
Connection.Close () ;
Доступ к данным Microsoft Project через OLE DB
Для доступа к данным Microsoft Project можно использовать объекты ADO. Общие принципы, применяемые для доступа к данным MS Project, такие же, что и для других источников данных, но есть некоторые особенности и ограничения.
Некоторые аспекты использования средства доступа OLE DB для Microsoft Project уникальны и должны быть приняты во внимание во избежание нежелательных результатов.
Существует четыре типа данных:
• text — текстовый;
• number - ЧИСЛОВОЙ;
• boolean — логический;
• date — дата-время (в том виде, как они отображаются в интерфейсе, например 27.12.1999 10:30).
П Поля длительности возвращают число минут, умноженное на 10 (например, 8 часов — это 4800), а поля трудозатрат — число минут, умноженное на 1000 (8 часам соответствует 480 000).
? Даты, отображающиеся в интерфейсе как NA (нет данных), возвращаются как значение о.
П Формула в настраиваемом поле, которая в интерфейсе привела бы к результату # error, возвращает значение по умолчанию для данного поля.
П Настраиваемое поле, для которого не установлено никакого значения, возвращает значение, принимаемое по умолчанию.
П Поле индикатора настраиваемого поля в случае, когда индикатор не установлен, возвращает значение -1,
П Значения трудозатрат для материальных ресурсов выражаются в единицах, определенных в интерфейсе, а не числом минут, умноженным на 1000.
О Оператор SELECT без предложения WHERE возвращает пустые строки таблиц ресурсов и задач. Если задать предложение WHERE, эти строки уже не будут возвращены, даже если они подходят по всем остальным условиям.
В реализации средства доступа OLE DB для Microsoft Project 2002 действует
ряд ограничений.
П Не поддерживается доступ для чтения и записи.
П Не поддерживаются запросы сразу к нескольким таблицам. Для каждой таблицы, к которой требуется доступ, необходимо использовать отдельный запрос.
П Доступ к OLE DB осуществляется с помощью курсоров (наборов записей) последовательного доступа. Наборы записей с последовательным доступом не поддерживают такие методы, как MovePrevious, MoveFirst или MoveLast. Кроме того, наборы записей с последовательным доступом не поддерживают использование свойства Recordcount.
П Объединения не поддерживаются, однако аналогичные возможности предоставляют сформированные наборы записей, устанавливающие ранее не существовавшие отношения между ключами, полями или наборами строк. Можно также создавать иерархические наборы записей в табличном формате.
П Не поддерживаются операторы — ANY, LIKE и NOT.
П Не поддерживаются статистические функции — Sum, Avg, міп, мах, count И StDev.
П Средство доступа OLE DB снабжено механизмом контроля времени, который сигнализирует, когда следует выгружать файлы, но делает это не раньше, чем произойдет событие загрузки. Если в поле TirneBeforeUnload установлено значение 1, то не проверяется — имеется ли открытый файл,
до попытки открыть другой. В итоге этот файл блокируется для чтения. Во избежание возникновения данной ситуации надо создать фиктивный файл, чтобы заставить средство доступа, после завершения работы над текущим проектом, загружать некий несуществующий файл. Таким образом, файл, который был в работе, будет выгружен, а блокировка чтения будет установлена на фиктивный файл.
Среда ADO обеспечивает доступ к OLE DB с использованием набора объектов, событий, методов и свойств. Возможны два способа использования ADO:
? доступ к поставщику данных на локальном компьютере;
? доступ к поставщику с сервера Microsoft Project Server.
В листинге 5.19 показан доступ к файлу Microsoft Project на локальном компьютере, а также отображаются некоторые сведения о проекте.
Листинг 5.19. Подключение к проекту и вывод его свойств
// Определение параметров соединения Провайдер = "Microsoft.Project.OLEDB.10.0";
ИмяФайла = "C:\example.mpp";
// Если файл не защищен, то в строке подключения параметры
// User ID (пользователь) и Password (пароль) указывать не обязательно
Пользователь =
:г,!;
Пароль = "";
// Установка соединения с проектом Попытка
Connection = Новый СОМОбъект("ADODB.Connection") ;
Connection.Open("Provider=" + СокрЛП(Провайдер) +
Project Kame“” + СокрЛП (ИмяФайла) +
";
rJserID=” + СскрЛП (Пользователь ) +
";Password=" + СокрЛП(Пароль));
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
// Запрос к проекту
Command = Новый СОМОбъект("ADODB.Command"); .
Command.ActiveConnection = Connection;
Command. CommandText = "SELECT * FROM Project";
RecordSet = Новый СОМОбъект ("ADODB.RecordSet");
RecordSet = Command.Execute();
// Получение свойств проекта
Название = RecordSet.Fields("ProjectTitle").Value;
ДатаНачала = RecordSet.Fields("ProjectStartDate").Value;
ДатаКонца = RecordSet.Fields("ProjectFinishDate").Value;
// Вывод свойств проекта
Сообщить ("Название проекта: " + Название) ;
Сообщить ("Дата начала: " + ДатаНачала) ;
Сообщить("Дата завершения: " + ДатаКонца);
В данном примере происходит подключение к файлу проекта C:\example.mpp и выводится название проекта, даты начала и завершения проекта из таблицы Project (проект). Эта таблица обеспечивает доступ к параметрам уровня проекта.
Таблица Project имеет большое количество полей. Основные из них приведены в табл. 5.4.
Таблица 5.4. Основные поля таблицы Project
Имя поля
Тип Описание данных
Project (Проект) text Название проекта, отображаемое как путь к
его расположению на диске, например C:\example.mpp
ProjectUniqueiD number Уникальный идентификатор проекта
(Уникальный идентификатор проекта)
Proj ectAuthor
(Автор) |
text |
Proj ectCompany
(Организация) |
text |
ProjectCreationDate (Дата создания) |
date |
ProjectStartDate (Дата начала) |
date |
ProjectFinishDate (Дата окончания) |
date |
Имя автора проекта. Используется для группировки аналогичных проектов
Название организации, создавшей проект; используется для группировки аналогичных проектов
Дата создания проекта
Дата и время запланированного начала проекта
Дата и время запланированного завершения проекта
Таблица 5.4 ( окончание)
Имя поля
Тип Описание
данных
date Дата последнего сохранения проекта
text Руководитель проекта. Используется для
группировки проектов, имеющих одного руко
водителя
text Текущий номер версии файла проекта
text Тема проекта. Используется для группировки аналогичных проектов
text Название проекта. Используется для группировки аналогичных проектов
ProjectLastSaved
(Дата сохранения)
ProjectManager
(Руководитель)
ProjectRevision
(Версия)
ProjectSubject
(Тема)
ProjectTitle
(Название)
Все остальные поля таблицы Project и их типы можно вывести с помощью объектов ADOX (листинг 5.20).
Листинг 5.20. Вывод всех полей таблицы Project
// Определение параметров соединения Провайдер = "Microsoft.Project.OLEDB.10.0";
ИмяФайла = "C:\exair.ple.mpp”;
// Начальная инициализация Catalog = Новый СОМОбъект("ADOX.Catalog") ;
Catalog.ActiveConnection = "Provider=" + СокрЛП(Провайдер) + "/Project Name=" + СокрЛП (ИмяФайла) ; . ¦
Table = Catalog.Tables.Item("Project");
// Выводим поля таблицы Если Table.Columns.Count > 0 Тогда
Для НомерПоля = 0 По Table.Columns.Count-1 Цикл Column = Table.Columns.Item(НомерПоля);
ИмяПоля = Column. Name;
ТипПоля = Column.Type;
ДлинаПоля = Column.DefinedSize;
Сообщить ("Имя поля: " + ИмяПоля) ;
Сообщить("Тип поля: " + ТипПоля);
Сообщить("Длина поля: " + ДлинаПоля); КонецЦикла;
КонецЕсли;
Основная таблица, в которой хранятся сведения о задачах, включенных в проект, имеет идентификатор — Tasks, основные поля которой перечислены в табл. 5.5.
Таблица 5.5. Основные поля таблицы Tasks
Имя поля Тип Описание
данных
TaskUniquelD
(Уникальный
идентификатор)
TaskActualStart (Фактическое начало)
TaskActualFinish
(Фактическое
окончание)
TaskActualWork
(Фактические
трудозатраты)
TaskStart
(Начало)
TaskContact (Контактное лицо)
number Уникальный идентификатор задачи
date Дата и время фактического начала задачи
date Дата и время фактического завершения задачи
number Объем трудозатрат, которые уже выполнены назначенными задаче ресурсами
date Дата и время запланированного начала выполнения задачи вычисляется автоматически, если у задачи есть предшественник. TaskFinish — дата и время запланированного завершения выполнения задачи
text Имя человека, являющегося ответственным за выполнение задачи
Название задачи Введенные заметки о задаче
TaskName (Название) text TaskNotes (Заметки) text
TaskOutlineLevel
(Уровень структуры)
number Число, определяющее уровень задачи в иерархической структуре проекта
TaskOutlineNumber text
(Номер в структуре)
Точная позиция задачи в структуре. Например, номер 7.2 означает, что данная задача является второй подзадачей седьмой суммарной задачи верхнего уровня
TaskPercentComplete number Текущее состояние задачи, выраженное в виде (Процент завершения) завершенной части работы в процентах по от
ношению к общей длительности задачи
К задачам обычно привязан один или несколько ресурсов. В таблице Assignments содержатся данные о необходимых ресурсах для выполнения всех задач. Основные поля таблицы Assignments приведены в табл. 5.6.
Таблица 5.6. Основные поля таблицы Assignments
Имя поля Тип Описание
данных
TaskUniquelD (Уникальный number идентификатор задачи)
AssignmentUniquelD number
(Уникальный идентификатор)
AssignmentResourcelD number
(Идентификатор ресурса)
AssignmentActualStart date
(Фактическое начало)
AssignmentActualFinish date
(Фактическое окончание)
AssignmentActualWork number
(Фактические трудозатраты)
Assignment St art (Начало) date
AssignmentFinish date
(Окончание)
AssignmentFinishVariance number
(Отклонение окончания)
AssignmentNotes (Заметки) text AssignmentUnits (Единицы) number
Указатель на действительный идентификатор в таблице Tasks
Уникальный идентификатор назначения
Указатель на действительный идентификатор в таблице Resources
Дата и время фактического начала назначения
Дата и время фактического завершения назначения
Объем работы, которая уже выполнена ресурсом задачи
Запланированная дата и время начала работы назначенного ресурса
Запланированная дата и время завершения использования ресурса по задаче
Разница между датой окончания назначения по базовому плану и запланированной датой окончания
Заметки о назначении
Число единиц,' на которое ресурс назначается задаче. Выражается в процентах от максимального числа единиц ресурса
Общий запланированный объем трудозатрат, которые ресурс должен выполнить по задаче
Название ресурса, связанного с назначением
Тип ресурса: 0 — трудовой (люди и оборудование, назначается по умолчанию); 1 — материальный (расходные материалы, например, сталь, бетон или грунт)
Л s я L g rime n t W о r k numbe r
(Трудозатраты)
AssignmentResourceName text
(Название ресурса)
AssignmentResourceType number
(Тип ресурса)
Рассмотрим пример вывода дерева задач с указанием использованных ресурсов для системы "1С:Предприятие” версии 8.0 (листинг 5.21).
Листинг 5.21. Вывод дерева задач с указанием использованных ресурсоЕ I для версии 8.0
// Переводит номер задачи из формата ххх.хх.х в ххх,хх Функция ПолучитьКодРодителя(Знач НомерЗадачи)
ЧислоВхождений = СтрЧислоВхождений(НомерЗадачи, ".");
Поз = 0:
Если ЧислоВхождений = 0 Тогда Возврат "О";
Иначе
Для Ном = 1 По ЧислоВхождений Цикл
Поз -- Поз + Найти (Сред (НомерЗадачи, Поз f 1), ".")
КонецЦикла;
Возврат Лев(НомерЗадачи, Поз - 1);
КонецЕсли;
КонецФункции
// Формирует дерево задач Процедура СформироватьДерево()
Провайдер = "Microsoft.Project.OLEDB.10.0" ИмяФайла = ”C:\example.rnpp";
Пароль =
Состояние("Соединение с проектом. Пожалуйста ждите...");
Попытка
Connection = Новый СОМОбъект("ADODB.Connection") ; Connection.Open("Provider=" + СокрЛП Провайдер) +
Project Na.me=” + СскрЛП (ИмяФайла) + ".¦Password”" + СокрЛП(Пароль));
Исключение
Сообщить(ОписаниеОшибки()); Возврат;
КонецПопытки;
// Запрос к задачам
Command = Новый СОМОбъект("ADODB.Command");
Command-ActiveConnection = Connection,-Command.CommandText = " select
TaskName,TaskType,TaskUniquelD,TaskOutlineLevel,TaskOutlineNumber, TaskStart,TaskFinish,TaskPercentComplete from Tasks” ;
RecordSet = Новый СОМОбъект("ADODB.RecordSet");
Recordset = Command.Execute();
// Перебор данных
Пока RecordSet. EOF' (> = 0 Цикл
// Тип записи: 1-группа, 0-задача
ТипЗадачи = RecordSet.Fields("TaskType").Value;
// Имя задачи или группы
ИмяЗадачи = RecordSet.Fields("TaskName").Value; .
// Уникальный идентификатор задачи или группы
ИдентификаторЗадачи = RecordSet.Fields("TaskUniquelD").Value;
// Уровень задачи
УровеньЗадачи = RecordSet.Fields("TaskOutlineLevel").Value;
// Номер задачи в формате хх.х.х
НомерЗадачи = RecordSet.Fields("TaskOutlineNumber").Value; ДатаНачала = RecordSet.Fields("TaskStart").Value;
ДатаКонца = RecordSet.Fields("TaskFinish").Value; ПроцентВыполнения = RecordSet.Fields("TaskPercentComplete").Value;
Если НомерЗадачи = 0 Тогда
СтрокаТПБазовая = ТабличноеПоле;
Иначе
// Поиск родительской задачи Результат =
ТабличноеПоле.Строки.Найти(ПолучитьКодРодителя(НомерЗадачи), "Ид", Истина);
Если Результат = Неопределено Тогда СтрокаТПБазовая .= ТабличноеПоле;
Иначе
СтрокаТПБазовая = Результат;
КонецЕсли;
КонецЕсли;
// Добавляем параметры задачи в дерево
СтрокаТП = СтрокаТПБазовая.Строки.Добавить();
СтрокаТП.Ид = НомерЗадачи;
СтрокаТП.Задача = ИмяЗадачх;
СтрокаТП.ДатаНачала = ДатаНачала;
СтрокаТП.ДатаКонца = ДатаКонца;
Ресурсы =
Если ТипЗадачи = 0 Тогда // Это задача // Запрос по ресурсам
Command = Новый СОМОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "SELECT AssignmentUnits,
AssignmentResourceName FROM Assignments WHERE AssignmentResourcelD > 0 AND TaskUniquelD = " + ИдентификаторЗадачи;
RecordSetResource = Новый СОМОбъект("ADODB.RecordSet"); RecordSetResource = Command.Execute();
// Перебор данных
0 Цикл
Пока RecordSetResource.EOF()
ИмяРесурса =
RecordSetResource.Fields("AssignmentResourceName"). Value; ПроцентЗагрузки =
RecordSetResource.Fields("AssignmentUnits"). Value * 100;
Ресурсы = Ресурсы + ?(Ресурсы^-"","","; ")
СокрЛП(ИмяРесурса) + " (" + ПроцентЗагрузки + "%)";
RecordSetResource.MoveNextО;
КонецЦикла;,
RecordSetResource.Close();
КонецЕсли;
СтрокаТП.Ресурсы = Ресурсы;
// Переход к следующей задачи
RecordSet.MoveNext О;
КонецЦикла;
RecordSet.Close ();
КонецПроцедуры
В данном примере подразумевается, что на форме обработки имеется элемент — табличное поле с идентификатором табличноеполе. Это табличное поле имеет четыре созданных на форме текстовых поля:
а ид — скрытое поле, предназначенное для хранения идентификатора задачи;
О задача — название задачи;
П датаНачала — запланированная дата начала выполнения задачи;
П датакониа — запланированная дата окончания задачи;
П Ресурсы — строка, содержащая список используемых ресурсов и их загрузку.
Результат вывода дерева задач произвольного проекта показан на рис. 5.2.
 |
Рис. 5.2. Результат вывода дерева задач проекта |
Помимо основных, ранее описанных таблиц (project, Tasks и Assignments), существуют и другие, не менее важные таблицы, подробное описание которых в данной книге приводиться не будет. Рассмотрим их состав и назначение.
П Availability — таблица обычно используется вместе с таблицей для получения сведений о доступности ресурсов.
П BaselineTaskSplits — в этой таблице сохраняются базовые сведения о прерывании для конкретной задачи.
П CalendarData и CalendarExceptions — в этих таблицах хранятся все КЯЛСП-
дарные данные, имеющиеся в средстве доступа Microsoft Project OLE DB.
П Calendars — календари, используются для определения стандартного рабочего и нерабочего времени. В проекте необходимо иметь один базовый
календарь. У задач и ресурсов могут быть свои собственные календари, но все они должны строиться на основе базового календаря. В этой таблице хранятся основные календарные данные.
О CostRates — таблица обычно используется вместе с таблицей Resources для отображения содержимого таблиц норм затрат, относящихся к ресурсу. Кроме того, данную таблицу можно использовать совместно с таблицей Assignments для получения сведений о таблице норм затрат, используемой назначением.
П CustomFieidGraphicalindicators — таблица обычно используется вместе с таблицей CustomFieids для получения параметров настраиваемых полей, для которых предусмотрены графические индикаторы.
П CustomFieids (настраиваемые поля) — данная таблица используется для получения всех параметров настраиваемого поля. Для изменения этих полей необходимо извлечь глобальный корпоративный шаблон.
П customFieidVaiueList — эта таблица используется для получения значений таблицы подстановок для настраиваемых полей, имеющих список значений.
О CustomOutiineCodeFieids (поля кодов структуры) — в этой таблице содержится маска для каждой таблицы подстановки настраиваемого кода структуры.
П (таблицы подстановки) — таблица дан
ного типа используется для получения списка значений таблиц подстановки, связанных с полями настраиваемых кодов структуры.
П Predecessors (предшественники) — таблица обычно используется вместе с таблицей Tasks для отображения подробных сведений о задачах-предшественниках.
П Resources — в этой таблице содержатся сведения, относящиеся к ресурсам.
П Successors — таблица обычно используется вместе с таблицей Tasks для отображения подробных сведений о задачах-последователях.
П TaskSplits — в этой таблице хранятся даты начала и окончания прерывания задачи.
П (структурная декомпозиция работ) — в этой таблице хранятся определения кода СДР, а также параметры кода СДР для проекта.
Содержание раздела