|
Подключение к базе данных 1С и выполнение SQL запросов на примере работы со справочниками. Часть 3.
Сегодня, как мы и обещали, рассмотрим основные приемы работы с базой данных 1С с использованием средств Microsoft ActiveX Data Objects (ADO). Цитата из Microsoft Solution Developer Network Library (MSDN): "Microsoft ActiveX Data Objects (ADO) enable your client applications to access and manipulate data from a variety of sources through an OLE DB provider. Its primary benefits are ease of use, high speed, low memory overhead, and a small disk footprint. ADO supports key features for building client/server and Web-based applications." Краткий литературный перевод: "При помощи ADO легко и удобно работать с различными базами данных, и уж тем более с MS SQL Server."
Так как ADO является ключевой технологией Microsoft, то прилагать особых усилий для установки его на Ваш компьютер не придется. В 99% он уже присутствует.
Объектная модель ADO довольна обширна, но в рамках нашего цикла статей мы будет использовать только два объекта "Connection" и "Recordset". За описанием других объектов ADO Вам следует обратится к MSDN (любимая фраза преподавателей различный компьютерных курсов). Более того, в этой статье мы не ставим целью описать все тонкости работы с упомянутыми объектами, а рассмотрим только ту часть информации, которая позволит нам подключаться и получать данные из 1С. Если у Вас появится желание стать экспертом по использованию ADO, то... совершенно верно: Вам следует обратиться к MSDN.
И так, продолжим...
Объект "Connection"
Объект предназначен для представления сервисов по подключению к базе данных. Необходимые нам свойства и методы объекта:
Наименование |
Описание |
Свойства |
ConnectionString |
Cтрока подключения к базе данных. Имеет вид: "Driver={SQL Server};Server=ИмяСервера;Uid=ИмяПользователя;Pwd=Пароль(или пусто);DataBase=ИмяБазыДанныхНаСервере;". |
ConnectionTimeOut |
Время ожидания соединения (в секундах) с сервером, по истечении которого генерируется ошибка. По умолчанию равно 15 сек. |
CommandTimeOut |
Время ожидания (в секундах) выполнения команды (SQL запроса),по истечении которого генерируется ошибка.
По умолчанию равно 30 сек.
Примечания:
- если предполагаются операции с большими или очень большими объемами данных, то данное время крайне желательно увеличить;
- если Вам пришлось увеличить данное время, подумайте все ли Вы правильно делаете.
|
Методы |
Open(СтрокаПодключенияКБазеДанных) |
Открывает соединение с базой данных |
Execute(СтрокаЗапроса) |
Выполняет SQL запрос. Имеет смысл применять в том случае, если необходимо выполнить запрос, не возвращающий данные клиену. Например, обновление или вставка новых строк в таблицу. |
Close() |
Закрывает соединение с базой данных. |
Объект "Recordset"
Объект предназначен для выполнения запросов к базе данных и возврата итоговой выборки клиенту. Основные свойства и методы:
Наименование |
Описание |
Свойства |
ActiveConnection |
Содержит объект Connection, с помощью которого мы можем подключиться к серверу. |
State |
Свойство указывает открыт или закрыт объект. Например, если был выполнен запрос, но в итоговой выборке нет строк, то в свойстве State будет 0. Учтите, что нельзя открывать еще раз уже открытый объект и закрывать уже закрытый. Так что перед выполнением соответствующих методов лучше проверять значение свойства State. Вы уверены, что всегда знаете закрыт Ваш объект или открыт? В таком случае Вы либо еще очень молоды (это пройдет), либо жизнь Вас ни чему не учит (а вот это едва ли). |
|
|
Fields(ИмяПоля).Value |
Возвращает значение ИмяПоля из выборки (строго говоря это коллекция, но отнесем ее к свойствам мы же не коллекционеры). |
EOF |
Возвращает 1, если в результате перебора дошли до конца выборки. |
Методы |
Open(СтрокаЗапроса) |
Открывает выборку данных. |
MoveNext() |
Получить следующее значение выборки. |
Close() |
Закрыть выборку. |
Работа с ADO
В общем случае ADO более предпочтительно в использовании, однако есть большой недостаток: ADO, в отличии от "Rainbow", не работает в монопольном режиме. Если Вы будете применять его при проведении документов, то Вам придется отказаться от системного перепроведения.
Первая проблема с которой Вы столкнетесь при использовании ADO это проблема формирования строки подключения. Если имя пользователя и пароль всегда известны (в 90% случаев это "sa" и пустой пароль), то с именами сервера и базы данных возникает небольшая проблема. Есть три пути решения данной проблемы:
- "Зашить" строку подключения в код (откажитесь сразу).
- Использовать константы (уже лучше, но есть недостаток. При загрузке данных в другую базу Вам придется не забывать менять эти константы, иначе в лучшем случае Ваши пользователи будут получать неправильные отчеты, в худшем... тут фантазия рисует жуткие картины всемирного апокалипсиса).
- Написать функцию, которая при помощи "Rainbow" сформирует нужную строку подключения. (лучший вариант).
Недостатки первых двух методов очевидны. Что касается третьего метода, то может возникнуть вопрос, а зачем использовать ADO, если есть "Rainbow"? Ответ простой - ADO обладает рядом преимуществ перед "Rainbow":
- Ошибка в ADO не вызывает аварийного закрытия 1С. "Rainbow" в этом случае закрывает 1С со страшным сообщением "Невосстановимая ошибка базы данных". Не верьте. Очень даже восстановимая.
- ADO быстрее (без комментариев).
- ADO при наличии одного открытого объекта Connection позволяет использовать в разных объектах Recordset временные таблицы (бывает очень нужно).
- При открытом объекте Recordset нет никаких ограничений на работу с базой данных самой 1С. Проще говоря, если вы открыли выборку при помощи "Rainbow", то, пока не закроете, не сможете пользоваться методами 1С для доступа к данным. При применении ADO делайте, что хотите, хоть документ проводите, хоть справочник меняйте.
Правда, повторимся, за это приходится жертвовать монопольным режимом.
Попробуем перейти от теории к практике.
Написать функцию глПолучитьСтрокуПодключения(), возвращающую строку подключения по материалам прошлых статей не должно составить труда.
Подсказка: запрос имеет следующий вид:
-- @@SERVERNAME - имя сервера, NAME - имя базы данных
SELECT @@SERVERNAME, NAME
FROM master.dbo.sysprocesses pr, master.dbo.sysdatabases db
WHERE pr.dbid = db.dbid AND pr.spid = @@SPID
Пример инициализации объектов ADO:
стрПараметрыПодключенияКБД = глПолучитьСтрокуПодключения();
objConnection = СоздатьОбъект("ADODB.Connection");
objConnection.Open(стрПараметрыПодключенияКБД);
objRecordset = СоздатьОбъект("ADODB.Recordset");
objRecordset.ActiveConnection = objConnection;
Теперь давайте перепишем функцию, созданную в прошлой статье, и использованием технологии ADO:
Функция ПолучитьТЗКонтрагентовПоУсловию(ВыбМенеджер, ВыбРегион)
тзРезультат = СоздатьОбъект("ТаблицаЗначений");
тзРезультат.НоваяКолонка("Контрагенты", "Справочник.Контрагенты");
метаIDКонтрагента = Число(глПолучитьМетаIDОбъекта(Метаданные.Справочник("Контрагенты"), 0));
РеквизитОтвМенеждер = Метаданные.Справочник("Контрагенты").Реквизит("ОтветственныйМенеджер");
метаIDОтветственныйМенеджер = Число(глПолучитьМетаIDОбъекта(РеквизитОтвМенеджер, 0));
РеквизитРегион = Метаданные.Справочник("Контрагенты").Реквизит("Регион");
метаIDРегион = Число(глПолучитьМетаIDОбъекта(РеквизитРегион, 0));
IDМенеджера = глПолучитьIDОбъекта(ВыбМенеджер.ТекущийЭлемент(), 1);
IDРегиона = глПолучитьIDОбъекта(ВыбРегион.ТекущийЭлемент(), 1);
стрЗапрос =
"SELECT ID
|FROM SC" + метаIDКонтрагента + "
|WHERE
| SP" + метаIDОтветственныйМенеджер + " = " + IDМенеджера + "
| AND SP" + метаIDРегион + " = " + IDРегиона;
objRecordset.Open(стрЗапрос);
Если Число(objRecordset.State) <> 0 Тогда
Пока objRecordset.EOF = 0 Цикл
тзРезультат.НоваяСтрока();
текЗначение = objRecordset.Fields("ID").Value;
тзРезультат.Контрагенты = глПолучитьОбъектПоID("Справочник", метаIDКонтрагента, текЗначение);
objRecordset.MoveNext();
КонецЦикла;
objRecordset.Close();
КонецЕсли;
Возврат тзРезультат;
КонецФункции
На сегодня все. В следующей статье мы рассмотрим средства автоматизации работы со справочниками.
|