При интеграции двух баз 1С:Предприятия 7.7 часто возникает необходимость быстро извлечь данные из внешней базы. Разработчики нередко пытаются комбинировать механизм OLE Automation (V77.Application) и класс прямых запросов. Однако при таком подходе возникают ошибки передачи типов между процессами, а также падает общая производительность. Разберем, почему возникает ошибка при работе через OLE, как правильно организовать прямой доступ к внешней базе данных DBF и с какими ограничениями можно столкнуться при типизации полей.
Проанализируем исходную проблему. При создании объекта внешнего приложения через V77.Application создается отдельный процесс Windows со своим адресным пространством. Когда мы выполняем прямой запрос внутри OLE-базы:
Запрос = ВнешняяБаза.CreateObject("Класс.ПрямойЗапрос");
Рез = Запрос.Выполнить("ТаблицаЗначений", ТекстЗапроса);
Рез.Выгрузить(Экран);
Метод Выполнить() возвращает объект ТаблицаЗначений, созданный в контексте внешней базы (как COM-объект IDispatch). Локальные элементы диалога и встроенные методы текущей сессии 1С не могут напрямую работать с внутренней памятью удаленного COM-объекта, из-за чего платформа выдает ошибку Плохой тип переменной.
Для передачи таблицы значений через OLE потребовалась бы сериализация через строку (ЗначениеВСтрокуВнутр() во внешней базе и ЗначениеИзСтрокиВнутр() в текущей) либо промежуточная выгрузка во временный файл, что сводит на нет преимущества высокой скорости прямых запросов.
Выясним более эффективный путь: для выполнения прямого запроса ко второй базе вовсе не обязательно запускать саму 1С 7.7 через OLE. Классы прямого доступа (например, из внешней компоненты 1С++ через провайдеры ODBC или OLE DB) позволяют подключаться напрямую к каталогу таблиц внешней базы данных.
Рассмотрим ключевые преимущества такого подхода:
1cv7s.exe, проверку лицензий и инициализацию интерфейса.ТаблицаЗначений или ИндексированнаяТаблица текущей базы.При составлении текста запроса к внешней файловой базе важно помнить о структуре хранения данных в DBF-версии 1С 7.7. Рассмотрим разницу между SQL и файловым форматом:
_1SJOURN, _1SBLKS.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 текущей (локальной) конфигурации. Это приводит к следующим особенностям:
Посмотрим, как извлекать идентификаторы объектов в виде простых строк (в формате Base36):
ТекстЗапроса = "
|SELECT
| Жур.IDDOC as ИдентификаторДокумента,
| Жур.IDDOCDEF as ИдентификаторВида,
| Жур.@ОбщийРеквизит.IDD as IDDВудаленнойБазе
|FROM
| База2.1SJOURN as Жур
|WHERE
| Жур.IDDOCDEF = @ВидДокумента.ПоступлениеДопРасходы
|";
Полученные строковые идентификаторы (Base36 длиной 9 или 13 символов) и уникальные реквизиты (например, глобальный код IDD) позволяют однозначно идентифицировать и сопоставить записи между базами без создания чужих типизированных объектов в локальной памяти.
При организации прямых запросов к внешним файловым базам необходимо учитывать следующие технические аспекты:
Microsoft Visual FoxPro Driver или VFPOLEDB) обязательно должны быть установлены в 32-битной версии подсистемы Windows.