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