Статьи

Подключение к базе данных 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 сек.
Примечания:
  1. если предполагаются операции с большими или очень большими объемами данных, то данное время крайне желательно увеличить;
  2. если Вам пришлось увеличить данное время, подумайте все ли Вы правильно делаете.
Методы
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" и пустой пароль), то с именами сервера и базы данных возникает небольшая проблема. Есть три пути решения данной проблемы:
  1. "Зашить" строку подключения в код (откажитесь сразу).
  2. Использовать константы (уже лучше, но есть недостаток. При загрузке данных в другую базу Вам придется не забывать менять эти константы, иначе в лучшем случае Ваши пользователи будут получать неправильные отчеты, в худшем... тут фантазия рисует жуткие картины всемирного апокалипсиса).
  3. Написать функцию, которая при помощи "Rainbow" сформирует нужную строку подключения. (лучший вариант).
Недостатки первых двух методов очевидны. Что касается третьего метода, то может возникнуть вопрос, а зачем использовать ADO, если есть "Rainbow"? Ответ простой - ADO обладает рядом преимуществ перед "Rainbow":
  1. Ошибка в ADO не вызывает аварийного закрытия 1С. "Rainbow" в этом случае закрывает 1С со страшным сообщением "Невосстановимая ошибка базы данных". Не верьте. Очень даже восстановимая.
  2. ADO быстрее (без комментариев).
  3. ADO при наличии одного открытого объекта Connection позволяет использовать в разных объектах Recordset временные таблицы (бывает очень нужно).
  4. При открытом объекте 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();
   КонецЕсли;
   Возврат тзРезультат;
КонецФункции
На сегодня все. В следующей статье мы рассмотрим средства автоматизации работы со справочниками.
Hosted by uCoz