Почему запрос через OLE/COM (V83.ComConnector) возвращает пустой результат и как отлаживать внешние соединения?

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

В практике интеграции систем на платформе 1С:Предприятие часто возникает необходимость связать legacy-системы (например, базы на платформе 1С 7.7) с современными конфигурациями на платформе 1С 8.3. Наиболее быстрым и производительным способом для этого является использование технологии OLE/COM через компонент V83.ComConnector.

Однако при работе с внешними соединениями разработчики часто сталкиваются со странным поведением запросов: в консоли запросов на стороне 1С 8.3 данные выбираются корректно, а при выполнении того же запроса через COM-соединение возвращается пустая выборка. В этой статье мы подробно разберем, почему возникает такая проблема, как правильно передавать параметры в COM-запросы, и разрушим миф о том, что внешние соединения невозможно отлаживать.

---

Причина 1: Административная ошибка (подключение к неактуальной базе)

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

Проанализируем, как можно программно защититься от этой ошибки на стороне 1С 7.7 при инициализации соединения. Рекомендуется выводить в лог или на экран параметры базы, к которой произошло фактическое подключение:


// Пример проверки имени базы данных на стороне 1С 7.7
СтрокаСоединения = "Srvr=""Server1C"";Ref=""WorkDB"";";
Попытка
    V8 = СоздатьОбъект("V83.ComConnector");
    Соединение = V8.Connect(СтрокаСоединения);
    
    // Получим имя текущей базы данных для сверки
    ИмяБазыПриемника = Соединение.СтрокаСоединенияИнформационнойБазы();
    Предупреждение("Успешное подключение к базе: " + ИмяБазыПриемника, 2);
Исключение
    Предупреждение("Ошибка подключения: " + ОписаниеОшибки());
КонецПопытки;

---

Причина 2: Проблема «нулевой секунды» при фильтрации по датам

В запросе автора темы используется жесткое ограничение по периоду:

ЦеныНоменклатуры.Период МЕЖДУ ДатаВремя(2019,10,30) И ДатаВремя(2019,10,30)

Разберем, к чему приводит такая конструкция. Функция ДатаВремя(2019,10,30) создает дату с нулевым временем, то есть 30.10.2019 00:00:00. Таким образом, условие МЕЖДУ фактически ищет записи, которые были записаны строго в первую секунду дня — 30 октября 2019 года ровно в полночь.

Если в регистр сведений данные записываются регистратором (документом), то время записи всегда будет соответствовать времени проведения документа (например, 30.10.2019 14:35:22). Такие записи гарантированно не попадут в указанный интервал. Чтобы избежать этой проблемы, всегда указывайте конечную границу периода с точностью до секунды или используйте параметры.

Правильный вариант фильтрации за день в тексте запроса:

ЦеныНоменклатуры.Период МЕЖДУ ДатаВремя(2019,10,30,0,0,0) И ДатаВремя(2019,10,30,23,59,59)

---

Причина 3: Использование строковых фильтров (ПОДОБНО) и правильная параметризация

В исходном запросе автора присутствует крайне неоптимальная конструкция фильтрации по наименованию вида цен:

И ЦеныНоменклатуры.ВидЦены.Наименование ПОДОБНО "Розница"

Использование текстового оператора ПОДОБНО (аналог LIKE в SQL) для фильтрации ссылочных типов — это грубейшая ошибка проектирования по нескольким причинам:

Выясним, как правильно передавать ссылки в качестве параметров через COM-границу. Передавать напрямую объекты ссылочных типов из 1С 7.7 в 1С 8.3 невозможно из-за различия архитектур платформ. Однако мы можем найти нужный объект на стороне 1С 8.3 через COM-соединение, а затем передать полученную COM-ссылку в качестве параметра запроса.

Рассмотрим правильный шаблон реализации этой логики на стороне 1С 7.7:


// 1. Находим нужный элемент справочника на стороне 1С 8.3 через COM
ВидЦеныСсылка = Соединение.Справочники.ВидыЦен.НайтиПоНаименованию("Розница");

Если Соединение.ЗначениеЗаполнено(ВидЦеныСсылка) = 0 Тогда
    Предупреждение("Вид цены 'Розница' не найден в базе 1С 8.3!");
    Возврат;
КонецЕсли;

// 2. Создаем объект запроса
Запрос8 = Соединение.NewObject("Query");
Запрос8.Текст = 
"ВЫБРАТЬ
|   ЦеныНоменклатуры.Регистратор КАК Ссылка,
|   ЦеныНоменклатуры.Цена КАК Цена,
|   ЦеныНоменклатуры.Номенклатура.Наименование КАК НоменклатураНаименование
|ИЗ
|   РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
|ГДЕ
|   ЦеныНоменклатуры.Период МЕЖДУ &НачалоПериода И &КонецПериода
|   И ЦеныНоменклатуры.ВидЦены = &ВидЦены";

// 3. Устанавливаем типизированные параметры
// Передаем даты (строковый формат 1С 7.7 автоматически преобразуется в дату 1С 8.3 через COM)
Запрос8.УстановитьПараметр("НачалоПериода", '20191030000000'); 
Запрос8.УстановитьПараметр("КонецПериода", '20191030235959');
// Передаем COM-ссылку, полученную на шаге 1
Запрос8.УстановитьПараметр("ВидЦены", ВидЦеныСсылка);

Выборка = Запрос8.Выполнить().Выбрать();
Пока Выборка.Следующий() = 1 Цикл
    Сообщить("Товар: " + Выборка.НоменклатураНаименование + " | Цена: " + Выборка.Цена);
КонецЦикла;

---

Причина 4: Как настроить и запустить отладку внешнего COM-соединения?

Существует распространенное заблуждение (отраженное в сообщении №10 на форуме), что отладить код или посмотреть результаты выполнения запроса при обращении из стороннего приложения через COM-соединение невозможно. Это не так. Платформа 1С 8.3 полностью поддерживает сквозную отладку внешних соединений.

Разберем по шагам, как настроить сервер и конфигуратор для перехвата управления в точках останова при COM-вызовах:

Шаг 1. Включение отладки на сервере приложений 1С

Если ваша база 1С 8.3 работает в клиент-серверном режиме, сервер приложений должен быть запущен с разрешением отладки. Для Windows-службы в реестре в параметрах запуска службы 1C:Enterprise 8.3 Server Agent должен присутствовать ключ -debug. Для Linux-сервера в конфигурационном файле должна быть установлена переменная SRV1CV8_DEBUG=1.

Шаг 2. Создание файла comcntrcfg.xml

Для того чтобы COM-процесс на стороне клиента «знал», куда отправлять отладочную информацию, необходимо создать конфигурационный файл с именем comcntrcfg.xml. Этот файл нужно разместить на том компьютере, где запускается база 1С 7.7, инициирующая подключение.

Путь для размещения файла (для 64-разрядной версии платформы 1С 8):
C:\Program Files\1cv8\conf\comcntrcfg.xml

Содержимое файла comcntrcfg.xml должно быть следующим:


<config xmlns="http://v8.1c.ru/v8/comcntrcfg">
  <debugconfig debug="true" protocol="tcp" debuggerURL="tcp://localhost:1562"/>
</config>

В параметре debuggerURL укажите адрес компьютера, на котором запущен ваш Конфигуратор 1С 8.3, и порт отладки (по умолчанию используется порт 1562 для протокола TCP).

Шаг 3. Настройка автоматического подключения в Конфигураторе 1С 8

  1. Откройте Конфигуратор целевой базы 1С 8.3.
  2. Перейдите в меню Отладка -> Подключение....
  3. В открывшемся окне нажмите кнопку Автоматическое подключение.
  4. Установите флажок напротив пункта Внешние соединения на сервере (или Клиентские и внешние соединения на сервере).
  5. Нажмите ОК.

Теперь вы можете поставить точку останова в любом общем модуле (у которого взведен флаг «Внешнее соединение») или в МодулеВнешнегоСоединения. Как только код из 1С 7.7 обратится к методам 1С 8.3 через COM, выполнение приостановится на точке останова, и вы сможете использовать табло, вычислять любые выражения и анализировать результаты запросов в реальном времени.

---

Причина 5: Как перехватить «сырой» текст запроса на стороне СУБД

Если настроить отладчик по каким-то причинам невозможно (например, на рабочем сервере запрещено включать режим отладки), вы можете перехватить текст запроса и проанализировать возвращаемые им данные с помощью технологических инструментов.

Рассмотрим два наиболее эффективных метода:

1. Использование Технологического журнала (ТЖ) платформы 1С

Вы можете настроить ТЖ на сервере 1С для логирования событий баз данных (SDBL). Для этого создайте файл logcfg.xml в каталоге C:\Program Files\1cv8\conf\ на сервере 1С со следующим содержимым:


<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/techlog/logcfg">
  <log location="C:\v8logs\com_queries" history="24">
    <event>
      <eq property="Name" value="DBMSSQL"/>
    </event>
    <event>
      <eq property="Name" value="SDBL"/>
    </event>
    <property name="all"/>
  </log>
</config>

Платформа запишет в лог все запросы к СУБД MS SQL Server, включая те, что приходят из COM-сессий. Вы сможете увидеть точный SQL-текст запроса, количество задействованных таблиц и строк в результате выборки.

2. Трассировка средствами SQL Server Profiler

Поскольку внешнее соединение под капотом обращается к SQL-серверу, запустите утилиту SQL Server Profiler (для MS SQL). Настройте фильтр по имени базы данных и типу события SQL:BatchCompleted. При запуске COM-запроса из 1С 7.7 вы увидите чистый SQL-запрос, отправленный процессом rphost. Это позволит моментально определить, какие именно условия на даты или виды цен были переданы на уровень СУБД.

---

Различия между V83.ComConnector и V83.Application

В завершение разберем важный нюанс использования COM-технологий. Для программного взаимодействия между базами часто используют два разных класса: V83.ComConnector и V83.Application. Понимание разницы между ними критично для стабильности интеграционного решения.

Критерий оценки V83.ComConnector V83.Application
Тип процесса Внутрипроцессный сервер (in-process). Выполняется в адресном пространстве вызывающей программы (или dllhost). Внепроцессный сервер (out-of-process). Запускает полноценный фоновый процесс 1cv8.exe.
Потребление ресурсов Минимальное. Не загружает графическую подсистему, формы и лишние библиотеки. Высокое. Потребляет сотни мегабайт оперативной памяти на каждый сеанс.
Инициализация модулей Выполняется только МодульВнешнегоСоединения. Инициализация интерфейсных модулей игнорируется. Выполняются абсолютно все модули: МодульПриложения, МодульУправляемогоПриложения, заполняются глобальные переменные.
Скорость работы Максимально высокая. Идеально подходит для бэкэнд-интеграций и вызова серверных методов. Низкая за счет длительного времени старта тяжелого EXE-процесса.

Таким образом, выбор автора темы в пользу V83.ComConnector абсолютно оправдан. Соблюдая правила типизации параметров запроса и умея правильно настраивать сквозную отладку, вы сможете легко диагностировать и решать любые проблемы обмена данными.

← На главную