Как создать отчет в 1С на основе данных из СУБД Firebird?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Интеграция 1С с другими системами управления базами данных — частая задача при автоматизации бизнеса. СУБД Firebird часто используется в качестве учетной системы на кассовых узлах, в логистических программах или архивных базах данных. Однако при попытке построить отчет в 1С напрямую на основе данных из Firebird разработчики сталкиваются с рядом технических сложностей.

В этой статье мы подробно проанализируем особенности взаимодействия 1С с СУБД Firebird, разберем ограничения встроенного механизма «Внешних источников данных» и реализуем наиболее надежную схему получения отчетов: ADO — Таблица значений — СКД (Система компоновки данных).

Выясняем причину: почему стандартные Внешние источники данных дают сбой?

Платформа 1С:Предприятие обладает встроенным механизмом работы с внешними базами данных — Внешние источники данных (ВИД). На первый взгляд, это самый удобный путь: достаточно настроить ODBC-подключение к Firebird, после чего таблицы сторонней СУБД будут доступны в конструкторе запросов 1С наряду со стандартными справочниками и регистрами.

Однако на практике разработчики сталкиваются с критической проблемой совместимости SQL-диалектов:

  1. При формировании запросов (особенно при ограничении количества выбираемых записей или использовании постраничного вывода) 1С транслирует запросы, используя стандартный синтаксис SELECT TOP.
  2. СУБД Firebird не поддерживает синтаксическую конструкцию SELECT TOP. Вместо нее в диалекте Firebird используются конструкции FIRST / SKIP (в более ранних версиях) или ROWS (в современных версиях).
  3. В результате при попытке выполнить даже простейший запрос к внешнему источнику данных Firebird платформа 1С возвращает синтаксическую ошибку СУБД-источника. Использование универсальных драйверов (даже платных аналогов от Devart) далеко не всегда решает эту проблему, поскольку платформа 1С жестко ориентирована на синтаксические стандарты MS SQL, PostgreSQL, Oracle или IBM DB2.

Помимо синтаксических ошибок, при работе с большими объемами данных через ВИД сильно страдает производительность. Платформа не всегда способна оптимально переложить сложные фильтры и агрегации на сторону СУБД Firebird, из-за чего может инициировать избыточный трансфер «сырых» строк на сервер 1С для последующей локальной обработки.

Поэтому для надежной работы мы рекомендуем использовать проверенную схему прямого SQL-запроса через ADO с передачей данных в СКД.

Пошаговое решение: Схема «ADO — Таблица значений — СКД»

Давайте подробно разберем, как реализовать стабильный импорт данных. Наша задача — самостоятельно выполнить прямой SQL-запрос к Firebird, получить результат в виде COM-объекта, перенести его в Таблицу Значений 1С и скормить системе компоновки данных через Набор данных - объект.

Шаг 1. Подготовка схемы СКД

В первую очередь настроим макет нашего отчета:

  1. Откроем схему компоновки данных (СКД).
  2. Вместо привычного «Набора данных - запрос» добавим новый Набор данных - объект.
  3. Зададим имя для этого набора, например, ДанныеFirebird.
  4. Вручную опишем поля, которые мы планируем получить из внешней базы данных. Чрезвычайно важно точно указать имена полей и их типы данных (например, Идентификатор с типом Число, Контрагент с типом Строка, Сумма с типом Число). Эти поля будут доступны пользователю для группировок, отборов и сортировок так же, как и поля обычных таблиц 1С.

Шаг 2. Написание программного кода в модуле отчета

Перейдем в модуль отчета и переопределим стандартный вывод, чтобы самостоятельно управлять процессом компоновки результатов. Нам потребуется обработчик события ПриКомпоновкеРезультата.

Рассмотрим пример кода:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Отключаем стандартный вывод отчета платформой
    СтандартнаяОбработка = Ложь;
    
    // 1. Создаем подключение ADO к базе данных Firebird
    Соединение = Новый COMОбъект("ADODB.Connection");
    
    // Формируем строку подключения. 
    // Обратите внимание на явное указание кодировки подключения CHARSET!
    СтрокаПодключения = "Driver={Firebird/InterBase(r) driver};" 
                      + "DbName=192.168.1.100:C:\Database\Trade.fdb;" 
                      + "Uid=SYSDBA;" 
                      + "Pwd=masterkey;" 
                      + "CHARSET=WIN1251;";
                      
    Попытка
        Соединение.Open(СтрокаПодключения);
    Исключение
        ЗафиксироватьОшибку("Не удалось установить связь с СУБД Firebird. Проверьте сеть и настройки ODBC. " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // 2. Формируем запрос, используя родной синтаксис Firebird
    // Здесь мы без проблем можем использовать конструкции FIRST и SKIP
    ТекстЗапросаFB = "SELECT FIRST 500 ID, CLIENT_NAME, TOTAL_SUM FROM SALES ORDER BY ID DESC";
    
    НаборЗаписей = Новый COMОбъект("ADODB.Recordset");
    Попытка
        НаборЗаписей.Open(ТекстЗапросаFB, Соединение, 3, 1); // adOpenStatic, adLockReadOnly
    Исключение
        Соединение.Close();
        ЗафиксироватьОшибку("Ошибка при выполнении запроса к Firebird: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // 3. Создаем и подготавливаем Таблицу Значений 1С
    ТаблицаДанных = Новый ТаблицаЗначений;
    ТаблицаДанных.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Число"));
    ТаблицаДанных.Колонки.Добавить("Контрагент", Новый ОписаниеТипов("Строка"));
    ТаблицаДанных.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    
    // 4. Заполняем Таблицу Значений данными из полученного Recordset
    Пока НаборЗаписей.EOF() = 0 Цикл
        НоваяСтрока = ТаблицаДанных.Добавить();
        НоваяСтрока.Идентификатор = НаборЗаписей.Fields("ID").Value;
        НоваяСтрока.Контрагент = СокрЛП(Строка(НаборЗаписей.Fields("CLIENT_NAME").Value));
        НоваяСтрока.Сумма = Число(НаборЗаписей.Fields("TOTAL_SUM").Value);
        
        НаборЗаписей.MoveNext();
    КонецЦикла;
    
    // Закрываем внешние соединения сразу после импорта в ОЗУ
    НаборЗаписей.Close();
    Соединение.Close();
    
    // 5. Инициализируем стандартные механизмы компоновки 1С
    СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    // Передаем нашу ТЗ во внешние наборы данных по имени, которое мы указали в СКД
    ВнешниеНаборыДанных = Новый Структура;
    ВнешниеНаборыДанных.Вставить("ДанныеFirebird", ТаблицаДанных);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Альтернативное решение: Использование Linked Server на стороне MS SQL Server

Если сервер 1С:Предприятие работает в связке с СУБД Microsoft SQL Server, существует возможность использовать механизмы трансляции самого MS SQL для обхода ограничений синтаксиса. В этом случае мы сможем использовать привычные «Внешние источники данных» без переписывания логики на стороне 1С.

Рассмотрим этот алгоритм по шагам:

  1. На физическом сервере, где развернут MS SQL Server, устанавливается официальный ODBC-драйвер для Firebird соответствующей разрядности (обычно x64).
  2. В СУБД MS SQL Server настраивается Связанный сервер (Linked Server), указывающий на рабочую базу данных Firebird. Настройка осуществляется через SQL Server Management Studio (SSMS) в разделе Server Objects -> Linked Servers.
  3. В СУБД MS SQL создается представление (View) или синоним (Synonym), который обращается к связанному серверу Firebird через функцию удаленных запросов OPENQUERY. Эта функция позволяет передать чистый SQL-запрос во внутреннем диалекте Firebird, получить ответ и представить его для MS SQL как обычную таблицу.
  4. В платформе 1С внешний источник данных подключается не к самой СУБД Firebird напрямую, а к нашему серверу MS SQL. 1С будет обращаться к созданному представлению (View). Запросы 1С будут содержать стандартный синтаксис SELECT TOP, который MS SQL Server успешно отработает на своей стороне, а затем перенаправит отфильтрованные данные из Firebird.

Этот способ сложнее в первоначальном администрировании, однако он позволяет использовать СКД в стандартном режиме «Набор данных - запрос» без написания дополнительного программного кода.

Важные технические нюансы и подводные камни

При интеграции 1С с СУБД Firebird разработчики регулярно сталкиваются с неочевидными системными ошибками. Разберем ключевые проблемы и способы их устранения.

1. Проблема разрядности драйверов (32-bit против 64-bit)

Если при попытке инициализации COM-объекта или подключения внешнего источника вы получаете ошибку: [ODBC] Источник данных не найден и не указан драйвер, используемый по умолчанию, это признак несовпадения разрядности.

Помните золотое правило:

Настройку системных имен источников данных (DSN) на 64-битных операционных системах Windows следует выполнять аккуратно:

2. Проблема искажения кириллицы

Если после выгрузки отчета русские буквы в строках отображаются знаками вопроса или нечитаемой «кракозяброй», проблема кроется в кодировке соединения.

Для корректного импорта текстовых данных в строке подключения ADO (ConnectionString) обязательно указывайте параметр CHARSET. Для русскоязычных конфигураций баз данных Firebird практически всегда используется кодировка Windows-1251. В строке подключения это выглядит так: CHARSET=WIN1251;. Если база современная и спроектирована под стандарт Юникод, используйте CHARSET=UTF8;.

Подведем итоги

Мы проанализировали особенности интеграции 1С с базами данных Firebird. Прямое использование внешних источников данных ограничено несовместимостью синтаксиса СУБД, однако использование схемы ADO — Таблица значений — СКД позволяет полностью обойти эту проблему. Данный подход гарантирует высокую скорость работы за счет выполнения сложных выборок на стороне Firebird и предоставляет разработчику максимальную гибкость при оформлении отчетов средствами компоновки данных 1С.

← На главную