При разработке функционала для работы с системой «Честный знак» (ГИС МТ) программисты часто сталкиваются с архитектурной особенностью типовых конфигураций 1С (ERP, КА, УТ). Проблема заключается в том, что в справочнике ВидыНоменклатуры используется перечисление ОсобенностиУчетаНоменклатуры, а в регистре сведений НастройкиУчетаМаркируемойПродукцииИСМП — перечисление ВидыПродукцииИС. Несмотря на то что названия элементов (например, «Табак» или «Обувь») визуально идентичны, для платформы 1С это принципиально разные типы данных, которые невозможно связать простым условием соединения в запросе.
В этой статье мы подробно разберем, почему возникла такая ситуация, и рассмотрим несколько эффективных способов решения проблемы: от простых условий в тексте запроса до создания динамических таблиц соответствий.
Разберем причину разделения. Перечисление ОсобенностиУчетаНоменклатуры отвечает за внутреннюю логику системы 1С: как должны вести себя документы, нужно ли открывать форму подбора кодов маркировки и какие проверки выполнять. Перечисление ВидыПродукцииИС — это более «узкий» технический классификатор, предназначенный для прямого взаимодействия с API системы «Честный знак». Одна особенность учета в 1С (например, молочная продукция) может соответствовать нескольким видам продукции в ИС МП в зависимости от законодательных актов.
Проанализируем самый простой, но «жесткий» способ. Если список категорий маркируемого товара в вашей компании невелик и редко меняется, можно выполнить преобразование типов прямо в тексте запроса. Мы создадим виртуальное поле в первой таблице, которое будет иметь тот же тип, что и во второй.
Рассмотрим пример кода запроса:
ВЫБРАТЬ
ВидыНоменклатуры.Ссылка КАК ВидНоменклатуры,
ВЫБОР
КОГДА ВидыНоменклатуры.ОсобенностьУчета = ЗНАЧЕНИЕ(Перечисление.ОсобенностиУчетаНоменклатуры.Табак)
ТОГДА ЗНАЧЕНИЕ(Перечисление.ВидыПродукцииИС.Табак)
КОГДА ВидыНоменклатуры.ОсобенностьУчета = ЗНАЧЕНИЕ(Перечисление.ОсобенностиУчетаНоменклатуры.Обувь)
ТОГДА ЗНАЧЕНИЕ(Перечисление.ВидыПродукцииИС.ОбувнаяПродукция)
КОГДА ВидыНоменклатуры.ОсобенностьУчета = ЗНАЧЕНИЕ(Перечисление.ОсобенностиУчетаНоменклатуры.МолочнаяПродукция)
ТОГДА ЗНАЧЕНИЕ(Перечисление.ВидыПродукцииИС.МолочнаяПродукцияПодконтрольнаяВЕТИС)
ИНАЧЕ ЗНАЧЕНИЕ(Перечисление.ВидыПродукцииИС.ПустаяСсылка)
КОНЕЦ КАК ВидПродукцииДляСвязи
ПОМЕСТИТЬ ВТ_ВидыНоменклатуры
ИЗ
Справочник.ВидыНоменклатуры КАК ВидыНоменклатуры;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ.ВидНоменклатуры,
Настройки.ДатаКонтрольПроизводства
ИЗ
ВТ_ВидыНоменклатуры КАК ВТ
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиУчетаМаркируемойПродукцииИСМП КАК Настройки
ПО ВТ.ВидПродукцииДляСвязи = Настройки.ВидПродукции
Преимущества: не требует создания новых объектов метаданных.
Недостатки: при добавлении новых категорий маркировки в 1С (например, «Пиво» или «БАДЫ») запрос придется переписывать вручную.
Выясним, как сделать решение более гибким и эстетичным. Вместо жесткого кодинга в запросе, мы можем программно подготовить таблицу значений, где сопоставим два типа перечислений по их именам, и передать её в запрос как параметр.
Разберем алгоритм реализации по шагам:
Посмотрим на пример реализации на языке 1С:
// 1. Подготовка таблицы соответствия
ТаблицаСоответствия = Новый ТаблицаЗначений;
ТаблицаСоответствия.Колонки.Добавить("ОсобенностьУчета", Новый ОписаниеТипов("ПеречислениеСсылка.ОсобенностиУчетаНоменклатуры"));
ТаблицаСоответствия.Колонки.Добавить("ВидПродукцииИС", Новый ОписаниеТипов("ПеречислениеСсылка.ВидыПродукцииИС"));
// 2. Автоматическое заполнение по именам
Для Каждого ТекОсобенность Из Перечисления.ОсобенностиУчетаНоменклатуры Цикл
ИмяОсобенности = Метаданные.Перечисления.ОсобенностиУчетаНоменклатуры.ЗначенияПеречисления[Перечисления.ОсобенностиУчетаНоменклатуры.Индекс(ТекОсобенность)].Имя;
// Пытаемся найти одноименное значение в другом перечислении
Попытка
ВидИС = Перечисления.ВидыПродукцииИС[ИмяОсобенности];
НоваяСтрока = ТаблицаСоответствия.Добавить();
НоваяСтрока.ОсобенностьУчета = ТекОсобенность;
НоваяСтрока.ВидПродукцииИС = ВидИС;
Исключение
// Если имена не совпадают (например, Обувь vs ОбувнаяПродукция), прописываем исключения вручную
Если ИмяОсобенности = "Обувь" Тогда
НоваяСтрока = ТаблицаСоответствия.Добавить();
НоваяСтрока.ОсобенностьУчета = ТекОсобенность;
НоваяСтрока.ВидПродукцииИС = Перечисления.ВидыПродукцииИС.ОбувнаяПродукция;
КонецЕсли;
КонецПопытки;
КонецЦикла;
// 3. Передача в запрос
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Соответствие ИЗ &ТаблицаСоответствия КАК ТаблицаСоответствия;
|
|ВЫБРАТЬ
| ВидыНоменклатуры.Ссылка,
| Настройки.ДатаКонтрольПроизводства
|ИЗ
| Справочник.ВидыНоменклатуры КАК ВидыНоменклатуры
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Соответствие КАК Соответствие
| ПО ВидыНоменклатуры.ОсобенностьУчета = Соответствие.ОсобенностьУчета
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиУчетаМаркируемойПродукцииИСМП КАК Настройки
| ПО Соответствие.ВидПродукцииИС = Настройки.ВидПродукции";
Запрос.УстановитьПараметр("ТаблицаСоответствия", ТаблицаСоответствия);
Результат = Запрос.Выполнить();
Проанализируем возможности типовых конфигураций. В современных версиях ERP и УТ уже существуют общие модули, которые занимаются этим преобразованием. Прежде чем писать свой велосипед, проверьте наличие функций в модуле МаркировкаТоваровИСПеречисления или ИнтеграцияИСМП.
Часто встречается функция вида ВидПродукцииПоОсобенностиУчета(ОсобенностьУчета). Вы можете использовать её в цикле перед формированием запроса, чтобы собрать массив нужных видов продукции и передать его в условие ГДЕ ВидПродукции В (&МассивВидов).
При проверке дат начала прослеживаемости через регистр НастройкиУчетаМаркируемойПродукцииИСМП следует учитывать несколько критических моментов:
ЛЕВОЕ СОЕДИНЕНИЕ вместо ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Если для какой-то категории продукции настройка в регистре еще не создана, при внутреннем соединении этот товар просто исчезнет из выборки, что может привести к ошибкам в логике отчета или обработки.01.01.0001 считается отсутствием ограничения. Проверяйте условие ДатаКонтроль > &ТекущаяДата или наличие заполненной даты.ВестиУчетМаркируемойПродукции..., которые кэшируются системой и работают быстрее тяжелых запросов.Если вам часто требуется связывать эти данные в разных частях системы, лучшим решением будет создание Служебного Регистра Сведений (например, СоответствиеКатегорийМаркировки). Вы можете заполнить его один раз (автоматически при обновлении или вручную) и использовать во всех запросах. Это избавит вас от необходимости передавать таблицы параметров и сделает ваши запросы максимально читаемыми и производительными.
Таким образом, мы выяснили, что проблема разных типов — это не ошибка, а следствие разделения бизнес-логики и интеграционных механизмов. Используя метод временных таблиц или программного маппинга, вы сможете создавать надежные и легко поддерживаемые решения для работы с маркируемым товаром.