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