При работе с отраслевыми решениями, такими как УСХП 1.3 или УПП 1.3, часто возникает необходимость кастомизации стандартных печатных форм под требования конкретного бизнеса. Одной из классических задач является модификация накладной ТОРГ-12 для вывода дополнительных характеристик товара, например, веса бетона, его плотности или пересчета единиц измерения в реальном времени. Рассмотрим подробно, как реализовать этот функционал, избежав типичных ошибок начинающих разработчиков.
Для начала проанализируем ситуацию: бетон продается в метрах кубических (м3), но заказчик хочет видеть в печатной форме еще и вес (массу нетто), рассчитанный на основе плотности. Плотность в данном случае удобно хранить в реквизите Вес справочника ЕдиницыИзмерения. Наша задача — изменить запрос печатной формы, добавить расчетную логику в модуль и вывести данные в макет.
Первым делом необходимо отредактировать сам макет. В области Строка добавим новые параметры, например, Вес, Объем и ЦенаЗаКуб. Помните, что добавление колонок в ТОРГ-12 требует внимательности, так как форма жестко регламентирована, и лишние смещения могут испортить итоговый документ.
В типовых решениях на обычных формах данные для печати собираются функцией ПечатьТОРГ12(). Основная ошибка новичков — попытка делать запросы к базе данных внутри цикла обхода строк (сообщения 3 и 15 на форуме). Это приводит к катастрофическому падению производительности. Правильный путь — модификация текста основного запроса ТекстЗапросаТовары.
Нам нужно извлечь вес из единицы измерения. Разберем, как это сделать через обращение к полям вложенного запроса. Добавим выборку веса:
// В секции выбора полей основного запроса добавляем:
| ВложенныйЗапрос.ЕдиницаИзмерения.Вес КАК Вес,
| ВложенныйЗапрос.ЕдиницаИзмерения.ЕдиницаПоКлассификатору.Код КАК КодОКЕИ,
Обратите внимание на КодОКЕИ. Использование кода по классификатору (например, "113" для м3) гораздо надежнее, чем проверка по наименованию "м3", которое пользователь может изменить вручную.
После того как запрос выполнен и данные выгружены в таблицу (или выборку), мы переходим к обработке каждой строки. Здесь мы будем рассчитывать массу и объем. Проанализируем фрагмент кода, который позволяет корректно заполнять параметры макета:
Для Каждого ВыборкаСтрок Из ЗапросТовары Цикл
// Пропускаем пустые строки или услуги, если нужно
Если НЕ ЗначениеЗаполнено(ВыборкаСтрок.Номенклатура) Тогда
Продолжить;
КонецЕсли;
// Получаем данные из выборки
Количество = ВыборкаСтрок.Количество;
Плотность = ВыборкаСтрок.Вес; // Это значение из справочника ЕдиницыИзмерения
// Рассчитаем массу, если заполнена плотность
МассаНетто = Количество * Плотность;
// Выводим данные в макет
ОбластьМакета.Параметры.Заполнить(ВыборкаСтрок); // Автозаполнение совпадающих имен
ОбластьМакета.Параметры.Масса = МассаНетто;
// Дополнительная проверка: считаем объем только для бетона (м3)
Если ВыборкаСтрок.КодОКЕИ = "113" Тогда
ОбластьМакета.Параметры.Объем = Количество; // Для бетона количество и есть объем в м3
Иначе
ОбластьМакета.Параметры.Объем = 0;
КонецЕсли;
// Выводим область в итоговый документ
ТабДокумент.Вывести(ОбластьМакета);
КонецЦикла;
Часто после внесения изменений в цикл печати возникает проблема: каждая строка товара начинает печататься на новой странице (сообщение 14). Это происходит из-за некорректной работы метода ПроверитьВывод(). Этот метод анализирует, поместится ли массив областей на текущий лист.
Если вы добавили в массив для проверки слишком большую область (например, весь Подвал или Шапку) вместе с текущей строкой, система будет думать, что места нет, и принудительно вставит разделитель страниц. Рассмотрим правильную настройку проверки вывода:
МассивВыводимыхОбластей.Очистить();
МассивВыводимыхОбластей.Добавить(ОбластьМакетаСтрока);
МассивВыводимыхОбластей.Добавить(ОбластьИтоговПоСтранице);
Если вы закомментируете блок проверки (как сделал автор в сообщении 19), форма может "развалиться" при печати больших документов. Лучше настроить логику проверки аккуратно.
При выводе веса и объема важно соблюдать точность. Используйте встроенную функцию Окр() или форматную строку в макете. Например, для объема часто требуется один знак после запятой:
ОбластьМакета.Параметры.Объем = Формат(Объем, "ЧЦ=15; ЧДЦ=1");
Также не забудьте про итоговую массу прописью в подвале документа. В 1С:УПП за это отвечает функция ЧислоПрописью(). Посмотрим, как корректно передать в неё единицы измерения веса:
// Пример формирования веса прописью
МассаПрописью = ЧислоПрописью(ИтогоМассаБрутто, "L=ru_RU", "килограмм, килограмма, килограммов, m, грамм, грамма, граммов, m, 3");
ОбластьПодвала.Параметры.МассаГрузаПрописью = МассаПрописью;
Проанализируем ситуацию из сообщения 15, где автор вставил запрос к регистру сведений ЗначенияСвойствОбъектов прямо в цикл. Это критическая ошибка! Вместо этого следует использовать механизм дополнительных реквизитов или свойств прямо в основном запросе печати, соединив таблицу товаров с регистром сведений через ЛЕВОЕ СОЕДИНЕНИЕ по полю Номенклатура или Характеристика.
Выясним причину, почему это важно: при формировании накладной на 50 позиций, внешнее соединение в запросе выполнится один раз и отработает за доли секунды. Запрос же в цикле создаст 50 отдельных транзакций к базе данных, что создаст ненужную нагрузку на сервер и замедлит работу пользователя.
Рассмотрим подробнее работу с характеристиками. Если плотность бетона зависит от его марки, которая указана в характеристике, в запросе нужно обращаться к РеализацияТоваровУслуг.Товары.ХарактеристикаНоменклатуры. Это позволит сделать отчет максимально гибким и автоматизированным.
Таким образом, системный подход к редактированию ТОРГ-12 заключается в переносе всей тяжелой логики в основной запрос и аккуратной обработке расчетных полей в цикле вывода строк с обязательным контролем разбиения на страницы.