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

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

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

Разбор типичной ошибки: почему ТекущиеДанные не подходят для массового расчета

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


ТекДанные = Элементы.Товары.ТекущиеДанные;
ТекДанные.Сумма = ТекДанные.Цена * Текданные.Количество;

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

Решение 1: Массовый расчет в цикле на сервере

Для инициализации данных при открытии формы правильнее всего использовать серверное событие ПриСозданииНаСервере. Это позволяет подготовить данные до того, как они будут переданы на клиент и отрисованы пользователю. Выполнение расчетов на сервере минимизирует количество вызовов между клиентом и сервером, что положительно сказывается на производительности.

Разберем по шагам, как реализовать обход строк табличной части Товары, которая входит в состав основного реквизита Объект:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Перебираем все строки табличной части документа
    Для Каждого СтрокаТовара Из Объект.Товары Цикл
        
        // Выполняем расчет суммы для каждой строки
        СтрокаТовара.Сумма = СтрокаТовара.Цена * СтрокаТовара.Количество;
        
    КонецЦикла;
    
КонецПроцедуры

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

Решение 2: Автоматизация расчета при изменении данных

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

Выясним, как это реализовать профессионально:

  1. Найдем в дереве элементов формы колонки ТоварыЦена и ТоварыКоличество.
  2. Для обеих колонок назначим один и тот же обработчик события ПриИзменении.
  3. Внутри обработчика будем использовать ТекущиеДанные, так как в момент редактирования конкретной строки фокус гарантированно находится на ней.

&НаКлиенте
Процедура ТоварыДанныеПриИзменении(Элемент)
    
    // Получаем строку, которую редактирует пользователь
    ТекДанные = Элементы.Товары.ТекущиеДанные;
    
    Если ТекДанные <> Неопределено Тогда
        // Рассчитываем сумму
        ТекДанные.Сумма = ТекДанные.Цена * ТекДанные.Количество;
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: использование проверки на Неопределено позволяет избежать критических ошибок в случае, если пользователь попытается вызвать событие в пустой таблице.

Решение 3: Работа с динамическими списками

Если ваша таблица на форме является не табличной частью документа, а Динамическим списком (например, вы отображаете список заказов с остатками), то использование циклов будет неэффективным или невозможным. В этом случае расчет суммы следует перенести на уровень SQL-запроса.

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


ВЫБРАТЬ
    ТаблицаТовары.Ссылка,
    ТаблицаТовары.Цена,
    ТаблицаТовары.Количество,
    (ТаблицаТовары.Цена * ТаблицаТовары.Количество) КАК Сумма
ИЗ
    Документ.ЗаказПокупателя.Товары КАК ТаблицаТовары

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

Решение 4: Использование Условного оформления (Только просмотр)

Если вам нужно просто показать сумму пользователю, не сохраняя её в базу данных (например, в справочнике номенклатуры для ознакомления), можно воспользоваться механизмом Условного оформления. Хотя чаще его используют для раскраски строк, в некоторых конфигурациях через него можно выводить вычисляемые значения в текстовые поля колонок, используя шаблоны или специальные настройки СКД (в отчетах).

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

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

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

Подводя итог, можно сказать: чтобы колонка "Сумма" заполнялась корректно, всегда разделяйте логику первоначального заполнения (на сервере через цикл по данным реквизита) и логику оперативного изменения (на клиенте через ТекущиеДанные в обработчике события колонки).

← На главную