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

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

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

Анализ проблемы: почему метод Итог() не работает в выборке запроса

Рассмотрим типичную ситуацию. Программист создает запрос, который выбирает данные документа и его табличную часть (вложенную таблицу). При обходе результата запроса через Выборка.Следующий() переменная Выборка.Товары (если мы используем вложенные таблицы) имеет тип ВыборкаИзРезультатаЗапроса. У этого объекта действительно нет метода Итог(). Этот метод существует у объекта ТаблицаЗначений или непосредственно у табличной части документа (объекта), но не у выборки данных из базы.

Проанализируем первый вариант кода, который часто приводит к ошибке:


// Ошибочный подход
СуммаВсего = Товары.Итог("Сумма"); // 1С не знает, что такое "Товары" в данном контексте
// или
СуммаВсего = Выборка.Товары.Итог("Сумма"); // Ошибка: Метод объекта не обнаружен (Итог)

Для решения этой задачи мы можем пойти несколькими путями, в зависимости от требований к производительности и сложности структуры документа.

Способ №1: Ручной подсчет суммы в цикле обхода (Наиболее эффективный)

Этот метод считается «классическим» и самым экономичным с точки зрения ресурсов сервера. Поскольку мы в любом случае перебираем строки табличной части для вывода их в ТабДок (табличный документ), мы можем параллельно накапливать сумму в переменной.

Разберем этот процесс по шагам:

  1. Инициализируем переменную СуммаВсего нулем перед началом цикла обхода строк.
  2. Внутри цикла при каждом проходе прибавляем значение текущей строки к этой переменной.
  3. После завершения цикла передаем накопленное значение в параметры области макета.

Рассмотрим пример реализации:


// Инициализируем переменную перед выводом строк
СуммаВсего = 0;

// Начинаем выборку строк табличной части "Товары"
ВыборкаТовары = Выборка.Товары.Выбрать();

Пока ВыборкаТовары.Следующий() Цикл
    // Заполняем параметры строки макета
    ОбластьТовары.Параметры.Заполнить(ВыборкаТовары);
    
    // Выводим строку в табличный документ
    ТабДок.Вывести(ОбластьТовары, ВыборкаТовары.Уровень);
    
    // Суммируем итог в переменную
    СуммаВсего = СуммаВсего + ВыборкаТовары.Сумма;
КонецЦикла;

// После цикла заполняем область подвала (итогов)
ИтогоСумма.Параметры.СуммаВсего = СуммаВсего;
ТабДок.Вывести(ИтогоСумма);

Преимущество: Мы не делаем лишних запросов к базе данных и не создаем дополнительных объектов в памяти.

Способ №2: Использование метода Выгрузить() и Итог()

Если вы хотите сохранить лаконичность кода и использовать встроенный метод Итог(), можно принудительно преобразовать выборку во временную таблицу значений. Это позволит вызвать метод напрямую, но стоит помнить, что на больших объемах данных это может быть чуть медленнее, чем ручной подсчет.

Посмотрим на пример кода:


// Выгружаем вложенную таблицу выборки в полноценную таблицу значений
ТаблицаТоваров = Выборка.Товары.Выгрузить();

// Теперь мы можем использовать метод Итог()
СуммаВсего = ТаблицаТоваров.Итог("Сумма");

// Выводим результат в макет
ИтогоСумма.Параметры.СуммаВсего = СуммаВсего;
ТабДок.Вывести(ИтогоСумма);

Этот способ удобен, если вам нужно выполнять более сложные манипуляции с данными (например, фильтрацию или поиск по таблице) перед выводом итогов.

Способ №3: Получение итога через объект ссылки

Иногда программисты пытаются получить итог напрямую из ссылки документа, которая передается в процедуру печати: Ссылка.Товары.Итог("Сумма").

Внимание: Этот метод таит в себе подводный камень. Обращение через точку к табличной части ссылки Ссылка.Товары заставляет 1С выполнить неявный (скрытый) запрос к базе данных, чтобы получить данные объекта. Если вы уже получили эти данные основным запросом в начале процедуры, то такое обращение будет избыточным и замедлит формирование печатной формы.

Однако, если по каким-то причинам в вашем запросе нет вложенной таблицы, этот метод может выглядеть так:


// Получаем итог напрямую из данных объекта по ссылке
Если ЗначениеЗаполнено(Ссылка) Тогда
    ОбщаяИТОГ = Ссылка.Товары.Итог("Сумма");
    ИтогоСумма.Параметры.СуммаВсего = ОбщаяИТОГ;
КонецЕсли;

Рекомендации по оформлению итогов в печатной форме

Просто получить число — это только половина задачи. В профессиональных печатных формах итоги должны быть правильно отформатированы. Проанализируем два важных аспекта:

1. Форматирование числа. Чтобы сумма не выглядела как «10000», а имела разделители и копейки («10 000,00»), используйте функцию Формат().

ИтогоСумма.Параметры.СуммаВсего = Формат(СуммаВсего, "ЧЦ=15; ЧДЦ=2; ЧГ=3,0");

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


// Пример вывода суммы прописью для валюты РФ
ПараметрыВалюты = "L=ru_RU; SN=true";
ПредставлениеСуммы = ЧислоПрописью(СуммаВсего, ПараметрыВалюты, "рубль, рубля, рублей, м, копейка, копейки, копеек, ж, 2");
ОбластьПодвал.Параметры.СуммаПрописью = ПредставлениеСуммы;

Подведение итогов

Мы рассмотрели различные подходы к решению проблемы вывода итогов. Подведем итог: если вы используете запрос с вложенной таблицей (как это делает стандартный конструктор), самым оптимальным решением будет суммирование в цикле (Способ №1). Это гарантирует максимальную скорость работы и отсутствие ошибок типов. Если же код нужно написать максимально быстро и объем данных невелик, можно использовать выгрузку в таблицу значений (Способ №2).

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

← На главную