При разработке внешних печатных форм в 1С часто возникает задача вывести в итог документа данные, которых нет непосредственно в табличной части (например, вес номенклатуры, хранящийся в справочнике). Многие разработчики сталкиваются с ошибками, пытаясь использовать метод Итог() к полям, которые не являются частью табличной части, или допуская ошибки в логике циклов. Давайте разберем, как реализовать эту задачу правильно и эффективно.
Метод Итог() в 1С предназначен для работы с данными, которые физически присутствуют в табличной части объекта (например, Объект.Товары.Итог("Количество")). Когда мы обращаемся к реквизиту через точку (например, СтрокаТаблицы.Номенклатура.Вес), мы работаем с данными справочника, а не табличной части. В такой ситуации табличная часть 1С «не знает» о суммарном значении этих полей, и попытка вызвать стандартный метод Итог() приведет либо к ошибке выполнения, либо к пустому результату.
Если данные необходимо получать именно в процессе обхода строк табличной части, самый надежный способ — это использование переменной-накопителя. Рассмотрим пошагово, как это реализовать, чтобы избежать распространенных ошибок.
Подвал или Подвал2 должен происходить строго после завершения цикла.Давайте посмотрим на правильный пример кода для реализации этой задачи:
// Инициализируем переменную ДО цикла
ВесВсего = 0;
Для Каждого СтрокаТовары Из ТаблицаТовары Цикл
// Получаем значение веса из справочника Номенклатура
ВесТекущейПозиции = СтрокаТовары.Номенклатура.ВесЧислитель;
// Накапливаем сумму
ВесВсего = ВесВсего + ВесТекущейПозиции;
// Выводим вес по строке в макет (если нужно)
СтрокаТаблицыТовары.Параметры.Вес = ВесТекущейПозиции;
КонецЦикла;
// Выводим итог в подвал ПОСЛЕ цикла
Подвал.Параметры.ВесОбщий = ВесВсего;
ТабличныйДокумент.Вывести(Подвал);
В процессе работы мы часто видим одни и те же ошибки, которые приводят к пустым значениям или неверным результатам:
ВесВсего = 0 перед циклом приводит к ошибкам преобразования типов или непредсказуемому поведению.Подвал внутрь цикла, результат будет выводиться для каждой строки отдельно, затирая или дублируя данные. Помните: итог выводится один раз — в финале.Подвал, а не к области, которая выводится в строках документа.Если документ содержит большое количество позиций, использование циклов может быть менее производительным. В таких случаях лучше использовать Запрос. С помощью запроса вы можете объединить табличную часть документа со справочником номенклатуры и получить общую сумму одним методом Выбрать() или используя конструкцию ИТОГИ.
Рассмотрим структуру запроса:
ВЫБРАТЬ
Товары.Номенклатура КАК Номенклатура,
Товары.Номенклатура.ВесЧислитель КАК Вес
ПОМЕСТИТЬ ВТ_Товары
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка = &Ссылка;
ВЫБРАТЬ
СУММА(Вес) КАК ОбщийВес
ИЗ
ВТ_Товары;
Использование запросов не только ускоряет работу печатной формы, но и делает код более чистым и профессиональным. Мы рекомендуем по возможности всегда использовать запросы для получения итоговых данных, так как это снижает нагрузку на систему и исключает ошибки, связанные с ручным перебором строк.
Совет: Если данные все равно не выводятся, обязательно воспользуйтесь Отладчиком. Поставьте точку останова на строке после цикла и проверьте значение переменной ВесВсего. Если она равна нулю, значит, данные из справочника не были получены корректно (проверьте, заполнен ли реквизит у номенклатуры).