Как правильно выводить области макета и заполнять их параметры по условию в 1С?

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

При разработке печатных форм в 1С начинающие программисты часто сталкиваются с ситуацией, когда необходимо выводить разные секции (области) макета в зависимости от определенных условий. Типичная проблема заключается в том, что при использовании конструкции Если ... ИначеЕсли параметры области либо не заполняются вовсе, либо система выдает ошибку, что параметр не обнаружен. Рассмотрим подробнее, почему это происходит, и разберем наиболее эффективные способы решения этой задачи.

Анализ типичной ошибки логики

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

Выясним причину: в 1С обращение к параметру области через прямую адресацию требует, чтобы этот параметр был явно задан в макете именно для этой области. Если вы получили область "Зачисление", а пытаетесь заполнить параметр "ПричинаВосстановления", который есть только в области "Восстановление", программа прервет выполнение.

Решение 1: Структурирование условий и последовательный вывод

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


Если Запрос.ВидПриказа = Перечисления.ВидыПриказовДвиженияКонтингента.Зачисление Тогда
    ОбластьМакета = Макет.ПолучитьОбласть("Зачисление");
    // Заполняем только те параметры, которые есть в этой конкретной области
    ОбластьМакета.Параметры.Заголовок = Запрос.Заголовок;
    ОбластьМакета.Параметры.ТекущийГод = Формат(ТекущаяДата(), "ДФ=yyyy");
    
ИначеЕсли Запрос.ВидПриказа = Перечисления.ВидыПриказовДвиженияКонтингента.Восстановление Тогда
    ОбластьМакета = Макет.ПолучитьОбласть("Восстановление");
    // Здесь заполняем свои параметры
    ОбластьМакета.Параметры.Дата = Запрос.Дата;

КонецЕсли;

// Выводим область только после того, как она была получена и заполнена
Если ОбластьМакета <> Неопределено Тогда
    ТабличныйДокумент.Вывести(ОбластьМакета);
КонецЕсли;

Такой подход работает, но он заставляет нас дублировать код, если многие параметры (например, ФИО студента, дата, номер приказа) одинаковы для всех областей. Чтобы этого избежать, перейдем к более профессиональному методу.

Решение 2: Использование структуры и метода Заполнить() — лучший вариант

Наиболее эффективным методом является предварительное формирование Структуры со всеми возможными данными и последующее использование метода Параметры.Заполнить(). Рассмотрим подробнее преимущества этого способа. Метод Заполнить() уникален тем, что он сопоставляет ключи структуры с именами параметров в области макета. Если в структуре есть лишние данные, которых нет в области, 1С просто проигнорирует их, не вызывая ошибку. Это позволяет нам подготовить один общий массив данных для всех видов печатных форм.

Проанализируем пример реализации:


// 1. Создаем структуру и наполняем её всеми данными из запроса или выборки
ДанныеДляПечати = Новый Структура;
ДанныеДляПечати.Вставить("Заголовок", Запрос.Заголовок);
ДанныеДляПечати.Вставить("Дата", Формат(Запрос.Дата, "ДЛФ=Д"));
ДанныеДляПечати.Вставить("ФИОСтудента", Запрос.ФИО);
ДанныеДляПечати.Вставить("НомерГруппы", Запрос.УчебнаяГруппа);

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

// 3. Заполняем параметры области из структуры "одним махом"
// Система сама выберет только нужные параметры для конкретной области
ОбластьМакета.Параметры.Заполнить(ДанныеДляПечати);

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

Важный совет: Вместо ручного создания структуры можно передавать сразу строку выборки из результата запроса: ОбластьМакета.Параметры.Заполнить(ВыборкаИзЗапроса);. Это максимально сокращает код и делает его очень чистым.

Тонкости работы с табличными документами и макетами

Рассмотрим дополнительные нюансы, которые помогут сделать ваши печатные формы более надежными и быстрыми:

  1. Оптимизация производительности: Если вы выводите список (например, 100 студентов), никогда не вызывайте Макет.ПолучитьОбласть() внутри цикла. Получение области — ресурсоемкая операция. Правильнее получить все нужные области в переменные до начала цикла Пока Выборка.Следующий(), а внутри цикла только заполнять их параметры и выводить.
  2. Методы "Вывести" и "Присоединить": Помните, что метод Вывести() добавляет область вниз (создает новые строки), а Присоединить() добавляет область справа в ту же строку. Это полезно для формирования динамических колонок.
  3. Безопасность параметров: Если вы все же решили заполнять параметры через точку, всегда используйте проверку на наличие области. Например, если условие не сработало, переменная ОбластьМакета может остаться пустой, что приведет к аварийному завершению программы.
  4. Обработка пустых значений: Чтобы в печатной форме вместо пустой даты не выводилось "01.01.0001", настройте формат ячейки в конфигураторе (свойство "Формат", параметр "ЧН="). Для строк же лучше использовать проверку ЗначениеЗаполнено() перед выводом целых секций.
  5. Условное оформление: Если по условию нужно изменить не только текст, но и, например, цвет шрифта, используйте программное обращение к области: ОбластьМакета.Область("НужнаяЯчейка").ЦветТекста = ЦветаСтиля.ОсобыйТекст;.

Итоги

Подводя итог, можно сказать, что правильная стратегия работы с условными областями строится на трех принципах:

1. Отделение логики подготовки данных (формирование структуры или выборки) от логики визуализации (выбора области макета).

2. Использование универсального метода Заполнить(), который прощает отсутствие параметров в макете.

3. Вынос получения областей за пределы циклов обработки данных для ускорения формирования документа.

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

← На главную