Как вывести на печать только видимые колонки табличной части в 1С 8.3

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

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

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

Метод 1. Динамическое построение таблицы (Вывести и Присоединить)

Этот метод считается наиболее надежным и профессиональным. Вместо того чтобы выводить всю таблицу целиком, мы конструируем ее построчно и поколоночно. Макет в данном случае должен содержать элементарные области (отдельные ячейки для каждого типа данных), которые мы стыкуем программно слева направо.

Вспомним базовое правило работы с объектом ТабличныйДокумент: метод Вывести всегда начинает новую строку в документе, а метод Присоединить добавляет указанную область справа от уже выведенных ячеек в текущей строке.

Рассмотрим пошаговый алгоритм реализации этого метода:

  1. Создаем новый объект ТабличныйДокумент.
  2. Определяем массив или список имен тех колонок, которые в данный момент видимы на форме (или по которым итог больше нуля).
  3. Для шапки таблицы: первую колонку ("Сотрудник" или "Номенклатура") выводим методом Вывести, а все последующие видимые колонки последовательно добавляем справа методом Присоединить.
  4. Для строк таблицы: в цикле обходим строки нашей табличной части. Для каждой строки первую ячейку выводим методом Вывести, а данные последующих видимых колонок присоединяем в той же строке методом Присоединить.
  5. Аналогичным образом выводим подвал таблицы с итогами.

Посмотрим на практический пример реализации этого алгоритма в коде:


&НаСервере
Функция СформироватьПечатнуюФормуДинамически() Экспорт

    ТабДок = Новый ТабличныйДокумент;
    Макет = ПолучитьМакет("МакетОтчета");
    
    // Получаем области из макета
    ОбластьШапкаЛево = Макет.ПолучитьОбласть("Шапка|КолонкаСотрудник");
    ОбластьШапкаКолонка = Макет.ПолучитьОбласть("Шапка|ДинамическаяКолонка");
    
    ОбластьСтрокаЛево = Макет.ПолучитьОбласть("Строка|КолонкаСотрудник");
    ОбластьСтрокаКолонка = ...; // Получаем область динамической ячейки
    
    // Сначала определим, какие колонки мы будем выводить
    СписокВыводимыхКолонок = Новый СписокЗначений;
    Для Каждого Колонка Из Объект.ТабличнаяЧасть.Выгрузить().Колонки Цикл
        // Проверяем условие видимости или заполненности
        Если Объект.ТабличнаяЧасть.Итог(Колонка.Имя) > 0 Тогда
            СписокВыводимыхКолонок.Добавить(Колонка.Имя, Колонка.Заголовок);
        КонецЕсли;
    КонецЦикла;
    
    // 1. Выводим шапку таблицы
    ТабДок.Вывести(ОбластьШапкаЛево);
    Для Каждого ЭлементСписка Из СписокВыводимыхКолонок Цикл
        ОбластьШапкаКолонка.Параметры.ТекстЗаголовка = ЭлементСписка.Представление;
        ТабДок.Присоединить(ОбластьШапкаКолонка);
    КонецЦикла;
    
    // 2. Выводим строки данных
    Для Каждого СтрокаТЧ Из Объект.ТабличнаяЧасть Цикл
        
        // Выводим левую фиксированную часть строки
        ОбластьСтрокаЛево.Параметры.Заполнить(СтрокаТЧ);
        ТабДок.Вывести(ОбластьСтрокаЛево);
        
        // Присоединяем динамические колонки справа
        Для Каждого ЭлементСписка Из СписокВыводимыхКолонок Цикл
            ИмяПоля = ЭлементСписка.Значение;
            ОбластьСтрокаКолонка.Параметры.Значение = СтрокаТЧ[ИмяПоля];
            ТабДок.Присоединить(ОбластьСтрокаКолонка);
        КонецЦикла;
        
    КонецЦикла;
    
    Возврат ТабДок;

КонецФункции

Этот способ гарантирует идеальный результат: в итоговом документе не будет скрытых пустых областей, а ширина колонок будет соответствовать настройкам макета.

Метод 2. Удаление пустых колонок из готового документа (УдалитьОбласть)

Если макет отчета достаточно сложный, содержит много объединенных ячеек в шапке или подвале, собирать его "по кирпичикам" программно может быть трудоемко. В таком случае проще сначала вывести документ целиком (со всеми возможными колонками), а затем программно удалить те колонки, которые оказались пустыми.

Для удаления областей в 1С используется метод УдалитьОбласть объекта ТабличныйДокумент. При удалении колонок важно указать тип смещения по горизонтали, чтобы правые колонки автоматически сдвигались влево, заполняя образовавшееся пустое пространство.

Важное правило "Обратного цикла": При физическом удалении колонок обход всегда необходимо выполнять справа налево (с конца в начало). Если обходить колонки слева направо, то после удаления, например, второй колонки, третья станет второй, четвертая — третьей, и индексы в цикле собьются, из-за чего программа пропустит часть пустых колонок.

Проанализируем пример кода, реализующий удаление колонок:


&НаСервере
Процедура УдалитьПустыеКолонки(ТабДок)

    // Определяем общее количество колонок в получившейся таблице
    ВсегоКолонок = ТабДок.ШиринаТаблицы;
    
    // Начинаем обратный цикл со второй колонки (первую колонку с данными сотрудника не трогаем)
    Для НомерКолонки = ВсегоКолонок По 2 Шаг -1 Цикл
        
        // Проверяем, пустая ли колонка. Для этого можно проанализировать итог или данные формы
        ИмяКолонкиТЧ = "Доплата" + (НомерКолонки - 1); // Пример соответствия имен
        
        Если Объект.ТабличнаяЧасть.Итог(ИмяКолонкиТЧ) = 0 Тогда
            
            // Получаем область всей колонки сверху донизу
            // Параметры метода Область: (ПерваяСтрока, ПерваяКолонка, ПоследняяСтрока, ПоследняяКолонка)
            ОбластьКолонки = ТабДок.Область(, НомерКолонки, , НомерКолонки);
            
            // Удаляем область со смещением по горизонтали
            ТабДок.УдалитьОбласть(ОбластьКолонки, ТипСмещенияТабличногоДокумента.ПоГоризонтали);
            
        КонецЕсли;
        
    КонецЦикла;

КонецПроцедуры

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

Метод 3. Скрытие колонок через свойство "Видимость"

Существует альтернативный, незаслуженно забытый способ быстрого скрытия колонок без их физического удаления и риска повредить структуру объединенных ячеек. У объекта ОбластьЯчеекТабличногоДокумента есть штатное свойство Видимость.

Если мы установим видимость колонки в значение Ложь, 1С визуально сожмет ее ширину до нуля. При этом нам не нужно заботиться о пересчете индексов колонок справа налево, а геометрия шапки отчета гарантированно не пострадает.

Рассмотрим, как лаконично выглядит этот подход в коде:


&НаСервере
Процедура СкрытьПустыеКолонкиЧерезВидимость(ТабДок)

    ВсегоКолонок = ТабДок.ШиринаТаблицы;
    
    Для НомерКолонки = 2 По ВсегоКолонок Цикл
        
        ИмяКолонкиТЧ = "Доплата" + (НомерКолонки - 1);
        
        Если Объект.ТабличнаяЧасть.Итог(ИмяКолонкиТЧ) = 0 Тогда
            // Получаем область колонки целиком и отключаем видимость
            ТабДок.Область(, НомерКолонки, , НомерКолонки).Видимость = Ложь;
        КонецЕсли;
        
    КонецЦикла;

КонецПроцедуры

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

Резюме и рекомендации

Выбор конкретного метода зависит от структуры вашего макета:

← На главную