К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как связать две таблицы в 1С: пошаговая инструкция

Способы связать две таблицы в 1С: левое, внутреннее и полное соединение в запросе, связи в СКД, типичные ошибки и проверка результата на дубли.

Связь двух таблиц — базовая операция при работе с данными 1С: она нужна в запросах, отчётах на СКД, динамических списках и при выгрузке данных. Чаще всего речь идёт о соединении таблиц в запросе на встроенном языке запросов 1С: например, справочника «Номенклатура» с таблицей остатков регистра накопления, чтобы к каждому товару подтянуть его складские остатки.

Механизм похож на JOIN в SQL, но имеет свои особенности: свои типы соединений, правила работы с NULL, виртуальные таблицы регистров и ограничения при соединении таблиц с разными типами полей связи. Неправильно выбранный тип соединения или условие связи приводит к потере строк, задвоению данных и неверным итогам в отчётах.

Ниже разобраны все практические сценарии: соединения в консоли запросов и в коде, связь наборов данных в СКД, работа с временными таблицами, типичные ошибки и способы проверить результат.

Какие способы связи таблиц существуют в 1С

В зависимости от задачи связать две таблицы можно несколькими способами. Первый — соединение в тексте запроса: подходит для отчётов, выборок в коде, обработок и динамических списков. Это самый универсальный и самый частый вариант.

Второй способ — связь наборов данных в схеме компоновки данных (СКД). Он используется, когда отчёт строится на нескольких запросах-наборах, которые нельзя или неудобно объединить в один запрос. Третий вариант — объединение через временные таблицы и пакетные запросы, когда данные сначала помещаются во временную таблицу, а затем соединяются с основной выборкой.

Отдельно стоит задача связать две таблицы значений в коде без запроса — например, данные, полученные из внешних источников. Здесь прямого аналога JOIN нет, и связь выполняется программно через соответствие или поиск по индексированной колонке.

Сравнение способов связи

Соединение в запросе

Универсальный вариант для отчётов и выборок. Требует понимания типов соединений и условий связи.

Связи наборов данных в СКД

Подходит для отчётов из нескольких запросов. Настраивается мышкой, но работает медленнее одиночного запроса на больших объёмах.

Временные таблицы

Нужны при сложной предварительной фильтрации. Дают лучшую производительность, но усложняют структуру пакетного запроса.

Связь таблиц значений в коде

Для данных вне СУБД: файлы, обмен, внешние компоненты. Медленнее запроса, требует программной обработки.

Типы соединений в запросе 1С

Язык запросов 1С поддерживает четыре вида соединения. ЛЕВОЕ СОЕДИНЕНИЕ возвращает все строки левой таблицы и подставляет данные правой там, где нашлось совпадение; если совпадения нет, поля правой таблицы будут NULL. Это самый частый тип: например, вывести весь справочник товаров и подтянуть остатки тем, у которых они есть.

ВНУТРЕННЕЕ СОЕДИНЕНИЕ возвращает только строки, где совпадение есть в обеих таблицах. Подходит, когда нужны только объекты с данными: например, товары, по которым были движения. ПРАВОЕ соединение зеркально левому — на практике его почти всегда заменяют левым, меняя таблицы местами. ПОЛНОЕ СОЕДИНЕНИЕ возвращает строки обеих таблиц независимо от совпадений; используется редко, например при сверке двух источников.

Важный нюанс: если в правой таблице на одну строку левой приходится несколько совпадений, строка левой таблицы продублируется. Это главная причина «раздутых» итогов в отчётах, о чём подробнее ниже.

Пошаговая связь двух таблиц в консоли запросов

Разберём практический пример: нужно вывести список номенклатуры с остатками из регистра накопления «ТоварыНаСкладах». Откройте консоль запросов (в типовых конфигурациях — через «Функции для технического специалиста» или внешнюю обработку консоли) и выполните шаги ниже.

Порядок действий
  1. 1
    Выберите основную таблицу: ВЫБРАТЬ Товары.Ссылка, Товары.Наименование ИЗ Справочник.Номенклатура КАК Товары.
  2. 2
    Добавьте соединение: ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки ПО Товары.Ссылка = Остатки.Номенклатура.
  3. 3
    Добавьте поля правой таблицы в выборку: Остатки.КоличествоОстаток.
  4. 4
    При необходимости замените NULL нулём: ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток.
  5. 5
    Выполните запрос и проверьте: количество строк должно совпадать с количеством элементов справочника, а товары без остатков — показывать 0.

Итоговый текст запроса выглядит так:

ВЫБРАТЬ

Товары.Ссылка КАК Номенклатура,

Товары.Наименование КАК Наименование,

ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

ИЗ

Справочник.Номенклатура КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Товары.Ссылка = Остатки.Номенклатура

Псевдонимы (КАК Товары, КАК Остатки) обязательны при соединении: без них обращаться к полям конкретной таблицы неудобно, а при совпадающих именах полей запрос вернёт ошибку неоднозначности.

Связь по нескольким полям и составные условия

Часто одного поля связи недостаточно. Например, остатки нужны не просто по номенклатуре, а по номенклатуре в разрезе конкретного склада, или цены — по номенклатуре и типу цен. В этом случае условия перечисляются через логическое И:

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены

ПО Товары.Ссылка = Цены.Номенклатура

И Цены.ТипЦен = &ТипЦен

Обратите внимание: условие по полю правой таблицы (например, Цены.ТипЦен = &ТипЦен) нужно писать именно в секции ПО, а не в ГДЕ. Если перенести его в ГДЕ, левое соединение фактически превратится во внутреннее — строки без цен отфильтруются, потому что у них поле типа цен равно NULL и условие не выполнится.

Связь таблиц в отчёте на СКД

Когда отчёт строится на системе компоновки данных и данные приходят из двух разных запросов-наборов, соединять их в одном запросе не обязательно. На закладке «Связи наборов данных» добавьте связь: укажите набор-источник, набор-приёмник, выражение-источник и выражение-приёмник (поля связи).

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

Учтите ограничение: связи наборов выполняются на уровне платформы после выполнения запросов, поэтому на больших объёмах данных один запрос с соединением обычно работает быстрее. Связи наборов оправданы, когда источники принципиально разные — например, запрос к базе и набор-объект с данными из таблицы значений.

Временные таблицы и пакетные запросы

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

ВЫБРАТЬ

Продажи.Номенклатура КАК Номенклатура,

СУММА(Продажи.Количество) КАК Продано

ПОМЕСТИТЬ ВТ_Продажи

ИЗ

РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Продажи

СГРУППИРОВАТЬ ПО

Продажи.Номенклатура

;

ВЫБРАТЬ

Товары.Ссылка,

ЕСТЬNULL(ВТ.Продано, 0) КАК Продано

ИЗ

Справочник.Номенклатура КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Продажи КАК ВТ

ПО Товары.Ссылка = ВТ.Номенклатура

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

Как связать две таблицы значений в коде без запроса

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

Индекс = Новый Соответствие;

Для Каждого Строка Из ТаблицаЦен Цикл

Индекс.Вставить(Строка.КодТовара, Строка.Цена);

КонецЦикла;

Для Каждого Строка Из ТаблицаТоваров Цикл

Цена = Индекс[Строка.Код];

Если Цена <> Неопределено Тогда

Строка.Цена = Цена;

КонецЕсли;

КонецЦикла;

Такой подход работает за линейное время, тогда как вложенный поиск методом Найти() по каждой строке на больших таблицах заметно медленнее. Если таблицы большие и данные можно получить запросом — предпочтительнее поместить их во временные таблицы через МенеджерВременныхТаблиц и выполнить соединение на уровне СУБД.

Типичные ошибки и проверка результата

Типичные ошибки
01
Соединение с непредварительно сгруппированной таблицей: одна строка левой таблицы дублируется по числу совпадений справа, итоги завышаются. Решение — сгруппировать правую таблицу во временную таблицу.
02
Условие по правой таблице в секции ГДЕ вместо ПО: левое соединение превращается во внутреннее, строки без пары теряются.
03
Связь по полям разных типов (например, строка и ссылка): соединение не находит совпадений, все поля правой таблицы равны NULL.
04
Забытый ЕСТЬNULL: в отчёте вместо нулей выводятся пустые значения, а сравнения и арифметика с NULL дают неожиданные результаты.
05
Соединение с полной таблицей регистра вместо виртуальной (Остатки, СрезПоследних): резкое падение производительности и лишние строки.

После написания запроса обязательно проверьте результат до использования в отчёте или обработке.

Контрольные точки

Как проверить результат соединения

Количество строк результата
Норма

При левом соединении с уникальным ключом справа — равно числу строк левой таблицы

Тревожный признак

Строк больше, чем в левой таблице: есть дубли из-за множественных совпадений

Поля правой таблицы
Норма

Заполнены там, где пара есть; NULL заменён через ЕСТЬNULL

Тревожный признак

NULL попадает в вычисления и итоги

Итоги по суммовым полям
Норма

Совпадают с контрольной суммой из исходного регистра

Тревожный признак

Итог завышен кратно — признак задвоения строк

Строки без пары
Норма

Объекты без данных присутствуют с нулевыми значениями (для левого соединения)

Тревожный признак

Часть справочника пропала — условие попало в ГДЕ или выбран внутренний тип соединения

Простой приём контроля: выполните запрос к левой таблице без соединения, запомните количество строк, затем выполните полный запрос. Совпадение числа строк — хороший признак; рост — сигнал искать дубли в правой таблице.

Итог

Что важно запомнить

Стандартный способ связать две таблицы в 1С — левое соединение в запросе по ключевому полю с заменой NULL через ЕСТЬNULL. Условия по правой таблице пишите в секции ПО, а правую таблицу до соединения группируйте, чтобы избежать дублей. В отчётах СКД из нескольких запросов используйте закладку «Связи наборов данных», а таблицы значений в коде связывайте через соответствие.

Частые вопросы

Чем левое соединение отличается от внутреннего на практике?

Левое соединение сохраняет все строки первой таблицы, даже если пары во второй нет — поля второй будут NULL. Внутреннее оставляет только строки с совпадением в обеих таблицах. Если нужен полный список объектов с подтянутыми данными — используйте левое; если только объекты с данными — внутреннее.

Почему после соединения в отчёте задвоились суммы?

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

Можно ли связать таблицы по неравенству или нескольким условиям ИЛИ?

Да, в секции ПО допустимы любые логические выражения, включая сравнения и ИЛИ. Однако соединения по неравенству обычно выполняются медленно и часто порождают дубли строк — используйте их только при реальной необходимости и проверяйте количество строк результата.

Как связать таблицы, если поля связи имеют разные типы?

Приведите типы в самом запросе: например, через ВЫРАЗИТЬ(Поле КАК Справочник.Номенклатура) для составного поля или через ПОДСТРОКУ/преобразования для строк. Соединение несовместимых типов (ссылка и строка) не даст совпадений, даже если значения визуально совпадают.

Что выбрать: соединение в запросе или связь наборов данных в СКД?

Если оба источника — таблицы базы данных, предпочтительнее один запрос с соединением: он выполняется на СУБД и работает быстрее. Связи наборов оправданы, когда один из источников — объект (таблица значений, внешние данные) или когда запросы слишком сложные для объединения.

Как соединить больше двух таблиц в одном запросе?

Последовательно добавляйте соединения: основная таблица, затем ЛЕВОЕ СОЕДИНЕНИЕ второй, затем третьей и так далее — каждое со своим условием ПО. Ограничений по числу соединений для разумного количества таблиц нет, но каждое соединение с неуникальным ключом перемножает строки, поэтому порядок и предварительная группировка критичны.