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

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

При разработке печатных форм в среде 1С:Предприятие часто возникает задача вывести в ячейку результат арифметической операции над несколькими реквизитами документа — например, сложить два курса, перемножить цену и количество или прибавить надбавку. Начинающие разработчики нередко пытаются прописать формулу прямо в ячейке макета с типом заполнения Шаблон, например: [Параметр1] + [Параметр2]. Рассмотрим подробнее, почему такой подход не работает и какими способами правильно вычислять значения для макетов.

Ограничение механизма «Шаблон» в табличных документах

Выясним причину, почему платформа не вычисляет сумму параметров внутри шаблона. Свойство ячейки табличного документа Шаблон предназначено исключительно для строковой интерполяции — вставки строковых представлений параметров внутрь текста (например, Счет на оплату № [Номер] от [Дата]). Механизм шаблона не является интерпретатором выражений встроенного языка 1С. Внутри квадратных скобок [...] нельзя использовать знаки математических операций (+, -, *, /), условия или вызовы функций. Все, что находится внутри скобок, платформа воспринимает исключительно как имя одного параметра.

Для вывода расчетных данных значение необходимо сформировать заранее и передать в ячейку с типом Параметр либо Шаблон в уже готовом виде.

Анализ типовой ошибки при заполнении параметров в коде

Посмотрим на частую ошибку, которая возникает при попытке рассчитать значение параметра во встроенном языке. При попытке выполнить код:

Шапка.Параметры.ППП = КурсВалюты + КурсВалюты;

Платформа выдает ошибку компиляции:

Переменная не определена (КурсВалюты)

Проанализируем ситуацию и выделим сразу две ошибки в данном фрагменте:

  1. Область видимости: Поля, выбранные в запросе (например, ПриходнаяНакладная.КурсВалюты), не становятся локальными переменными процедуры. К ним нельзя обращаться напрямую по имени. Обращение всегда происходит через объект выборки: Выборка.КурсВалюты.
  2. Позиционирование выборки: Строка расчета была размещена до начала цикла Пока Выборка.Следующий() Цикл. До первого вызова метода Следующий() выборка из результата запроса еще не указывает ни на какую запись, поэтому прочитать значения ее полей невозможно.

Способ 1. Расчет значения во встроенном языке внутри цикла обхода выборки

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

Посмотрим на пример корректного фрагмента процедуры печати:


// Получаем области макета
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
Шапка = Макет.ПолучитьОбласть("Шапка");
ОбластьТаблЧастьШапка = Макет.ПолучитьОбласть("ТаблЧастьШапка");
ОбластьТаблЧасть = Макет.ПолучитьОбласть("ТаблЧасть");

ТабДок.Очистить();
ВставлятьРазделительСтраниц = Ложь;

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

Способ 2. Вычисление параметров на уровне текста запроса (рекомендуемый)

Рассмотрим более производительный и чистый подход к разработке печатных форм. Все математические преобразования данных оптимально переносить в текст запроса к базе данных. Для вычисляемого поля задается псевдоним (через ключевое слово КАК), совпадающий с именем параметра в макете.

В этом случае метод Заполнить() автоматически подставит готовое расчетное значение из выборки в параметр макета без необходимости писать дополнительный код присвоения.

Посмотрим на пример изменения текста запроса:


Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    ПриходнаяНакладная.Номер,
|    ПриходнаяНакладная.Дата,
|    ПриходнаяНакладная.КурсВалюты,
|    ПриходнаяНакладная.КурсВалюты * 2 КАК ППП,
|    ПриходнаяНакладная.Контрагент
|ИЗ
|    Документ.ПриходнаяНакладная КАК ПриходнаяНакладная
|ГДЕ
|    ПриходнаяНакладная.Ссылка В (&Ссылка)";

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


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

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

Если логика расчета сложная и включает условия, которые неудобно описывать в тексте запроса, можно использовать передачу параметров через объект Структура. Метод Параметры.Заполнить() умеет принимать в качестве источника данных структуры:


Пока Выборка.Следующий() Цикл
    ТабДок.Вывести(ОбластьЗаголовок);
    
    // Заполняем реквизиты документа
    Шапка.Параметры.Заполнить(Выборка);
    
    // Формируем дополнительные вычисляемые параметры
    ДопПараметры = Новый Структура;
    ДопПараметры.Вставить("ППП", Выборка.КурсВалюты * 2);
    
    Шапка.Параметры.Заполнить(ДопПараметры);
    ТабДок.Вывести(Шапка, Выборка.Уровень());
КонецЦикла;

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

← На главную