Как в запросе 1С получить все счета-фактуры одной строкой в привязке к счету?

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

Довольно часто при разработке выгрузок, отчетов или интеграций (например, в XML) возникает необходимость получить данные из 1С в специфичном формате. Проанализируем типичную ситуацию: нам нужно вывести список счетов на оплату, а рядом, в одной колонке или строке, получить все связанные с ними счета-фактуры через запятую. То есть вместо дублирования строк со счетом для каждой новой фактуры, мы хотим получить компактный вид: Счет 1 — СФВ 1, СФВ 2, СФВ 3.

Давайте разберем по шагам, почему эту задачу нельзя решить "в лоб" одним запросом и какие существуют правильные способы ее реализации в платформе 1С:Предприятие.

Анализ связей: частая ошибка при соединении таблиц

Рассмотрим логическую ошибку, которую часто допускают новички. При попытке связать документ СчетНаОплатуПокупателю и СчетФактураВыданный разработчики иногда используют левое соединение по полю ДоговорКонтрагента. Это в корне неверный подход.

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

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

  1. Счет на оплату покупателю
  2. Реализация товаров и услуг (или Акт выполненных работ)
  3. Счет-фактура выданный

Связь нужно искать через реквизит ДокументОснования, последовательно разворачивая цепочку, либо использовать механизм структуры подчиненности (критерий отбора СвязанныеДокументы).

Почему нельзя склеить строки внутри самого запроса 1С?

Многие разработчики, знакомые с классическим SQL, ищут аналоги функций STRING_AGG или GROUP_CONCAT. Однако встроенный язык запросов 1С не умеет выполнять конкатенацию строк (объединение значений в одну строку) при группировке. Запрос всегда будет возвращать каждую найденную счет-фактуру в новой строке.

Посмотрим на доступные варианты решения проблемы. В 1С для таких задач принято использовать два подхода: обработка результата запроса с итогами (через встроенный язык) либо использование Системы компоновки данных (СКД).

Решение 1: Программный обход выборки с итогами (для выгрузки в XML)

Если конечная цель — это формирование выгрузки (например, XML-файла), самым грамотным решением будет получение древовидной структуры данных с помощью предложения ИТОГИ ПО. Разберем этот алгоритм.

В тексте запроса мы указываем получение итогов по родительскому документу (Счету):


ВЫБРАТЬ
    ТаблицаСчетов.Счет КАК Счет,
    ТаблицаСчетов.СчетФактура КАК СчетФактура
ИЗ
    ТаблицаСчетов КАК ТаблицаСчетов
ИТОГИ ПО
    Счет

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


// Выполняем запрос с итогами
РезультатЗапроса = Запрос.Выполнить();

// Начинаем обход по верхнему уровню (по Счетам)
ВыборкаСчета = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаСчета.Следующий() Цикл
    СтрокаСФ = "";
    
    // Получаем вложенные записи (счета-фактуры, относящиеся к текущему счету)
    ВыборкаСФ = ВыборкаСчета.Выбрать();
    Пока ВыборкаСФ.Следующий() Цикл
        // Склеиваем номера счетов-фактур через запятую
        СтрокаСФ = СтрокаСФ + ?(ПустаяСтрока(СтрокаСФ), "", ", ") + Строка(ВыборкаСФ.СчетФактура);
    КонецЦикла;
    
    // Теперь переменная СтрокаСФ содержит "СФВ 1, СФВ 2, СФВ 3"
    // Здесь размещаем код для записи сформированной строки в файл XML
    // ЗаписьXML.ЗаписатьАтрибут("СчетаФактуры", СтрокаСФ);

КонецЦикла;

Этот подход идеален для задач интеграции, так как позволяет гибко управлять форматом итоговой строки.

Решение 2: Использование функции СоединитьСтроки в СКД (для отчетов)

Если же ваша задача — вывести данные в табличный документ или отчет для пользователя, нет смысла писать код с обходом выборок. Система компоновки данных (СКД) имеет мощную встроенную функцию для конкатенации.

Проанализируем, как это настроить в макете СКД:

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

При формировании отчета СКД автоматически соберет все вложенные детальные записи счетов-фактур, преобразует их в массив и объединит в единую красивую строку через запятую.

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

← На главную