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