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

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

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

Ограничения платформы: почему формулу нельзя задать в свойствах

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

Автоматический подсчет итогов без программирования работает исключительно для стандартных сумм числовых колонок табличной части. Любая дополнительная математическая операция над итогом (умножение, деление, вычитание) требует написания программного кода.

Способ 1. Использование клиентского реквизита формы и поля надписи

Рассмотрим классический способ решения задачи с использованием элемента управления с видом Поле надписи (ВидПоляФормы.ПолеНадписи). Особенность данного элемента заключается в том, что он обязательно требует привязки к реквизиту в свойстве ПутьКДанным, иначе надпись не будет отображаться на экране.

Разберем реализацию по шагам:

  1. Создание реквизита формы. Добавим на форму реквизит (например, ИтогУмноженный) с типом Число. Этот реквизит существует только в контексте формы и не сохраняется в базе данных.
  2. Настройка элемента формы. Добавим элемент с видом Поле надписи и свяжем его свойство ПутьКДанным с созданным реквизитом ИтогУмноженный.
  3. Расчет без вызова сервера. Коллекции данных формы в тонком клиенте поддерживают метод Итог(). Это позволяет выполнять расчет мгновенно на клиенте, не создавая лишней нагрузки на сервер:

&НаКлиенте
Процедура ПересчитатьФормулу()
    ИтогУмноженный = Объект.Запасы.Итог("Всего") * 2;
КонецПроцедуры

Теперь определим минимально необходимый и оптимальный набор событий для вызова этой процедуры, чтобы надпись всегда оставалась актуальной.

Оптимизация набора событий для пересчета

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

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

Посмотрим на пример комплексного модуля формы с подключенными событиями:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    ИтогУмноженный = Объект.Запасы.Итог("Всего") * 2;
КонецПроцедуры

&НаКлиенте
Процедура ЗапасыПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
    Если Не ОтменаРедактирования Тогда
        ПересчитатьФормулу();
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ЗапасыПослеУдаления(Элемент)
    ПересчитатьФормулу();
КонецПроцедуры

&НаКлиенте
Процедура ЗапасыВсегоПриИзменении(Элемент)
    ПересчитатьФормулу();
КонецПроцедуры

Способ 2. Вывод формулы через декорацию-надпись

Разберем альтернативный вариант, который позволяет обойтись без добавления отдельного реквизита формы. Для этого используем элемент формы с видом Декорация (ВидДекорацииФормы.Надпись).

Элементу декорации не требуется заполнять ПутьКДанным. Мы можем обращаться напрямую к его свойству Заголовок из клиентского кода. Посмотрим на реализацию расчета:


&НаКлиенте
Процедура ПересчитатьФормулуДекорации()
    Результат = Объект.Запасы.Итог("Всего") * 2;
    Элементы.ДекорацияИтог.Заголовок = "Удвоенный итог: " + Формат(Результат, "ЧДЦ=2");
КонецПроцедуры

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

Оценка подхода с добавлением расчетного реквизита в табличную часть

Иногда разработчики рассматривают вариант создания скрытого реквизита табличной части (например, ВсегоУдвоенное) с включенным признаком подсчета итогов. В таком случае платформа автоматически сформирует свойство Объект.Запасы.ИтогВсегоУдвоенное, к которому можно привязать Поле надписи без написания обработчиков пересчета общего итога.

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

← На главную