Как скрыть области в макете или динамически сформировать колонки по месяцам в 1С

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке отчетов в системе 1С:Предприятие без использования Системы компоновки данных (СКД) программисты часто сталкиваются с задачей динамического формирования структуры колонок. Типичный пример — отчет, где количество колонок зависит от выбранного периода (например, по месяцам). В данной статье мы разберем, как правильно управлять видимостью колонок и как формировать макет так, чтобы не приходилось ничего скрывать.

Постановка задачи

Представим ситуацию: у нас есть макет с заранее определенными областями для 12 месяцев. Пользователь выбирает период, например, три месяца. Нам нужно либо скрыть лишние 9 колонок, либо вывести только нужные 3. Разберем оба подхода, их плюсы и минусы, а также проанализируем программный код для реализации этой логики.

Метод 1: Динамическое построение макета через метод Присоединить()

Рассмотрим наиболее эффективный и правильный с точки зрения производительности метод. Вместо того чтобы выводить фиксированную "шапку" со всеми месяцами и затем скрывать ненужные, мы будем "собирать" шапку только из тех периодов, которые присутствуют в данных.

Для этого в макете необходимо разделить шапку на три части:

  1. Левая часть: фиксированные колонки (например, "Номенклатура", "Артикул").
  2. Центральная часть (повторяющаяся): одна колонка "Месяц".
  3. Правая часть: итоговые показатели.

Разберем алгоритм вывода в коде. Сначала мы выводим левую часть методом Вывести(), а затем в цикле добавляем нужное количество колонок месяца методом Присоединить().


// Подготовительный этап: формирование массива периодов
СтандартныйПериод = Отчет.Период;
МассивПериодов = Новый Массив;
ТекущаяДата = НачалоМесяца(СтандартныйПериод.ДатаНачала);

Пока ТекущаяДата <= СтандартныйПериод.ДатаОкончания Цикл
    МассивПериодов.Добавить(ТекущаяДата);
    ТекущаяДата = ДобавитьМесяц(ТекущаяДата, 1);
КонецЦикла;

// Вывод в табличный документ
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетОтчета");

// 1. Выводим фиксированную левую часть
ОбластьЛево = Макет.ПолучитьОбласть("Шапка|Лево");
ТабДок.Вывести(ОбластьЛево);

// 2. В цикле присоединяем колонки месяцев
ОбластьМесяц = Макет.ПолучитьОбласть("Шапка|Центр");
Для Каждого МесяцДата Из МассивПериодов Цикл
    // Заполняем параметр месяца (например, "Январь 2024")
    ОбластьМесяц.Параметры.ПериодНаименование = Формат(МесяцДата, "ДФ='ММММ гггг'");
    ТабДок.Присоединить(ОбластьМесяц);
КонецЦикла;

// 3. Присоединяем правую часть с итогами
ОбластьПраво = Макет.ПолучитьОбласть("Шапка|Право");
ТабДок.Присоединить(ОбластьПраво);

Проанализируем преимущества этого метода: мы создаем в памяти ровно столько объектов ячеек, сколько нужно для отображения. Это значительно ускоряет работу с большими отчетами и упрощает поддержку кода, так как нам не нужно писать сложные условия для скрытия.

Метод 2: Управление видимостью существующих колонок

Если структура макета уже жестко задана и переделывать её под метод Присоединить() слишком трудозатратно, можно воспользоваться свойством Видимость или ШиринаКолонки. Это может понадобиться, если макет очень сложный и состоит из множества пересекающихся областей.

Для реализации этого метода нам нужно определить номера колонок, которые подлежат скрытию. Выясним причину, по которой это может быть неудобно: при изменении структуры макета индексы колонок могут "поехать", и код придется переписывать. Чтобы избежать этого, рекомендуется использовать именованные области.

Посмотрим на пример кода, который скрывает колонку, если в массиве периодов нет соответствующего месяца:


// Предположим, у нас в макете колонки с 3 по 14 — это месяцы года
Для НомерКолонки = 3 По 14 Цикл
    // Определяем, какой месяц соответствует данной колонке (условно)
    ТекущийНомерМесяца = НомерКолонки - 2; 
    
    // Проверяем наличие этого месяца в нашем массиве данных
    Если МесяцНеНайденВМассиве(ТекущийНомерМесяца) Тогда
        // Скрываем колонку
        ОбластьДляСкрытия = ТабДок.Область(, НомерКолонки);
        ОбластьДляСкрытия.Видимость = Ложь;
    КонецЕсли;
КонецЦикла;

Рассмотрим важный нюанс: использование Видимость = Ложь иногда может приводить к некорректному отображению границ при печати или сохранении в PDF. В таких случаях мы рекомендуем альтернативный способ — установку ширины колонки в значение 0.


// Альтернативный способ скрытия через ширину
ТабДок.Область(, НомерКолонки).ШиринаКолонки = 0;

Метод 3: Использование функции Месяц() и форматирования

Часто программисты застревают на условии: "как понять, что эта колонка — январь?". Выясним, как сделать это элегантно. Если вы используете дату начала периода, функция Месяц(Дата) вернет число от 1 до 12. Это число можно использовать как индекс для поиска в макете или сопоставления с номером колонки.

Рассмотрим пример заполнения заголовков с использованием форматирования, чтобы не писать длинные конструкции Если...Тогда:

Полезный совет: Для вывода красивого названия месяца используйте метод Формат() с параметром ДФ='ММММ'. Это автоматически подставит название месяца в нужном падеже в зависимости от локализации системы.

Оптимизация: Сначала расчет, потом вывод

Проанализируем ситуацию, когда отчет очень большой. Ошибка многих начинающих разработчиков заключается в том, что они проверяют условия скрытия непосредственно в момент вывода каждой строки. Это замедляет формирование документа.

Правильный алгоритм должен выглядеть так:

  1. Выполняем запрос к базе данных и получаем все необходимые цифры.
  2. Анализируем результат запроса и формируем список (массив или соответствие) только тех периодов, по которым реально есть данные.
  3. Запускаем цикл вывода шапки и строк, основываясь только на этом списке.

Таким образом, если в феврале не было продаж, колонка "Февраль" даже не начнет формироваться, что избавит нас от необходимости её скрывать.

Дополнительные настройки интерфейса

При работе с динамическими колонками (особенно если их много, например, за 2-3 года) полезно применять дополнительные возможности ТабличногоДокумента:

Резюме

Мы разобрали основные подходы к управлению областями макета в 1С. Подведем итоги:

1. Метод Присоединить() — наиболее универсальный и профессиональный. Он позволяет строить отчет "на лету", добавляя только те секции, которые нужны.

2. Свойство Видимость — подходит для простых правок в уже существующих сложных макетах, где переписывание логики вывода нецелесообразно.

3. ШиринаКолонки = 0 — надежная альтернатива скрытию, гарантирующая отсутствие "пустых мест" при печати.

Выбирайте метод в зависимости от сложности вашего макета и требований к производительности. Помните, что чистота кода и отсутствие лишних циклов проверки при выводе — залог быстрого отчета, который будет радовать пользователей.

← На главную