Как сложить сумму по колонке программно в 1С и вывести результат прописью

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

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

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

Способ 1. Использование встроенного метода «Итог()»

Это самый простой, лаконичный и быстрый способ получить сумму по колонке, если мы работаем с объектом типа ТаблицаЗначений, ТабличнаяЧасть или ДанныеФормыКоллекция. Платформа 1С выполняет этот расчет на уровне оптимизированного внутреннего кода, что работает значительно быстрее ручного обхода строк.

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

ИтогоКоличество = МояТаблицаЗначений.Итог("Количество");

Рассмотрим распространенную ошибку, с которой сталкиваются новички на форумах. При попытке скопировать этот код напрямую может возникнуть ошибка «Переменная не определена (МояТаблицаЗначений)». Важно понимать, что вместо МояТаблицаЗначений необходимо подставить реальное имя вашей таблицы или табличной части в контексте модуля. Например:

Способ 2. Классический обход таблицы в цикле «Для Каждого»

Если по какой-то причине вам требуется не просто сложить все значения, а попутно выполнить дополнительные проверки или вычисления (например, суммировать только строки, удовлетворяющие определенному условию), используется ручной обход коллекции строк.

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


// НЕПРАВИЛЬНЫЙ ВАРИАНТ (ошибка сброса результата)
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
    ИтогоКоличество = 0; // На каждой итерации итог сбрасывается в ноль!
    ИтогоКоличество = ИтогоКоличество + СтрокаТЧ.Количество;
КонецЦикла;

В приведенном выше примере переменная ИтогоКоличество инициализируется нулем прямо внутри цикла. В результате на каждом шаге предыдущая накопленная сумма теряется, и после завершения цикла переменная будет содержать значение «Количество» только из самой последней строки таблицы.

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


// ПРАВИЛЬНЫЙ ВАРИАНТ
ИтогоКоличество = 0; // Инициализируем переменную ДО начала обхода
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
    ИтогоКоличество = ИтогоКоличество + СтрокаТЧ.Количество;
КонецЦикла;

Этот способ универсален и применим к любым коллекциям 1С, которые поддерживают обход в цикле Для Каждого.

Способ 3. Агрегация данных с помощью метода «Свернуть()»

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

Проанализируем пример кода:


// Создаем копию таблицы, чтобы не испортить исходные данные на форме или в объекте
ВременнаяТЗ = Объект.Товары.Выгрузить();

// Первый параметр — колонки группировки (оставляем пустым для получения общего итога)
// Второй параметр — суммируемые колонки
ВременнаяТЗ.Свернуть("", "Количество");

// После свертки в таблице останется ровно одна строка, содержащая общий итог
Если ВременнаяТЗ.Количество() > 0 Тогда
    ИтогоКоличество = ВременнаяТЗ[0].Количество;
КонецЕсли;

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

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

Способ 4. Подсчет суммы через Запрос

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

Рассмотрим практический пример получения суммы по табличной части сохраненного документа:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	СУММА(РеализацияТовары.Количество) КАК ОбщийИтог
    |ИЗ
    |	Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары
    |ГДЕ
    |	РеализацияТовары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ЭтотОбъект.Ссылка);

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Если Выборка.Следующий() Тогда
    ИтогоКоличество = ?(ЗначениеЗаполнено(Выборка.ОбщийИтог), Выборка.ОбщийИтог, 0);
КонецЕсли;

Особенности подсчета итогов в управляемых формах и Деревьях значений

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

  1. Табличные части на форме: Реквизиты формы, отображающие таблицы, имеют тип ДанныеФормыКоллекция. Для них метод Итог() работает аналогично таблице значений. Чтобы итоги пересчитывались динамически при изменении количества пользователем «на лету», используйте обработчик события ПриИзменении в строке табличной части, обновляя итоговые поля формы.
  2. Дерево значений (иерархические структуры): Если вы примените стандартный метод МоеДерево.Итог("Количество"), платформа вернет сумму значений только для ветвей самого верхнего (корневого) уровня. Вложенные подчиненные строки проигнорируются. Для полного суммирования по дереву значений потребуется рекурсивная функция обхода ветвей.

Решение главной задачи: вывод итогового количества прописью

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

Основная сложность заключается в том, что по умолчанию эта функция ориентирована на денежный формат (рубли и копейки). Если передать туда просто число, на выходе мы получим что-то вроде: «Пятьдесят рублей 00 копеек». Чтобы преобразовать «штучный» или «весовой» товар, необходимо правильно настроить параметры функции.

Синтаксис вызова:

ЧислоПрописью(Число, ФорматнаяСтрока, ПараметрыПредметаИсчисления)

Вариант А. Вывод числа словами с указанием единиц измерения (например, «штука»)

Чтобы числительные грамматически верно склонялись вместе с существительным (например, «Двадцать одна штука», «Две штуки», «Пять штук»), нам нужно составить специальную строку параметров предмета исчисления.

Разберем готовый шаблон кода:


ИтогоКоличество = Объект.Товары.Итог("Количество");

// Формируем параметры исчисления для штук:
// Название единицы в разных падежах, женский род ("ж"), точность дробной части 0
ПараметрыПредмета = "штука, штуки, штук, ж, , , , , 0";

КоличествоПрописью = ЧислоПрописью(ИтогоКоличество, "Л=ru_RU", ПараметрыПредмета);
// Для числа 5 результат будет: "Пять штук"
// Для числа 21 результат будет: "Двадцать одна штука"

Вариант Б. Вывод «чистого» числа словами без указания валют и единиц

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


ИтогоКоличество = Объект.Товары.Итог("Количество");

// Оставляем пустыми падежи, но указываем "0" в конце для отключения дробной части
КоличествоПрописью = ЧислоПрописью(ИтогоКоличество, "Л=ru_RU", ", , , , , , , , 0");
// Для числа 150 результат будет: "Сто пятьдесят"

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

← На главную