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

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

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

Почему не работает метод Итог() для свойств номенклатуры?

Метод Итог() в 1С предназначен для работы с данными, которые физически присутствуют в табличной части объекта (например, Объект.Товары.Итог("Количество")). Когда мы обращаемся к реквизиту через точку (например, СтрокаТаблицы.Номенклатура.Вес), мы работаем с данными справочника, а не табличной части. В такой ситуации табличная часть 1С «не знает» о суммарном значении этих полей, и попытка вызвать стандартный метод Итог() приведет либо к ошибке выполнения, либо к пустому результату.

Пошаговое решение: расчет суммы через цикл

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

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

Давайте посмотрим на правильный пример кода для реализации этой задачи:


// Инициализируем переменную ДО цикла
ВесВсего = 0;

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

// Выводим итог в подвал ПОСЛЕ цикла
Подвал.Параметры.ВесОбщий = ВесВсего;
ТабличныйДокумент.Вывести(Подвал);

Распространенные ошибки при разработке

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

Альтернативный и более производительный подход: Запрос

Если документ содержит большое количество позиций, использование циклов может быть менее производительным. В таких случаях лучше использовать Запрос. С помощью запроса вы можете объединить табличную часть документа со справочником номенклатуры и получить общую сумму одним методом Выбрать() или используя конструкцию ИТОГИ.

Рассмотрим структуру запроса:


ВЫБРАТЬ
    Товары.Номенклатура КАК Номенклатура,
    Товары.Номенклатура.ВесЧислитель КАК Вес
ПОМЕСТИТЬ ВТ_Товары
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
    Товары.Ссылка = &Ссылка;

ВЫБРАТЬ
    СУММА(Вес) КАК ОбщийВес
ИЗ
    ВТ_Товары;

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

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

← На главную