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