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