Как вывести номера и даты нескольких накладных в шапку печатной формы одной строкой в 1С

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

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

Анализ типовой ошибки при выводе в цикле

Посмотрим на исходный вариант, который приводит к выводу каждой записи на новой строке:


Область = Макет.ПолучитьОбласть("Строка");
Для Каждого ТекСтрока Из РасходныеНакладные Цикл
    Область.Параметры.Номер = ТекСтрока.РасходнаяНакладная.Номер;
    Область.Параметры.Дата = Формат(ТекСтрока.РасходнаяНакладная.Дата, "ДЛФ=Д");
    ТабДок.Вывести(Область);
КонецЦикла;

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

Способ 1. Конкатенация строк в цикле с тернарным оператором

Рассмотрим классический способ склейки строк. В макете печатной формы в ячейке шапки зададим один общий параметр, например НомерДата.

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

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


НомерДата = "";
Для Каждого ТекСтрока Из РасходныеНакладные Цикл
    // Добавляем запятую перед каждым элементом, кроме первого
    Разделитель = ?(НомерДата = "", "", ", ");
    
    НомерДок = СокрЛП(ТекСтрока.РасходнаяНакладная.Номер);
    ДатаДок  = Формат(ТекСтрока.РасходнаяНакладная.Дата, "ДЛФ=Д");
    
    НомерДата = НомерДата + Разделитель + НомерДок + " от " + ДатаДок;
КонецЦикла;

Область = Макет.ПолучитьОбласть("Шапка");
Область.Параметры.НомерДата = НомерДата;
ТабДок.Вывести(Область);

Способ 2. Использование массива и функции СтрСоединить (рекомендуемый)

Проанализируем более современный и производительный подход. Начиная с платформы 1С:Предприятие 8.3.6, доступна встроенная функция СтрСоединить(). Она избавляет от необходимости писать условия проверки на первый элемент и исключает лишние операции конкатенации строк в памяти.

Разберем реализацию через массив строк:


МассивНакладных = Новый Массив;

Для Каждого ТекСтрока Из РасходныеНакладные Цикл
    НомерДок = СокрЛП(ТекСтрока.РасходнаяНакладная.Номер);
    ДатаДок  = Формат(ТекСтрока.РасходнаяНакладная.Дата, "ДЛФ=Д");
    
    МассивНакладных.Добавить(НомерДок + " от " + ДатаДок);
КонецЦикла;

Область = Макет.ПолучитьОбласть("Шапка");
Область.Параметры.НомерДата = СтрСоединить(МассивНакладных, ", ");
ТабДок.Вывести(Область);

Если в конфигурации используется Библиотека стандартных подсистем (БСП), аналогичную операцию можно выполнить с помощью вызова функции СтроковыеФункцииКлиентСервер.СтрокаИзМассива(МассивНакладных, ", ").

Важные рекомендации по настройке макета и оптимизации

Чтобы сформированная строка отображалась корректно и без потери данных, выполним следующие шаги:

  1. Свойство «Размещение текста» в ячейке макета: Откроем свойства ячейки с параметром НомерДата и установим свойство «Размещение текста» в значение Переносить (ТипРазмещенияТекстаТабличногоДокумента.Переносить). Если оставить значение Авто или Обрезать, длинный список накладных не поместится и визуально обрежется границей столбца.
  2. Автовысота строки: Убедимся, что для строки макета включено свойство «Автовысота строки», чтобы при переносе текста на несколько строк высота ячейки увеличивалась автоматически.
  3. Устранение обращений «через точку» (проблема N+1): Обращение вида ТекСтрока.РасходнаяНакладная.Номер внутри цикла вызывает неявные запросы к базе данных для каждой строки. При большом объеме данных рекомендуется заранее получить номера и даты накладных одним запросом с ключевым словом ВЫБРАТЬ РАЗЛИЧНЫЕ. Это также позволит автоматически исключить возможные дубликаты документов.
  4. Удаление лидирующих нулей и префиксов: Для вывода номеров в соответствии со стандартами 1С можно применить функцию БСП ОбщегоНазначенияКлиентСервер.НомерНаПечать(Номер) или ПрефиксацияОбъектовКлиентСервер.ПолучитьНомерНаПечать(Номер, Истина, Истина).
← На главную