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