При формировании печатных форм и отчетов в среде «1С:Предприятие» разработчики часто сталкиваются с задачей динамического изменения структуры табличного документа. Типичный сценарий: на форме отчета присутствует флажок (галочка), при снятии которого определенная колонка (например, информация о менеджере, скидке или артикуле) должна полностью скрываться из результирующего документа.
В этой статье мы подробно разберем, как правильно решать эту задачу, проанализируем распространенные ошибки начинающих разработчиков, рассмотрим несколько эффективных способов скрытия колонок и выработаем рекомендации по написанию производительного и отказоустойчивого кода.
Для начала давайте разберем типичную архитектурную ошибку, которую совершают при реализации этого механизма. Довольно часто в коде можно встретить следующую конструкцию:
Выб1 = ВыборкаДок.Выбрать();
Пока Выб1.Следующий() Цикл
Если ПараметрыОтчета.Мен = Истина Тогда
ДокументРезультат.Область(, 10, , 11).Видимость = Ложь;
Иначе
ДокументРезультат.Область(, 10, , 11).Видимость = Истина;
ОбластьСтрокаОтчет1.Параметры.МенСопр = Выб1.Мен;
КонецЕсли;
КонецЦикла;
Давайте проанализируем, почему этот код крайне неоптимален и опасен для использования в реальных задачах:
Видимость для всей области результирующего документа выполняется на каждом шаге цикла. Если выборка содержит тысячи строк, платформа будет многократно выполнять одну и ту же тяжелую операцию по пересчету интерфейса табличного документа, что приведет к катастрофическому падению производительности и зависанию программы.Давайте выясним, как решить задачу скрытия колонок правильно и профессионально.
Этот способ основан на обращении к области табличного документа и изменении ее свойства Видимость. Важное правило: изменять видимость нужно один раз, после того как весь табличный документ уже сформирован, или непосредственно перед выводом данных.
Рассмотрим пример кода, в котором колонка скрывается на основе настройки формы:
// 1. Формируем табличный документ стандартным образом
ТабДок = Новый ТабличныйДокумент;
// ... (Заполнение табличного документа данными в цикле) ...
// 2. Управляем видимостью колонок ОДИН РАЗ после завершения вывода данных
Если НЕ ПараметрыОтчета.ПоказыватьМенеджера Тогда
// Обращаемся ко всей вертикальной области с 10-й по 11-ю колонку
ТабДок.Область(, 10, , 11).Видимость = Ложь;
КонецЕсли;
ТабДок.Показать();
В методе Область() мы опускаем индексы строк (первый и третий параметры оставляем пустыми) и указываем только начальный и конечный номера колонок (второй и четвертый параметры). Таким образом, мы получаем вертикальную область, проходящую через весь документ.
Чтобы избежать жесткого кодирования номеров колонок, мы можем использовать именованные области в самом макете. Для этого в конфигураторе выделите нужную колонку целиком (кликнув на ее заголовок) и присвойте ей уникальное имя в свойствах (например, КолонкаМенеджер).
Давайте посмотрим, как в этом случае будет выглядеть наш программный код:
// Получаем макет отчета
Макет = ПолучитьМакет("Макет");
// Определяем реальный номер колонки в макете по ее имени
НомерКолонки = Макет.Области.КолонкаМенеджер.Лево;
// ... код заполнения ТабличногоДокумента ...
// После вывода данных скрываем колонку по динамически полученному индексу
Если НЕ ПараметрыОтчета.ПоказыватьМенеджера Тогда
ТабДок.Область(, НомерКолонки, , НомерКолонки).Видимость = Ложь;
КонецЕсли;
Этот подход гарантирует, что даже если структура макета со временем изменится (будут добавлены новые графы или удалены старые), платформа автоматически определит корректный индекс колонки, и код продолжит работать без ошибок.
Наиболее надежным и архитектурно правильным способом построения гибких отчетов в 1С является использование комбинированных (горизонтальных и вертикальных) областей. Вместо того чтобы выводить одну общую область, а затем "скрывать" ненужное, мы собираем каждую строку отчета по кусочкам (секциям) только из тех колонок, которые действительно должны быть отображены.
Для реализации этого метода в макете создаются пересекающиеся области. Например:
СтрокаКолонкаЛево, КолонкаМенеджер, КолонкаПравоРазберем по шагам, как программно собрать строку с условным выводом центральной колонки:
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
// 1. Получаем и выводим первую (левую) часть строки
ОбластьЛево = Макет.ПолучитьОбласть("Строка|КолонкаЛево");
ОбластьЛево.Параметры.Заполнить(Выборка);
ТабДок.Вывести(ОбластьЛево); // Первый вывод строки делает смещение вниз
// 2. Если условие выполняется, присоединяем среднюю колонку по горизонтали
Если ПараметрыОтчета.ПоказыватьМенеджера Тогда
ОбластьМенеджер = Макет.ПолучитьОбласть("Строка|КолонкаМенеджер");
ОбластьМенеджер.Параметры.Менеджер = Выборка.ОсновнойМенеджер;
ТабДок.Присоединить(ОбластьМенеджер);
КонецЕсли;
// 3. Присоединяем финальную (правую) часть строки
ОбластьПраво = Макет.ПолучитьОбласть("Строка|КолонкаПраво");
ОбластьПраво.Параметры.Заполнить(Выборка);
ТабДок.Присоединить(ОбластьПраво);
КонецЦикла;
Преимущества данного метода: табличный документ изначально генерируется чистым, без лишних невидимых колонок. Это исключает проблемы со сбивающимися границами ячеек, автовысотой строк и некорректным отображением сетки при печати.
В некоторых случаях использование свойства Видимость = Ложь может не подойти (например, если скрытая колонка мешает формулам или экспорту в сторонние форматы Excel). В таких сценариях колонку можно физически вырезать из таблицы с помощью метода УдалитьОбласть().
Рассмотрим практический пример реализации удаления колонки:
Если НЕ ПараметрыОтчета.ПоказыватьМенеджера Тогда
// Определяем область, которую необходимо вырезать (например, 4-я колонка)
ОбластьДляУдаления = ТабДок.Область(, 4, , 4);
// Удаляем колонку со смещением остальных колонок влево
ТабДок.УдалитьОбласть(ОбластьДляУдаления, ТипСмещенияТабличногоДокумента.ПоГоризонтали);
КонецЕсли;
Обратите внимание: при использовании метода УдалитьОбласть с типом смещения ПоГоризонтали все колонки, находившиеся правее удаляемой, автоматически сдвигаются влево. Это смещает их реальные индексы, что необходимо учитывать, если в коде планируется дальнейшая работа с номерами колонок табличного документа.
Выбор оптимального метода зависит от конкретных требований к вашему отчету. Проанализируем особенности каждого подхода:
Используйте рассмотренные подходы и рекомендации, чтобы ваши печатные формы и отчеты всегда формировались быстро, корректно и были устойчивы к любым изменениям метаданных и макетов.