Почему не выбираются серии номенклатуры при запросе через COM-соединение в 1С:Управление торговлей?

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

При работе с механизмами интеграции 1С часто возникает необходимость получить данные из одной информационной базы в другую. Одним из самых популярных способов является использование COM-соединения (V83.COMConnector). Однако при переносе данных или сверке остатков, особенно в таких сложных конфигурациях, как «Управление торговлей» (УТ 11), разработчики часто сталкиваются с тем, что специфические поля, такие как Серии номенклатуры, возвращаются пустыми, хотя в интерфейсе программы они видны. Рассмотрим подробнее, почему это происходит и как правильно организовать получение данных через OLE/COM.

Анализ основной ошибки: Переопределение объекта Запрос

Разберем типичную ситуацию, с которой столкнулся автор темы. Программист пытается подключиться из УТ 11.5 к старой базе УТ 11.4, чтобы выгрузить остатки с сериями. Проанализируем фрагмент кода, который стал причиной «замыленного глаза»:


// Подключаемся к внешней базе
Соединение = ПодключитьсяКбазе();  

// Создаем объект Запрос во внешней базе
Запрос114 = Соединение.NewObject("Запрос");  

// КРИТИЧЕСКАЯ ОШИБКА: переопределение объекта локальным
Запрос114 = Новый Запрос; 

Запрос114.Текст = "ВЫБРАТЬ ... ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(...)";

В чем здесь заключается подвох? Сначала переменной Запрос114 назначается объект, созданный в контексте внешней базы через Соединение.NewObject("Запрос"). Но следующей же строчкой разработчик пишет Запрос114 = Новый Запрос. В этот момент ссылка на внешний объект теряется, и Запрос114 становится обычным локальным запросом текущей базы (УТ 11.5).

Выясним причину, почему это приводит к «пустым сериям». Поскольку запрос выполняется в текущей базе, он ищет остатки в локальном регистре ТоварыНаСкладах. Если в текущей базе данных по этим складам или номенклатуре еще нет (или серии не были перенесены), результатом будет пустая выборка или выборка без серий. Если же данные частично совпадают по ГУИДам, запрос может что-то вернуть, но поле Серия все равно окажется пустой ссылкой, так как объекты серий в разных базах — это разные сущности с разными внутренними идентификаторами.

Правильный подход: объект запроса должен создаваться строго один раз через COM-соединение, и все его методы (установка параметров, выполнение) должны вызываться именно у этого объекта.

Влияние политики учета серий на результат запроса

Если после исправления кода серии всё равно приходят пустыми, нам необходимо проанализировать настройки учета в самой конфигурации УТ 11.4/11.5. В системе 1С:Управление торговлей отображение серий в остатках напрямую зависит от настройки Политики учета серий для конкретного вида номенклатуры.

Рассмотрим варианты настроек политики:

  1. Справочное указание серий: В этом режиме серия указывается только в документах (в табличных частях), но она не записывается в регистры накопления. Следовательно, в виртуальной таблице Остатки регистра ТоварыНаСкладах измерение Серия всегда будет пустым. Данные в этом случае нужно искать в регистре сведений ДвиженияСерийТоваров.
  2. Учет остатков серий: Это «честный» складской учет, при котором серия становится полноценным измерением. В этом случае запрос к ТоварыНаСкладах.Остатки обязан возвращать заполненное поле Серия.
  3. Учет себестоимости по сериям: Аналогично учету остатков, данные присутствуют в регистрах, так как системе нужно разделять стоимость каждой партии/серии.

Посмотрим на пример правильного запроса через COM, учитывающий контекст внешней базы:


// Создаем запрос правильно
ЗапросВнешний = Соединение.NewObject("Запрос");
ЗапросВнешний.Текст = 
"ВЫБРАТЬ
|   Остатки.Номенклатура.Наименование КАК НомНаименование,
|   Остатки.Серия.Номер КАК СерияНомер,
|   Остатки.Серия.ГоденДо КАК ГоденДо,
|   Остатки.ВНаличииОстаток КАК Количество
|ИЗ
|   РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК Остатки";

ЗапросВнешний.УстановитьПараметр("Период", ТекущаяДата());
Результат = ЗапросВнешний.Выполнить();
Выборка = Результат.Выбрать();

Особенности передачи параметров через COM-соединение

Проанализируем еще один важный момент: передачу параметров. Если мы хотим отфильтровать запрос по конкретному виду номенклатуры или складу, мы не можем просто написать:

ЗапросВнешний.УстановитьПараметр("Склад", СсылкаНаСкладИзТекущейБазы);

Это не сработает, так как СсылкаНаСкладИзТекущейБазы принадлежит нашей базе, а внешний запрос «не знает» об этом объекте. Чтобы фильтрация сработала, мы должны передать либо примитивный тип (строку, число, дату), либо найти объект внутри внешнего соединения.

Разберем по шагам, как передать ссылку во внешний запрос:

  1. Получаем уникальный идентификатор (GUID) объекта в текущей базе: СтрГУИД = Строка(СкладСсылка.УникальныйИдентификатор());.
  2. Во внешней базе восстанавливаем ссылку по этому ГУИДу: ВнешняяСсылка = Соединение.Справочники.Склады.ПолучитьСсылку(Соединение.NewObject("UUID", СтрГУИД));.
  3. Передаем ВнешняяСсылка в параметр запроса.

Регистр «Движения серий товаров» как альтернативный источник

Если выяснилось, что в базе используется «Справочное указание серий», то запрос к остаткам нам не поможет. Нам нужно проанализировать обороты или движения. В УТ 11 для таких целей предусмотрен регистр сведений ДвиженияСерийТоваров.

Этот регистр хранит записи о том, какая серия была указана в конкретном документе поступления или реализации. Чтобы собрать «остатки» по справочным сериям, придется анализировать приходы и расходы по этому регистру в связке с документами-регистраторами. Однако стоит помнить, что математически точного остатка по справочным сериям в системе может не быть, так как контроль остатков по ним не ведется.

Специфика версий 11.4 и 11.5

При переходе с версии 11.4 на 11.5 структура метаданных в части серий практически не изменилась, но изменились механизмы работы распределения запасов. Если вы планируете не просто разово выгрузить данные, а настроить постоянный обмен, рекомендуем обратить внимание на следующие объекты:

Важный совет: При отладке запросов через COM всегда проверяйте тип возвращаемого значения. Если вы получаете COMОбъект, это значит, что ссылка успешно передана. Если же вы видите Неопределено или пустую строку при обращении к реквизитам, скорее всего, объект не был найден во внешней базе или запрос выполняется в контексте текущей базы, где данные отсутствуют.

Используя предложенные методы проверки инициализации объектов и понимание политики учета серий, вы сможете избежать ошибок при интеграции и обеспечите корректный перенос данных между конфигурациями семейства «Управление торговлей».

← На главную