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

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

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

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

Почему возникает ошибка при работе с коллекцией Элементы

Распространенная ошибка начинающих разработчиков — попытка выполнить деление или умножение непосредственной адресацией к визуальным элементам интерфейса, например: Элементы.Таблица.ПолеФормула = Элементы.Таблица.Поле1 / Элементы.Таблица.Поле2.

В управляемых формах коллекция Элементы отвечает исключительно за элементы отображения (поля ввода, надписи, кнопки). Данные документа хранятся в реквизите Объект. Выполнять любые математические операции необходимо только с данными, обращаясь к структуре Объект.ТабличнаяЧасть или к текущей строке данных.

Расчет формулы для текущей редактируемой строки

Если требуется, чтобы результат вычислялся динамически прямо при изменении пользователем исходных данных в конкретной строке, рассмотим следующий подход:

  1. Перейдем в свойства реквизитов (или элемента формы) в табличной части и создадим обработчик события ПриИзменении. Обработчик следует назначить на **каждый** реквизит, участвующий в расчете (и для делимого, и для делителя).
  2. Получим текущие данные редактируемой строки с помощью свойства ТекущиеДанные элемента таблицы.
  3. Выполним расчет формулы.

Пример кода для клиентского обработчика события ПриИзменении:


&НаКлиенте
Процедура ТоварыПоле1ПриИзменении(Элемент)
    
    СтрокаТаблицы = Элементы.Товары.ТекущиеДанные;
    
    Если СтрокаТаблицы <> Неопределено Тогда
        // Проверяем делитель на ноль во избежание критической ошибки
        Если СтрокаТаблицы.Поле2 <> 0 Тогда
            СтрокаТаблицы.ПолеФормула = СтрокаТаблицы.Поле1 / СтрокаТаблицы.Поле2;
        Иначе
            СтрокаТаблицы.ПолеФормула = 0;
        КонецЕсли;
    КонецЕсли;

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

Пересчет всех строк табличной части в цикле

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

Рассмотрим пример обхода всех строк табличной части Товары:


Для Каждого ТекСтрока Из Объект.Товары Цикл
    
    Если ТекСтрока.Поле2 <> 0 Тогда
        ТекСтрока.ПолеФормула = ТекСтрока.Поле1 / ТекСтрока.Поле2;
    Иначе
        ТекСтрока.ПолеФормула = 0;
    КонецЕсли;
    
КонецЦикла;

Обращение к реквизитам через точку (например, коэффициент номенклатуры)

Если в формуле дополнительно используется реквизит связанного справочника (например, Номенклатура.КоэффициентЕдиницыДляОтчетов), обращение к нему выглядит аналогично, путем получения свойства через точку от объекта номенклатуры в строке:


// Пример расчета текущей строки с учетом коэффициента номенклатуры
СтрокаТаблицы = Элементы.Товары.ТекущиеДанные;

Если СтрокаТаблицы <> Неопределено И СтрокаТаблицы.Поле2 <> 0 Тогда
    Коэффициент = СтрокаТаблицы.Номенклатура.КоэффициентЕдиницыДляОтчетов;
    СтрокаТаблицы.ПолеФормула = (СтрокаТаблицы.Поле1 / СтрокаТаблицы.Поле2) * Коэффициент;
КонецЕсли;

Важная защита от ошибок и особенности платформы

При написании математических формул в форме документа важно учитывать следующие ключевые моменты:

  1. Проверка деления на ноль: Незаполненный числовой реквизит по умолчанию равен 0. Выполнение деления на ноль вызовет аварийное завершение работы программы с ошибкой. Всегда добавляйте условие Если Делитель <> 0 Тогда.
  2. Проверка на Неопределено: Свойство Элементы.Таблица.ТекущиеДанные возвращает Неопределено, если в таблице нет активной выбранной строки или таблица пуста. Обязательно проверяйте условие Если ТекущиеДанные <> Неопределено Тогда.
  3. Сохранение результатов: Если новое вычисляемое поле добавлено только как «Реквизит формы» и отсутствуют соответствующие колонки в конфигураторе у самой табличной части объекта, то при закрытии и повторном открытии документа эти значения не сохранятся в базе данных. В таком случае процедуру расчета необходимо также вызывать при открытии формы в событии ПриСозданииНаСервере или ПриЧтенииНаСервере.
← На главную