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

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

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

Анализ проблемы: почему итог равен нулю?

Давайте посмотрим на типичный код формирования печатной формы, где допущена логическая ошибка. Разработчик пытается вывести общую сумму и общий вес, обходя выборку из запроса:


Сумма = 0;
ВесБрутто = 0;
ВесНетто = 0;

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

ОбластьМакетаПодвал.Параметры.Сумма = Сумма;
ОбластьМакетаПодвал.Параметры.ВесНеттоПрописью = ЧислоПрописью(ВесНетто,,"тонна, тонны, тонн, м, килограмм, килограмма, килограммов, ж, 3");

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

Добавим нужную строку в код:


Сумма = Сумма + ВыборкаСтрокТовары.Сумма;
ВесНетто = ВесНетто + ВыборкаСтрокТовары.ВесНетто; // Накапливаем вес

Ошибка «Поле объекта не обнаружено»

Часто после добавления счетчика платформа выдает ошибку: «Поле объекта не обнаружено (ВесНетто)». Выясним причину. Эта ошибка означает, что в переменной ВыборкаСтрокТовары (которая является строкой результата запроса) физически нет колонки ВесНетто.

Если мы посмотрим на исходный запрос к табличной части Товары, мы увидим, что данные о весе хранятся в другой табличной части (например, ВесНеттоБрутто). Чтобы поле появилось в выборке, его необходимо добавить в текст запроса.

Оптимизация получения данных: избавляемся от поиска в цикле

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

Использование поиска или запросов внутри цикла многократно замедляет формирование печатной формы. Правильный подход — объединить табличные части еще на этапе выполнения самого запроса. Для этого используем конструкцию ЛЕВОЕ СОЕДИНЕНИЕ по общему ключу (например, по Номенклатуре).

При соединении таблиц обязательно помните о значениях NULL. Если для товара не окажется строки во второй табличной части, база вернет NULL, и попытка математического сложения вызовет ошибку. Оборачиваем поле в функцию ЕСТЬNULL:


ВЫБРАТЬ
    Товары.Номенклатура,
    Товары.Количество,
    Товары.Сумма,
    ЕСТЬNULL(ВесДанные.ВесНетто, 0) КАК ВесНетто
ИЗ
    Документ.ПоступлениеТоваровУслуг.Товары КАК Товары
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваровУслуг.ВесНеттоБрутто КАК ВесДанные
        ПО Товары.Ссылка = ВесДанные.Ссылка
        И Товары.Номенклатура = ВесДанные.Номенклатура

Использование встроенных методов для итогов

Рассмотрим альтернативные, более элегантные способы получения общей суммы, не прибегая к ручному суммированию в цикле:

  1. Использование метода таблицы значений. Если результат запроса выгружен в таблицу значений (Запрос.Выполнить().Выгрузить()), вы можете получить итог одной строкой: ВесНетто = ВыборкаСтрок.Итог("ВесНетто");
  2. Итоги в запросе. Можно поручить подсчет самому запросу, добавив в конец конструкции команду ИТОГИ СУММА(ВесНетто) ПО ОБЩИЕ.

Нюансы функции «ЧислоПрописью»

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

Единица 1, Единица 2..4, Единица 5+, Род (М/Ж/С), ДробнаяЕдиница 1, ДробнаяЕдиница 2..4, ДробнаяЕдиница 5+, Род дробной части, Количество знаков дробной части.

Пример строки для тонн и килограммов:


ФорматВеса = "тонна, тонны, тонн, ж, килограмм, килограмма, килограммов, м, 3";
ОбластьМакетаПодвал.Параметры.ВесНеттоПрописью = ЧислоПрописью(ВесНетто, , ФорматВеса);

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

Разделение логики и шаблона

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

← На главную