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

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

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

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

Критический разбор ошибок в простых решениях

Начинающие разработчики часто пытаются решить задачу простым сложением при изменении строки. Типичный пример некорректного кода выглядит так:


&НаКлиенте
Процедура СписокТоваровСуммаПриИзменении(Элемент)
    Строка = Элементы.СписокТоваров.ТекущиеДанные;
    Объект.Всего = Объект.Всего + Строка.Сумма; 
КонецПроцедуры

Проанализируем ситуацию и выясним, почему этот код категорически **нельзя использовать** в реальных конфигурациях:

  1. Накопительный эффект: При каждом изменении значения в текущей строке старое значение суммы не вычитается, а новое просто прибавляется к переменной Объект.Всего. Сумма будет бесконечно увеличиваться при редактировании одной и той же строки.
  2. Игнорирование удаления строк: Если пользователь удалит строку из табличной части, событие ПриИзменении конкретной колонки не сработает, и общий итог не уменьшится.
  3. Очистка таблицы: При полной очистке таблицы значение в реквизите Всего останется прежним.

Другая частая ошибка — простое присвоение значения текущей строки:

Объект.Всего = Элементы.СписокТоваров.ТекущиеДанные.Сумма;

Такой код просто перезапишет реквизит Всего значением из активной строки. Если в документе несколько строк, то общая сумма станет равна сумме последней измененной строки, что полностью ломает логику учета.

Решение 1. Программный расчет через встроенный метод Итог()

Для корректного программного расчета суммы по всей табличной части в платформе 1С предусмотрен специальный метод Итог(). Он работает быстро, надежно и автоматически обходит все строки таблицы.

Разберем по шагам правильную программную реализацию расчета:

Шаг 1. Создаем общую процедуру расчета итогов на клиенте

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


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

Шаг 2. Подключаем обработчики событий для колонок

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


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

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

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

Шаг 3. Обработка добавления и удаления строк

Чтобы сумма оставалась актуальной при добавлении новых или удалении старых строк, необходимо привязать расчет к событию ПриИзменении самой табличной части (а не ее отдельных колонок):


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

Решение 2. Быстрый платформенный метод (ИтогСумма)

Если вам требуется просто отобразить общую сумму табличной части на форме без необходимости записывать её в базу данных (или если запись будет происходить в модуле объекта перед записью), платформа 1С предлагает мощный встроенный механизм декларативной связи.

Рассмотрим, как настроить авторасчет вообще без написания кода:

  1. Откройте управляемую форму вашего документа или справочника в конфигураторе.
  2. В окне элементов формы (слева вверху) найдите или создайте поле ввода, в котором хотите отображать итог (например, назовем его ВсегоДекоративно).
  3. Откройте свойства этого поля ввода (нажмите F4).
  4. Найдите свойство ПутьКДанным (DataPath).
  5. Нажмите на кнопку выбора («три точки») и разверните структуру вашего объекта: Объект -> СписокТоваров.
  6. В самом низу списка реквизитов табличной части вы увидите виртуальное поле ИтогСумма (или имя вашей колонки с префиксом Итог, например, ИтогСуммаСтроки). Выберите его.

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

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


// В модуле документа
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Всего = СписокТоваров.Итог("Сумма");
КонецПроцедуры

Решение 3. Расчет итогов с учетом активных отборов

Рассмотрим более сложную практическую задачу. Что делать, если пользователь воспользовался встроенным поиском по табличной части (отбором) и нам нужно показать сумму только тех строк, которые он сейчас видит на экране?

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


&НаКлиенте
Функция ПолучитьСуммуВидимыхСтрок()
    РезультатСумма = 0;
    
    Для Каждого СтрокаТЧ Из Объект.СписокТоваров Цикл
        ИдентификаторСтроки = СтрокаТЧ.ПолучитьИдентификатор();
        
        // Проверяем, отображается ли строка на форме с учетом фильтров
        Если Элементы.СписокТоваров.ПроверитьСтроку(ИдентификаторСтроки) Тогда
            РезультатСумма = РезультатСумма + СтрокаТЧ.Сумма;
        КонецЕсли;
    КонецЦикла;
    
    Возврат РезультатСумма;
КонецФункции

Стандарты разработки фирмы «1С» для вывода итогов

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

← На главную