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

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

Как связать две таблицы в 1С

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

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

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

Ниже разобраны основные методы с примерами кода, типичные ошибки и способы проверить, что связь построена корректно и не теряет данные.

Что такое связь таблиц и когда она нужна

Связь таблиц — это правило, по которому строке одной таблицы ставится в соответствие одна или несколько строк другой. Классический пример: таблица «Товары» и таблица «Остатки» связаны по полю «Номенклатура». Зная товар, мы получаем его остаток; зная остаток — карточку товара.

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

Соединение таблиц в запросе: основной способ

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

Тип соединения определяет, что попадёт в результат. ВНУТРЕННЕЕ возвращает только строки, где ключ найден в обеих таблицах. ЛЕВОЕ — все строки первой таблицы плюс совпавшие данные второй (где совпадения нет — NULL). ПРАВОЕ и ПОЛНОЕ используются реже. Для выборки «товары и их остатки, включая товары без остатков» нужно именно ЛЕВОЕ соединение.

ВЫБРАТЬ

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

Товары.Артикул,

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

ИЗ

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

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

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

Обратите внимание на функцию ЕСТЬNULL: при левом соединении несовпавшие поля дают NULL, и без обработки в отчёте появятся пустые значения, а арифметика с NULL даст NULL.

Типы соединений

ВНУТРЕННЕЕ

Только совпавшие строки обеих таблиц. Подходит, когда нужны строго пары «товар — остаток». Строки без пары теряются.

ЛЕВОЕ

Все строки первой таблицы плюс совпадения из второй. Стандарт для справочник + регистр. Требует обработки NULL.

ПОЛНОЕ

Все строки обеих таблиц. Нужно редко, например при сверке двух наборов данных на расхождения.

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

Одного поля не всегда достаточно. Остатки могут различаться по складу, партии, характеристике — тогда условие соединения включает несколько полей через И. Чем точнее условие, тем меньше риск задвоения строк.

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

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

И Остатки.Склад = &Склад

Параметры вроде &Склад корректнее передавать в параметры виртуальной таблицы, а не в условие соединения: срез остатков по складу выполнится быстрее, и запрос останется читаемым. Условие соединения оставляйте для ключевых полей связи.

Если соединяются два документа, связанные реквизитом (например, «Реализация» и «Счёт-фактура» по полю «ДокументОснование»), убедитесь, что реквизит заполнен в обеих таблицах. Незаполненное основание даст NULL и строка выпадет из внутреннего соединения без какого-либо предупреждения.

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

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

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

ТаблицаОстатков.Индексы.Добавить("Номенклатура");

Отбор = Новый Структура("Номенклатура");

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

ЗаполнитьЗначенияСвойств(Отбор, СтрокаТовара);

Найденные = ТаблицаОстатков.НайтиСтроки(Отбор);

Для Каждого СтрокаОстатка Из Найденные Цикл

СтрокаТовара.Остаток = СтрокаОстатка.Количество;

КонецЦикла;

КонецЦикла;

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

Порядок связи таблиц значений
  1. 1
    Определите поле-ключ, общее для обеих таблиц
  2. 2
    Проиндексируйте вторую таблицу по ключу или постройте соответствие
  3. 3
    Пройдите циклом по первой таблице и подтяните данные из второй
  4. 4
    Обработайте случаи, когда пара не найдена (значение по умолчанию)
  5. 5
    Проверьте итоговое количество строк и контрольные суммы

Связь таблиц на форме и в динамических списках

На управляемой форме таблицы связываются декларативно, без кода. Типовой сценарий — список договоров, показывающий только договоры выбранного контрагента. Для этого у поля владельца настраивается «Связь параметров выбора», а для динамического списка — отбор по полю связи через свойства элемента формы.

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

Если связь на форме «не срабатывает», первым делом проверьте типы полей: ссылка на справочник не сравнится со строкой, содержащей наименование, даже если наименования совпадают. Связывать нужно ссылки со ссылками, а не представления.

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

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

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

Как проверить результат

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

Совпадает с числом строк левой таблицы (для левого соединения с уникальным ключом)

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

Строк стало больше — ключ не уникален, данные задвоились

Пустые значения в подтянутых полях
Норма

NULL обработаны через ЕСТЬNULL или значения по умолчанию

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

Пустые ячейки там, где ожидались нули или значения

Контрольная сумма по числовому полю
Норма

Сумма совпадает с суммой исходной таблицы

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

Сумма выросла кратно — строки продублированы

Типичные ошибки
01
Соединение по неуникальному ключу без группировки — строки и суммы задваиваются, отчёт врёт
02
Использование внутреннего соединения там, где нужно левое — теряются объекты без связанных данных
03
Связь по наименованию вместо ссылки — совпадения не находятся из-за пробелов и регистра, плюс медленная работа
04
Поиск НайтиСтроки без индекса в большом цикле — обработка зависает на больших объёмах
05
Игнорирование NULL после левого соединения — пустые значения и ошибки в последующих вычислениях

Когда какой способ выбрать

Маршрут решения

Как выбрать способ связи

Обе таблицы — объекты базы данных (справочники, регистры, документы)Используйте запрос с соединением — это быстрее и корректнее программного обхода
Данные уже в таблицах значений или пришли из файла/внешнего источникаСвязывайте в коде через индекс или соответствие
Нужно связать списки на форме для интерактивной работы пользователяНастройте связь параметров выбора или связь динамических списков в свойствах формы
Нужен отчёт с произвольной настройкой пользователемСтройте набор данных в СКД со связями на уровне схемы компоновки

Общее правило: чем ближе связь к базе данных, тем лучше. Соединение в запросе выполняет СУБД с оптимизацией, а программный обход всегда медленнее и требует больше кода. Программную связь оставляйте для случаев, когда запрос невозможен — внешние данные, разные информационные базы, сложная логика сопоставления.

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

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

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

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

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

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

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

Как связать таблицы из разных информационных баз?

Одним запросом напрямую — никак. Данные одной базы выгружают в таблицу значений (через COM, веб-сервис или файл), помещают во временную таблицу запроса и соединяют уже с таблицами текущей базы, либо связывают программно через соответствие.

Что быстрее: поиск по индексу таблицы значений или соответствие?

Соответствие обычно быстрее, особенно при большом числе обращений, потому что поиск по ключу в нём не зависит от размера коллекции. Индекс таблицы значений тоже даёт приемлемую скорость, но требует предварительного создания и уступает соответствию на очень больших объёмах.

Итог

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

Связь двух таблиц в 1С строится по общему ключу: в запросе — соединением, в коде — через индекс или соответствие, на форме — настройкой свойств. Контролируйте уникальность ключа, обрабатывайте NULL и сверяйте количество строк и контрольные суммы после соединения.