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

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

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

Анализ типичных ошибок начинающих разработчиков

Рассмотрим частые ошибки, приводящие к сбоям или отсутствию пересчета:

  1. Обращение к табличной части как к одной строке. Попытка написать выражение вида Объект.ТабличнаяЧасть.Сумма = Объект.ТабличнаяЧасть.Количество * Объект.ТабличнаяЧасть.Цена; приводит к ошибке выполнения. Табличная часть на управляемой форме представляет собой коллекцию строк (тип ДанныеФормыКоллекция). У коллекции в целом нет свойств конкретной строки — к колонкам можно обращаться только через конкретную выбранную или обходимую строку.
  2. Попытка получить данные строки через поле ввода. Обращение вида Элементы.ЛистЗаказаЦена.ТекущиеДанные вызывает системную ошибку «Поле объекта не обнаружено (ТекущиеДанные)». Свойство ТекущиеДанные доступно исключительно у самого элемента управления таблицы формы (например, Элементы.ЛистЗаказа), но не у подчиненных ему колонок или полей ввода.
  3. Неправильный выбор событий элемента. Назначение вычислений на события АвтоПодбор, ОкончаниеВводаТекста или события самой таблицы приводит к непредсказуемому поведению. Для обработки ввода конкретного значения пользователем предназначено строго определенное стандартное событие — ПриИзменении соответствующего поля ввода.

Пошаговая настройка обработчиков событий формы

Разберем классический способ решения задачи на клиенте:

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

&НаКлиенте
Процедура ЛистЗаказаЦенаПриИзменении(Элемент)
    СтрокаТаблицы = Элементы.ЛистЗаказа.ТекущиеДанные;
    СтрокаТаблицы.Сумма = СтрокаТаблицы.Количество * СтрокаТаблицы.Цена;
КонецПроцедуры

&НаКлиенте
Процедура ЛистЗаказаКоличествоПриИзменении(Элемент)
    СтрокаТаблицы = Элементы.ЛистЗаказа.ТекущиеДанные;
    СтрокаТаблицы.Сумма = СтрокаТаблицы.Количество * СтрокаТаблицы.Цена;
КонецПроцедуры

Оптимизация кода: один обработчик и проверка на пустое значение

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

Для повышения надежности и чистоты кода вынесем формулу расчета в отдельную вспомогательную процедуру и добавим проверку строки, а также округление результата с помощью функции Окр():


&НаКлиенте
Процедура ЛистЗаказаКоличествоЦенаПриИзменении(Элемент)
    РассчитатьСуммуСтроки(Элементы.ЛистЗаказа.ТекущиеДанные);
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьСуммуСтроки(Строка)
    Если Строка <> Неопределено Тогда
        Строка.Сумма = Окр(Строка.Количество * СтрокаТаблицы.Цена, 2);
    КонецЕсли;
КонецПроцедуры

После создания такой процедуры вернемся в свойства элементов формы: как для поля ЛистЗаказаКоличество, так и для ЛистЗаказаЦена в строке события ПриИзменении выберем одну и ту же процедуру ЛистЗаказаКоличествоЦенаПриИзменении из выпадающего списка.

Особенности работы с данными и программный расчет

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

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


Для Каждого Стр Из Объект.ЛистЗаказа Цикл
    Стр.Сумма = Окр(Стр.Количество * Стр.Цена, 2);
КонецЦикла;

Вывод итоговой суммы по всей таблице без кода

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

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

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

← На главную