Давно заметил, что ничего так не радует глаз пользователя и не заставляет его ценить твою профпригодность как наличие множества «галочек», «штучек», «пимпочек» и кнопочек на экранной форме. Ну, конечно, при условии, что все они работают и работают правильно. У меня обычно выходило так, что большинство написанных отчетов обрастали по меньшей мере еще третью от первоначального количества опций, а код угрожающе кренился в полную сумятицу от перегрузки условными операторами и дополнительными переменными.
Примечательно, что в основном приходится по разному группировать либо фильтровать одни и те же данные. Традиционно это делается безжалостным вторжением через оператор Если в тело запроса и процедуру печати. Конечно сам код от этого не становился ни понятнее ни проще, а где-то, где получение данных запросом было невозможно все превращалось в дикие танцы вокруг таблицы значений.
У каждого программиста есть свой способ выводить ТЗ на печать по нужным группировкам — кто то использует класс индексированных таблиц, а кто-то сам вводит в ТЗ индексы, а может есть и еще более или менее эффективные способы. Речь сейчас не о них.
Столкнувшись недавно с проблемой наличия просто сумасшедшего количества необходимых пользователю вариантов группировки данных для вывода на печать да еще и слитых из двух разных конфигураций твердо решил засунуть построение итоговой таблицы значений в одну процедуру. Независимо от количества групп и нужного пользователю порядка их следования.
Когда эту проблему удалось решить вслед за ней решилась и вторая проблема — создание печатных форм. Формат печаной формы также может быть универсальным — достаточно разработать макет вывода для каждого из уровней группировки, а в таблицу значений, получаемую для вывода на печать просто добавляем колонку с уровнем группировки и в зависимости от значения этого уровня применяем нужную секцию печатной таблицы. Весьма типичный пример того как правильное решение одной проблемы приводит к упрощению решения другой.
В чистом остатке мы получили 1(одну) функцию получения предназначенной для печати таблицы значений для любых возможных вариантов группировки и очень простую печатную форму для опять же любого варианта отчета.
Макет печаной формы приведен на картинке, а сама функция звучит так:
Функция ИтоговаяПоГруппировкамТЗ(исхТЗ,СтрГруппировок,СтрИтогов,ДобУровень = 0)
Если (ПустоеЗначение(СтрГруппировок) = 1) Или (ПустоеЗначение(СтрИтогов) = 1) Тогда
Предупреждение(«Не отмечены поля группировок или поля итогов!!!»);
Возврат «»;
КонецЕсли;
ТЗ = СоздатьОбъект(«ТаблицаЗначений»);
исхТЗ.Выгрузить(ТЗ,,,СтрГруппировок+«,»+СтрИтогов);
ТЗ.Свернуть(СтрГруппировок,стрИтогов);
ТЗИтогов = СоздатьОбъект(«ТаблицаЗначений»);
ТЗ.Выгрузить(ТЗИтогов);
спТаблиц = СоздатьОбъект(«СписокЗначений»);
спСвертки = СоздатьОбъект(«СписокЗначений»);
свернутьПо = «»;
сДляСписка = СтрЗаменить(стрГруппировок,«,»,РазделительСтрок);
СчетчикЦикла = 0;
Для ф = 1 По СтрКоличествоСтрок(сДляСписка) Цикл
спСвертки.ДобавитьЗначение(СтрПолучитьСтроку(сДляСписка,ф));
КонецЦикла;
Для ф=1 По спСвертки.РазмерСписка()-1 Цикл
времТ = СоздатьОбъект(«ТаблицаЗначений»);
ТЗ.Выгрузить(времТ);
свернутьПо = свернутьПо + ?(ф=1,«»,«,») + спСвертки.ПолучитьЗначение(ф);
времТ.Свернуть(свернутьПо,СтрИтогов);
спТаблиц.ДобавитьЗначение(времТ,свернутьПо);
КонецЦикла;
Если ДобУровень = 1 Тогда
ТЗ.НоваяКолонка(«Уровень_Группировки»,«Число»);
КонецЕсли;
Для ф=1 По спТаблиц.РазмерСписка() Цикл
времТ = СпТаблиц.ПолучитьЗначение(ф);
ВремТ.ВыбратьСтроки();
Пока ВремТ.ПолучитьСтроку() = 1 Цикл
ТЗ.НоваяСтрока();
Для ы = 1 По ВремТ.КоличествоКолонок() Цикл
идКолонки = времТ.ПолучитьПараметрыКолонки(ы);
текЗнач = ВремТ.ПолучитьЗначение(времТ.НомерСтроки,идКолонки);
ТЗ.УстановитьЗначение(ТЗ.НомерСтроки,идКолонки,текЗнач);
Если ДобУровень = 1 Тогда
ТЗ.УстановитьЗначение(ТЗ.НомерСтроки,«Уровень_Группировки»,ф);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
ТЗ.Сортировать(стрГруппировок);
Возврат ТЗ;
КонецФункции
ИсхТЗ — это обычная таблица значений, как на первом рисунке, а возвращаемая таблица значений показана на втором рисунке.
СтрГруппировок — это обычная строка с разделенными запятыми идентификаторами полей группировки.
А СтрИтогов — строковое выражение из идентификаторов суммируемых при группировке колонок.
Когда родилась универсальная функция возникла идея сделать ее логичное продолжение — универсальную обработку. Универсальная группировка и универсальная печать любой переданной параметром таблицы значений должна, имхо, сильно пригодиться в том случае когда удается получить таблицу значений, а вот с группировками и печатью заморачиваться некогда или не хочется, да и заказчик сам толком не понимает в каком виде ему будет удобнее анализировать данные (а скорее всего в каких видах). Обработка имеет и демо режим запуска без переданной таблицы значений — в этом случае ТЗ будет сгенерирована автоматически и весь функционал обработки можно будет оценить без построения ненужной ТЗ передачи ее с вызовом из ненужной обработки.
Еще как опцию ввел в обработку фильтр значений ТЗ. Сначала думал, отбор можно сделать предварительно, до передачи таблицы в обработку, но раз уж делать универсальную фабрику изготовления отчетов, то нужно развязать руки разработчику и в этом вопросе.
Если обработку немного допилить, то можно кроме ТЗ передавать параметром опции группировки и подведения итогов и сразу группировать и вызывать печать, не показывая формы. Тоже удобно, но интерфейсы отбора и настройки вывода данных нужно каждый раз писать в вызывающем отчете. Если хочется, то почему бы и нет:)
Последний из передаваемых аргументов функции сортировки — это флаг добавления в таблицу результата колонки с уровнем группировки. При ДобУровень установленном на 1 таблица значений на выходе получает еще одну колонку Уровень_Группировки, которая заполняется числами от 1 (самый главный уровень) по возрастающей. В соответствии с признаком группировки и используется секция печатной формы для вывода соответствующей строки сгруппированной таким образом таблицы значений. Так как количество секций для уровней в печатной форме в принципе не может быть бесконечным (в отличие от потенциального количества группируемых колонок), то в печатную форму введена секция для уровня 0, который используется для вывода всех уровней группировки корорых нет в подготовленной нами печатной форме. Я лично разместил пять секций для возможных уровней (дальше фантазия иссякла), а это значит что все уровне начиная с шестого буду выводиться на печать в дизайне секции «Уровень_0»
Вот собственно и все. Быстрых и качественных всем разработок!:)
группировки в одной колонке, не?
Группировки во всех нужных колонках. Хоть в одной хоть в 101:)
(0) Это и многое другое — «ИндексированнаяТаблица» , 1CPP.
(3) kompas-dm, Согласен на 100%. Однако, это работает везде где просто установлена клюшка. Я очень люблю писать штуки, которые работают всегда и везде. А еще это просто выпендреж и дань тщеславию
очень здорово это выглядит, спасибо
(4) Полностью согласна. обработки должны работать всегда и везде, где есть только 1С. Ну и конечно, выпендриться тож приятно!
интересно, спасибо 🙂
Очень полезная обработка. Спасибо.
Похоже, оно навернётся на сворачивании элементов с одинаковым представлением. 🙂
(9) berezdetsky, Метод Свернуть() ни разу не наворачивался при свертке элементов с одинаковым представлением пока я работаю в 1С. Ну а ТЗ с совпадающими идентификаторами колонок попробуйте создать:)
(10) 1. Берём двухуровневый справочник и такой код:
Показать
Видим красивую картинку: (см. Снимок1).
2. Теперь делаем представление группы 2 таким же, как у группы 1 и видим: (см. Снимок2).
3. Добавляем сортировку по внутреннему значению. 😉
(11) berezdetsky, Любопытно у Вас получилось. Но все еще не понятно.
Это как делалось? Или код приведите, пожалуйста, а то если и дописывать, то нужно понимать почему такое происходит.
(12) Нет никакого кода. 🙂 Просто скопировал наименование в форме справочника. Получилось две группы с одинаковым наименованием.
(13) berezdetsky, Жестокий эксперимент:) Не буду ничего переписывать — занят новыми проблемами.