Как правильно реализовать условный вывод или удаление области в печатной форме 1С?

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

При разработке внешних печатных форм (ВПФ) программисты часто сталкиваются с задачей: нужно вывести строку в табличный документ только в том случае, если выполняется определенное условие (например, заполнена сумма или есть остаток товара). Начинающие разработчики иногда пытаются сначала вывести область, а потом «удалить» её, если условие не соблюдено. В этой статье мы подробно разберем, какой подход является правильным, рассмотрим различные методы управления содержимым ТабличныйДокумент и выясним, как избежать распространенных ошибок отладки.

Классический подход: Условный вывод через логический оператор

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


// Получаем область из макета
ОбластьСтрока = Макет.ПолучитьОбласть("Строка"); 

// Проверяем условие выполнения
Если ВыборкаЗапроса.СуммаКвалификация > 0 Тогда 
    // Заполняем параметры области
    ОбластьСтрока.Параметры.СуммаКвалификация = ВыборкаЗапроса.СуммаКвалификация; 
    // Выводим заполненную область в итоговый табличный документ
    ТабличныйДокумент.Вывести(ОбластьСтрока); 
КонецЕсли;

Этот подход является наиболее правильным и эффективным. Мы не тратим ресурсы системы на вывод лишних строк, которые потом придется удалять. Если условие ВыборкаЗапроса.СуммаКвалификация > 0 не выполняется, метод Вывести() просто не вызывается, и строка в документе не появляется. Это логично, просто и минимизирует количество операций с объектом ТабличныйДокумент.

Метод УдалитьОбласть: когда он действительно нужен?

Иногда разработчики рассматривают альтернативный вариант: сначала вывести всё, а потом удалить лишнее с помощью метода УдалитьОбласть(). Давайте разберем, почему в контексте формирования обычных печатных форм это чаще всего избыточно, и как этот метод работает на самом деле.

Метод УдалитьОбласть() работает с уже сформированным документом. Чтобы им воспользоваться, нам нужно четко понимать координаты области, которую мы хотим убрать. Рассмотрим пример программного удаления:


// Пример удаления области, если мы уже вывели её в документ
Если Не УсловиеВыполнено Тогда
    // Определяем область по номерам строк (например, последняя выведенная строка)
    НомерСтроки = ТабличныйДокумент.ВысотаТаблицы;
    ОбластьДляУдаления = ТабличныйДокумент.Область(НомерСтроки, , НомерСтроки);
    ТабличныйДокумент.УдалитьОбласть(ОбластьДляУдаления, ТипСмещенияТабличногоДокумента.ПоВертикали);
КонецЕсли;

Важные нюансы метода:

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

Управление видимостью строк и колонок

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

Выясним, как это реализовать программно:


// Выводим область как обычно
ТабличныйДокумент.Вывести(ОбластьСтрока);

// Если условие не соблюдено, просто скрываем строку
Если ВыборкаЗапроса.СуммаКвалификация = 0 Тогда
    НомерСтроки = ТабличныйДокумент.ВысотаТаблицы;
    ТабличныйДокумент.Область(НомерСтроки, , НомерСтроки).Видимость = Ложь;
КонецЕсли;

Также можно использовать установку высоты строки в значение 0: ТабличныйДокумент.Область(НомерСтроки, , НомерСтроки).ВысотаСтроки = 0;. Результат будет визуально идентичен удалению, но структура документа останется нетронутой.

Оптимизация через макет: использование разных областей

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

Посмотрим на пример такой реализации:


ИмяОбласти = ?(ВыборкаЗапроса.СуммаКвалификация > 0, "СтрокаДанных", "ПустаяСтрока");
Область = Макет.ПолучитьОбласть(ИмяОбласти);

Если ИмяОбласти = "СтрокаДанных" Тогда
    Область.Параметры.Заполнить(ВыборкаЗапроса);
КонецЕсли;

ТабличныйДокумент.Вывести(Область);

Этот метод делает код более читаемым и позволяет гибко настраивать оформление «пустых» или «пропущенных» строк непосредственно в визуальном редакторе макета.

Проблема пустых значений и отладка

Как мы увидели в обсуждении на форуме, основной причиной «неработающего» кода часто является не ошибка в алгоритме, а состояние данных. Если в запросе получается NULL или 0, условие Сумма > 0 логично не срабатывает.

Рекомендации по отладке условий:

  1. Проверка на NULL: В запросах всегда используйте функцию ЕСТЬNULL(Поле, 0). Это гарантирует, что вы будете сравнивать число с числом, а не с неопределенным значением, что часто приводит к непредсказуемым результатам в коде 1С.
  2. Функция ЗначениеЗаполнено(): Если вы проверяете не только числа, но и ссылочные типы, используйте ЗначениеЗаполнено(Выборка.Ссылка) вместо сравнения с пустой ссылкой.
  3. Отладчик: Всегда проверяйте значения полей выборки непосредственно перед условием Если. Как показал пример автора темы, иногда мы просто забываем, что в исходных данных может оказаться ноль.

Проверка вывода на страницу

Разберем еще один важный аспект работы с областями — контроль за тем, чтобы область не «разрывалась» при переходе на новую страницу. Метод ПроверитьВывод() позволяет узнать, поместится ли область на текущем листе.


СписокОбластей = Новый Массив;
СписокОбластей.Добавить(ОбластьСтрока);

// Проверяем, влезет ли строка на текущий лист
Если Не ТабличныйДокумент.ПроверитьВывод(СписокОбластей) Тогда
    // Если не влезает, принудительно переносим на новую страницу
    ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;

ТабличныйДокумент.Вывести(ОбластьСтрока);

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

Итоги

Резюмируя разбор темы, можно выделить следующие правила:

← На главную