Как выполнить прямой запрос из 1С 7.7 к другой базе 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции двух баз 1С:Предприятия 7.7 часто возникает необходимость быстро извлечь данные из внешней базы. Разработчики нередко пытаются комбинировать механизм OLE Automation (V77.Application) и класс прямых запросов. Однако при таком подходе возникают ошибки передачи типов между процессами, а также падает общая производительность. Разберем, почему возникает ошибка при работе через OLE, как правильно организовать прямой доступ к внешней базе данных DBF и с какими ограничениями можно столкнуться при типизации полей.

Причина ошибки «Плохой тип переменной» при работе через OLE

Проанализируем исходную проблему. При создании объекта внешнего приложения через V77.Application создается отдельный процесс Windows со своим адресным пространством. Когда мы выполняем прямой запрос внутри OLE-базы:


Запрос = ВнешняяБаза.CreateObject("Класс.ПрямойЗапрос");
Рез = Запрос.Выполнить("ТаблицаЗначений", ТекстЗапроса);
Рез.Выгрузить(Экран);

Метод Выполнить() возвращает объект ТаблицаЗначений, созданный в контексте внешней базы (как COM-объект IDispatch). Локальные элементы диалога и встроенные методы текущей сессии 1С не могут напрямую работать с внутренней памятью удаленного COM-объекта, из-за чего платформа выдает ошибку Плохой тип переменной.

Для передачи таблицы значений через OLE потребовалась бы сериализация через строку (ЗначениеВСтрокуВнутр() во внешней базе и ЗначениеИзСтрокиВнутр() в текущей) либо промежуточная выгрузка во временный файл, что сводит на нет преимущества высокой скорости прямых запросов.

Прямой запрос к внешней базе без использования OLE

Выясним более эффективный путь: для выполнения прямого запроса ко второй базе вовсе не обязательно запускать саму 1С 7.7 через OLE. Классы прямого доступа (например, из внешней компоненты 1С++ через провайдеры ODBC или OLE DB) позволяют подключаться напрямую к каталогу таблиц внешней базы данных.

Рассмотрим ключевые преимущества такого подхода:

  1. Скорость работы: нет необходимости тратить время и ресурсы сервера на запуск процесса 1cv7s.exe, проверку лицензий и инициализацию интерфейса.
  2. Экономия лицензий: OLE-подключение занимает пользовательскую лицензию, тогда как прямое чтение файлов базы данных работает на уровне дисковых операций.
  3. Прямая загрузка в локальные объекты: результат запроса сразу формируется как локальная ТаблицаЗначений или ИндексированнаяТаблица текущей базы.

Особенности именования таблиц в DBF-базах

При составлении текста запроса к внешней файловой базе важно помнить о структуре хранения данных в DBF-версии 1С 7.7. Рассмотрим разницу между SQL и файловым форматом:

  1. В SQL-версиях имена служебных таблиц начинаются со знака подчеркивания, например _1SJOURN, _1SBLKS.
  2. В DBF-версиях файлы таблиц на диске не содержат нижнего подчеркивания в начале имени: 1SJOURN.DBF, SC*.DBF, DH*.DBF, DT*.DBF.

Посмотрим на пример запроса к журналу документов внешней базы База2:


// В файловой базе DBF имя таблицы пишется без подчеркивания:
ТекстЗапроса = "
|SELECT 
|   Жур.IDDOC as [Документ $Документ],
|   Жур.DOCNO as Номер,
|   Жур.DATE_TIME_IDDOC as ДатаДокумента
|FROM 
|   База2.1SJOURN AS Жур
|WHERE 
|   Жур.CLOSED = 0
|";

Если в запросе к DBF-базе указать имя таблицы с подчеркиванием (например, База2._1SJOURN), драйвер базы данных выдаст ошибку отсутствия файла таблицы.

Нюансы типизации данных из внешней базы

Разберем частую проблему: попытку типизировать поля внешней базы с помощью метаданных (конструкции вида $Справочник.Имя или $Документ.Имя).

Транслятор метаданных в прямых запросах анализирует исключительно файл 1Cv7.MD текущей (локальной) конфигурации. Это приводит к следующим особенностям:

  1. Несовпадение метаданных: если структуры двух баз различаются (другой набор реквизитов, другие идентификаторы видов документов и справочников), типизация вернет пустые значения или завершится ошибкой парсера.
  2. Идентичные базы (архивные копии): типизация через метаданные сработает корректно только в том случае, если внешняя база является точным клоном текущей (например, архивной базой за прошлый год с одинаковым файлом конфигурации).
  3. Работа с сырыми данными: при запросе к отличной по структуре базе поля ссылок следует считывать как базовые типы данных — строки и числа.

Посмотрим, как извлекать идентификаторы объектов в виде простых строк (в формате Base36):


ТекстЗапроса = "
|SELECT 
|   Жур.IDDOC as ИдентификаторДокумента,
|   Жур.IDDOCDEF as ИдентификаторВида,
|   Жур.@ОбщийРеквизит.IDD as IDDВудаленнойБазе
|FROM 
|   База2.1SJOURN as Жур
|WHERE 
|   Жур.IDDOCDEF = @ВидДокумента.ПоступлениеДопРасходы
|";

Полученные строковые идентификаторы (Base36 длиной 9 или 13 символов) и уникальные реквизиты (например, глобальный код IDD) позволяют однозначно идентифицировать и сопоставить записи между базами без создания чужих типизированных объектов в локальной памяти.

Системные требования и блокировки

При организации прямых запросов к внешним файловым базам необходимо учитывать следующие технические аспекты:

  1. Разрядность драйверов: платформа 1С 7.7 является 32-разрядным приложением (x86). Используемые драйверы (например, Microsoft Visual FoxPro Driver или VFPOLEDB) обязательно должны быть установлены в 32-битной версии подсистемы Windows.
  2. Кодировка таблиц: таблицы DBF в 1С 7.7 могут храниться в кодировке Windows (CP1251) или DOS (CP866). В строке соединения или параметрах источника данных следует явно указывать кодовую страницу, чтобы избежать искажения строковых реквизитов.
  3. Монопольный режим: если внешняя база открыта пользователем монопольно, стандартный механизм файлового доступа Windows может заблокировать открытие DBF-файлов на чтение. Для работы в таких условиях требуется использование библиотек с флагами совместного чтения файлов.
← На главную