При работе с механизмами интеграции 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С:Управление торговлей отображение серий в остатках напрямую зависит от настройки Политики учета серий для конкретного вида номенклатуры.
Рассмотрим варианты настроек политики:
Остатки регистра ТоварыНаСкладах измерение Серия всегда будет пустым. Данные в этом случае нужно искать в регистре сведений ДвиженияСерийТоваров.ТоварыНаСкладах.Остатки обязан возвращать заполненное поле Серия.Посмотрим на пример правильного запроса через COM, учитывающий контекст внешней базы:
// Создаем запрос правильно
ЗапросВнешний = Соединение.NewObject("Запрос");
ЗапросВнешний.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура.Наименование КАК НомНаименование,
| Остатки.Серия.Номер КАК СерияНомер,
| Остатки.Серия.ГоденДо КАК ГоденДо,
| Остатки.ВНаличииОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК Остатки";
ЗапросВнешний.УстановитьПараметр("Период", ТекущаяДата());
Результат = ЗапросВнешний.Выполнить();
Выборка = Результат.Выбрать();
Проанализируем еще один важный момент: передачу параметров. Если мы хотим отфильтровать запрос по конкретному виду номенклатуры или складу, мы не можем просто написать:
ЗапросВнешний.УстановитьПараметр("Склад", СсылкаНаСкладИзТекущейБазы);
Это не сработает, так как СсылкаНаСкладИзТекущейБазы принадлежит нашей базе, а внешний запрос «не знает» об этом объекте. Чтобы фильтрация сработала, мы должны передать либо примитивный тип (строку, число, дату), либо найти объект внутри внешнего соединения.
Разберем по шагам, как передать ссылку во внешний запрос:
СтрГУИД = Строка(СкладСсылка.УникальныйИдентификатор());.ВнешняяСсылка = Соединение.Справочники.Склады.ПолучитьСсылку(Соединение.NewObject("UUID", СтрГУИД));.ВнешняяСсылка в параметр запроса.Если выяснилось, что в базе используется «Справочное указание серий», то запрос к остаткам нам не поможет. Нам нужно проанализировать обороты или движения. В УТ 11 для таких целей предусмотрен регистр сведений ДвиженияСерийТоваров.
Этот регистр хранит записи о том, какая серия была указана в конкретном документе поступления или реализации. Чтобы собрать «остатки» по справочным сериям, придется анализировать приходы и расходы по этому регистру в связке с документами-регистраторами. Однако стоит помнить, что математически точного остатка по справочным сериям в системе может не быть, так как контроль остатков по ним не ведется.
При переходе с версии 11.4 на 11.5 структура метаданных в части серий практически не изменилась, но изменились механизмы работы распределения запасов. Если вы планируете не просто разово выгрузить данные, а настроить постоянный обмен, рекомендуем обратить внимание на следующие объекты:
ВидНоменклатуры, либо сама Номенклатура (в зависимости от настроек). При левом соединении в запросе это может быть критично для производительности.Важный совет: При отладке запросов через COM всегда проверяйте тип возвращаемого значения. Если вы получаете COMОбъект, это значит, что ссылка успешно передана. Если же вы видите Неопределено или пустую строку при обращении к реквизитам, скорее всего, объект не был найден во внешней базе или запрос выполняется в контексте текущей базы, где данные отсутствуют.
Используя предложенные методы проверки инициализации объектов и понимание политики учета серий, вы сможете избежать ошибок при интеграции и обеспечите корректный перенос данных между конфигурациями семейства «Управление торговлей».