Как правильно соединить две табличные части документа по номеру строки в запросе 1С и СКД?

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

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

Разберем детально, почему возникает эта проблема и как правильно построить запрос в СКД и языке запросов 1С для построчного объединения данных.

Причина возникновения дублей и перемножения строк

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

Если выполнить соединение двух табличных частей только по полю НомерСтроки, запрос начнет связывать строки с одинаковым номером всех документов, присутствующих в базе данных. Кроме того, если не указать связывающее условие по документу, система перемножит данные. Поэтому при соединении двух табличных частей одного документа критически важно связывать их одновременно по двум полям: Ссылка и НомерСтроки.

Решение с помощью соединения в языке запросов

Рассмотрим пример правильного запроса, объединяющего две табличные части документа АЛТ_ОперацияОтпускВозврат — НомераТруб и МеталлоломТаблица:


ВЫБРАТЬ
    НомераТрубТаблица.НомерСтроки КАК НомераТрубТаблицаНомерСтроки,
    НомераТрубТаблица.НомерТрубы КАК НомераТрубТаблицаНомерТрубы,
    МеталлоломТаблица.НомерСтроки КАК МеталлоломТаблицаНомерСтроки,
    МеталлоломТаблица.НомерТрубы КАК МеталлоломТаблицаНомерТрубы
ИЗ
    Документ.АЛТ_ОперацияОтпускВозврат.НомераТруб КАК НомераТрубТаблица
        СОЕДИНЕНИЕ Документ.АЛТ_ОперацияОтпускВозврат.МеталлоломТаблица КАК МеталлоломТаблица
        ПО НомераТрубТаблица.Ссылка = МеталлоломТаблица.Ссылка
            И НомераТрубТаблица.НомерСтроки = МеталлоломТаблица.НомерСтроки

В приведенном примере ключевое значение имеет секция ПО, где указано двойное условие соединения:

  1. НомераТрубТаблица.Ссылка = МеталлоломТаблица.Ссылка — ограничивает выборку рамками одного и того же документа;
  2. НомераТрубТаблица.НомерСтроки = МеталлоломТаблица.НомерСтроки — обеспечивает построчное сопоставление элементов с одинаковыми номерами.

Примечание: ключевое слово ВНУТРЕННЕЕ перед СОЕДИНЕНИЕ в языке запросов 1С является необязательным, так как внутреннее соединение применяется платформой по умолчанию.

Нюансы работы и альтернативные варианты

Проанализируем дополнительные ситуации, которые могут возникнуть при работе с такими запросами:

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