Почему СКД в 1С:ERP автоматически меняет запрос и как сохранить нулевые значения?

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

При работе с подсистемой бюджетирования в 1С:ERP программисты часто сталкиваются с ситуацией, когда Система компоновки данных (СКД) ведет себя непредсказуемо. Вы создаете простой запрос, который должен вернуть все записи справочника Номенклатура с их весовыми характеристиками, включая те, где вес не указан или равен нулю. Однако при выполнении отчета или получении данных для бюджетирования система «самовольно» добавляет в запрос условия типа ВЫБОР... <> 0 или ЕСТЬ НЕ NULL. Разберемся, почему это происходит и как усмирить «железяку».

Механизм трансформации запроса в СКД

Важно понимать, что итоговый запрос, который отправляется к базе данных (SQL), формируется не текстом из схемы компоновки, а специальным объектом — Компоновщиком макета. Процесс выглядит следующим образом: компоновщик берет вашу Схему компоновки данных и накладывает на нее Настройки компоновки данных (отборы, параметры, выбранные поля). Проанализируем, почему на этом этапе появляются лишние условия.

Рассмотрим типичный код, который используется для получения итогового текста запроса в целях отладки:


МакетКД = КомпоновщикМакета.Выполнить(СхемаСКД, КомпоновщикНастроек.ПолучитьНастройки());
НаборДанных = МакетКД.НаборыДанных.Найти(ИмяНабораДанных);
ТекстЗапроса = НаборДанных.Запрос;

В этот момент СКД анализирует не только текст запроса, но и метаданные, а также логику использования полей.

Причина 1: Скрытые настройки в ролях полей

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

  1. Флаг «Игнорировать значения NULL»: Если этот флажок установлен в роли поля, компоновщик автоматически добавит условие ГДЕ Поле ЕСТЬ НЕ NULL в итоговый запрос.
  2. Обязательное поле: Если поле помечено как обязательное, СКД будет стараться отсечь пустые результаты, чтобы оптимизировать выполнение.

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

Причина 2: Программная модификация в 1С:ERP (Бюджетирование)

В случае с подсистемой бюджетирования в 1С:ERP проблема чаще всего кроется не в самой СКД, а в программном коде конфигурации (БСП и модули бюджетирования). Рассмотрим ситуацию: вы создали правило получения данных, в котором выбрали схему СКД. Перед тем как выполнить запрос, система программно подготавливает настройки.

Подсистема бюджетирования спроектирована так, чтобы не перегружать регистры и таблицы «пустыми» записями. Поэтому код ERP часто делает следующее:

  1. Обходит коллекцию КомпоновщикНастроек.Настройки.Отбор.
  2. Программно добавляет элемент отбора: ЗначениеПоказателя Не равно 0.

Поскольку этот отбор добавляется в оперативной памяти непосредственно перед вызовом КомпоновщикМакета.Выполнить, вы не видите его в визуальном редакторе схемы СКД в конфигураторе. Найти его можно только в отладчике, исследовав объект КомпоновщикНастроек в момент формирования макета.

Как найти «ту самую галочку» в коде?

Если вы столкнулись с тем, что ЛЕВОЕ СОЕДИНЕНИЕ превращается во внутреннее из-за условия ГДЕ ЕСТЬNULL(Показатель, 0) <> 0, выполните следующие действия:

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


Для Каждого ЭлементОтбора Из КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
    Если ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ЗначениеПоказателя") Тогда
        // Вот здесь система может принудительно ставить "Не равно 0"
    КонецЕсли;
КонецЦикла;

Способы решения проблемы

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

Способ 1: Использование «фиктивных» вычислений в запросе

Иногда помогает «обман» оптимизатора СКД. Вместо прямой выборки поля Вес, попробуйте обернуть его в функции, которые сделают поле «непрозрачным» для автоматического анализа отборов бюджетирования:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Номенклатура,
    (ВЫБОР КОГДА Номенклатура.ВесЧислитель = 0 ТОГДА 0.000000001 ИНАЧЕ Номенклатура.ВесЧислитель КОНЕЦ) КАК ЗначениеПоказателя
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Малое числовое значение (0.000000001) позволит записи пройти через фильтр <> 0, а при последующем округлении в бюджетных формах оно превратится в нуль.

Способ 2: Отключение автозаполнения

Если вы полностью контролируете запрос, снимите галочку «Автозаполнение» в настройках набора данных СКД. В этом случае вы должны будете вручную определить все доступные поля и параметры. Это лишит компоновщик возможности «додумывать» условия на основе метаданных справочников (например, связи числителя и знаменателя веса номенклатуры).

Способ 3: Изменение логики соединения

Если система упорно добавляет условие ГДЕ на правую таблицу ЛЕВОГО СОЕДИНЕНИЯ, попробуйте перенести все вычисления во временную таблицу, а в итоговом запросе делать соединение с ЕСТЬNULL. Однако помните, что если программный код ERP накладывает отбор на финальное поле ЗначениеПоказателя, то даже ЕСТЬNULL не спасет — запись будет отсечена после соединения.

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

Резюме: СКД не обладает искусственным интеллектом, она лишь послушно исполняет команды. Если запрос меняется — значит, либо в ролях полей стоят ограничивающие флаги, либо (что вероятнее для ERP) внешняя процедура программно модифицирует настройки отбора перед генерацией макета. Тщательный анализ КомпоновщикНастроек.Настройки.Отбор в режиме отладки — ваш главный инструмент решения этой задачи.

← На главную