Как вывести номера документов через запятую в заголовке сводного отчета 1С

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

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

Шаг 1. Получение номеров документов в запросе

Проанализируем типовую ошибку при попытке получить номер документа. Если запрос строится к табличной части (например, Документ.МенюРаскладка_Л.Накладная), поле номера не хранится напрямую в строках табличной части. Поле Номер относится к шапке документа, поэтому обращаться к нему следует через реквизит ссылки: МенюРаскладка_Л.Ссылка.Номер.

Однако объединять выборку номенклатуры и номеров в один запрос к табличной части не всегда оптимально: если в документе 100 строк, номер повторится 100 раз, создавая лишнюю нагрузку на передачу данных. Более того, если документ был проведен с пустой табличной частью, он вовсе не попадет в выборку. Рассмотрим два способа выборки номеров.

Способ А. Выборка номеров в общем запросе с последующей сверткой

Добавим обращение к номеру через реквизит Ссылка:


ВЫБРАТЬ
    МенюРаскладка_Л.Количество КАК КОЛИЧЕСТВО,
    МенюРаскладка_Л.Сумма КАК СУММА,
    МенюРаскладка_Л.Номенклатура КАК НОМЕНКЛАТУРА,
    МенюРаскладка_Л.Ссылка.Номер КАК НОМЕР
ИЗ
    Документ.МенюРаскладка_Л.Накладная КАК МенюРаскладка_Л
ГДЕ
    МенюРаскладка_Л.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
    И МенюРаскладка_Л.Ссылка.ПометкаУдаления = ЛОЖЬ
    И МенюРаскладка_Л.Ссылка.Организация = &Организация
    И МенюРаскладка_Л.Ссылка.Склад = &Склад

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

Более чистое решение — получить агрегированные данные по товарам и отдельный список номеров документов в одном пакетном запросе. Это исключит лишнее копирование таблиц в оперативной памяти:


// Пакетный запрос
ТекстЗапроса = 
"ВЫБРАТЬ
|    Меню.Номенклатура КАК Номенклатура,
|    СУММА(Меню.Количество) КАК Количество,
|    СУММА(Меню.Сумма) КАК Сумма
|ИЗ
|    Документ.МенюРаскладка_Л.Накладная КАК Меню
|ГДЕ
|    Меню.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
|    И Меню.Ссылка.ПометкаУдаления = ЛОЖЬ
|    И Меню.Ссылка.Организация = &Организация
|    И Меню.Ссылка.Склад = &Склад
|СГРУППИРОВАТЬ ПО
|    Меню.Номенклатура;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
|    Док.Номер КАК Номер,
|    Док.Ссылка КАК Ссылка
|ИЗ
|    Документ.МенюРаскладка_Л КАК Док
|ГДЕ
|    Док.Дата МЕЖДУ &НачалоПериода И &КонецПериода
|    И Док.ПометкаУдаления = ЛОЖЬ
|    И Док.Организация = &Организация
|    И Док.Склад = &Склад
|УПОРЯДОЧИТЬ ПО
|    Номер";

Запрос.Текст = ТекстЗапроса;
ПакетРезультатов = Запрос.ВыполнитьПакет();

ТабНоменклатура = ПакетРезультатов[0].Выгрузить();
ТабНомеров      = ПакетРезультатов[1].Выгрузить();

Шаг 2. Формирование строки с номерами через запятую

Выясним причину, почему встроенная функция СтрСоединить() может вызывать ошибку. Функция СтрСоединить() появилась только в платформе 8.3.6. Если отчет выполняется в конфигурации «1С:Бухгалтерия предприятия 2.0» или любой другой конфигурации с установленным режимом совместимости «Версия 8.2» (или ниже 8.3.6), эта функция будет недоступна. Разберем универсальные варианты реализации.

Вариант 1. Универсальный цикл обхода таблицы значений

Обратите внимание на синтаксис: при обращении по индексу ТабНомеров[х] возвращается объект типа СтрокаТаблицыЗначений, поэтому необходимо явно указывать обращение к колонке .НОМЕР:


// Если запрос был единым, предварительно свернем номера
ТабНомеров = РезультатЗапроса.Выгрузить();
ТабНомеров.Свернуть("НОМЕР");
ТабНомеров.Сортировать("НОМЕР");

СтрокаНомеров = "";
Для Индекс = 0 По ТабНомеров.Количество() - 1 Цикл
    НомерДокумента = СокрЛП(ТабНомеров[Индекс].НОМЕР);
    
    // Добавляем запятую перед каждым элементом, кроме первого
    СтрокаНомеров = СтрокаНомеров + ?(Индекс = 0, "", ", ") + НомерДокумента;
КонецЦикла;

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

Если в конфигурации используется БСП, можно выгрузить колонку номеров в массив и использовать встроенную процедуру общего модуля:


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

Вариант 3. Использование СтрСоединить (для конфигураций без режима совместимости 8.2)

Если режим совместимости отключен или равен 8.3.6 и выше:


МассивНомеров = ТабНомеров.ВыгрузитьКолонку("НОМЕР");
СтрокаНомеров = СтрСоединить(МассивНомеров, ", ");

Шаг 3. Подготовка номеров к печати

В номерах документов 1С содержатся служебные лидирующие нули и префиксы узлов информационной базы (например, 00БП-000124). Для красивого вывода в печатную форму имеет смысл удалять префиксы с помощью типовых функций БСП:


НомерНаПечать = ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(ТекСтрока.НОМЕР, Истина, Истина);

Шаг 4. Вывод строки параметров в макет

Разберем типичную ошибку: вызов Область.Параметры.СтрокаНомеров.Заполнить() неверен, поскольку у свойства параметра примитивного типа (строка) нет метода Заполнить(). Значение присваивается напрямую свойству параметра области:

  1. Откроем табличный документ макета (в окне конфигуратора).
  2. Выделим ячейку в области заголовка, в свойствах ячейки установим значение Заполнение: Параметр и укажем имя параметра, например, НомераДокументов.
  3. Для ячейки обязательно установим свойство Размещение текста в значение Переносить, а для строки макета включим свойство Автовысота строки, чтобы длинный список номеров не обрезался при печати.
  4. В коде формирования отчета заполняем параметр и выводим область:

Область = Макет.ПолучитьОбласть("Заголовок");
Область.Параметры.ТекстЗаголовка = "Требование-накладная";
Область.Параметры.НачалоПериода  = Формат(НачалоПериода, "ДФ=dd.MM.yyyy");
Область.Параметры.КонецПериода   = Формат(КонецПериода, "ДФ=dd.MM.yyyy");
Область.Параметры.НомераДокументов = "Составлен на основании документов: " + СтрокаНомеров;

ТабДокумент.Вывести(Область);

Такой подход гарантирует корректную работу печатной формы как на старых редакциях конфигураций (1С:Бухгалтерия 2.0), так и на современных версиях платформы без ошибок переполнения ячеек или несовместимости строковых функций.

← На главную