Разработка и Конфигурация · 10 мин
Как связать две таблицы в 1С
Способы связать две таблицы в 1С: соединения в запросе, объединение таблиц значений, связь по ключу. Примеры кода, ошибки и проверка результата.
Связать две таблицы в 1С чаще всего требуется в трёх ситуациях: при построении отчёта на СКД, при написании запроса с соединением таблиц базы данных и при программной обработке таблиц значений в коде. Во всех случаях основа одна — наличие общего поля (ключа), по которому строки одной таблицы сопоставляются строкам другой.
Выбор способа зависит от задачи. Если данные лежат в базе (справочники, документы, регистры) — правильно использовать запрос с соединением. Если данные уже выгружены в таблицы значений в памяти — применяют программное сопоставление через индексы или соответствие. Если речь о форме — настраивают связь параметров выбора или связь по типу.
Ниже разобраны основные методы с примерами кода, типичные ошибки и способы проверить, что связь построена корректно и не теряет данные.
Что такое связь таблиц и когда она нужна
Связь таблиц — это правило, по которому строке одной таблицы ставится в соответствие одна или несколько строк другой. Классический пример: таблица «Товары» и таблица «Остатки» связаны по полю «Номенклатура». Зная товар, мы получаем его остаток; зная остаток — карточку товара.
Практические задачи, где без связи не обойтись: отчёт по продажам с расшифровкой по контрагентам, подбор цен из регистра сведений к списку номенклатуры, объединение данных двух документов, динамический список с полями из связанных объектов. Во всех этих случаях ключ связи — ссылка на объект базы (справочник, документ) или комбинация полей.
Соединение таблиц в запросе: основной способ
Запрос с соединением — стандартный инструмент, когда обе таблицы находятся в базе данных. В конструкторе запроса на закладке «Связи» указываются две таблицы и условие связи. В тексте запроса это выглядит как предложение СОЕДИНЕНИЕ с условием ПО.
Тип соединения определяет, что попадёт в результат. ВНУТРЕННЕЕ возвращает только строки, где ключ найден в обеих таблицах. ЛЕВОЕ — все строки первой таблицы плюс совпавшие данные второй (где совпадения нет — NULL). ПРАВОЕ и ПОЛНОЕ используются реже. Для выборки «товары и их остатки, включая товары без остатков» нужно именно ЛЕВОЕ соединение.
ВЫБРАТЬ
Товары.Ссылка КАК Номенклатура,
Товары.Артикул,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
ИЗ
Справочник.Номенклатура КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Товары.Ссылка = Остатки.Номенклатура
Обратите внимание на функцию ЕСТЬNULL: при левом соединении несовпавшие поля дают NULL, и без обработки в отчёте появятся пустые значения, а арифметика с NULL даст NULL.
Типы соединений
Только совпавшие строки обеих таблиц. Подходит, когда нужны строго пары «товар — остаток». Строки без пары теряются.
Все строки первой таблицы плюс совпадения из второй. Стандарт для справочник + регистр. Требует обработки NULL.
Все строки обеих таблиц. Нужно редко, например при сверке двух наборов данных на расхождения.
Связь по нескольким полям и виртуальные таблицы
Одного поля не всегда достаточно. Остатки могут различаться по складу, партии, характеристике — тогда условие соединения включает несколько полей через И. Чем точнее условие, тем меньше риск задвоения строк.
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Товары.Ссылка = Остатки.Номенклатура
И Остатки.Склад = &Склад
Параметры вроде &Склад корректнее передавать в параметры виртуальной таблицы, а не в условие соединения: срез остатков по складу выполнится быстрее, и запрос останется читаемым. Условие соединения оставляйте для ключевых полей связи.
Если соединяются два документа, связанные реквизитом (например, «Реализация» и «Счёт-фактура» по полю «ДокументОснование»), убедитесь, что реквизит заполнен в обеих таблицах. Незаполненное основание даст NULL и строка выпадет из внутреннего соединения без какого-либо предупреждения.
Связь таблиц значений в коде
Когда данные уже получены в две таблицы значений (например, из разных запросов или из внешних источников), соединение выполняется программно. Базовый подход — цикл по первой таблице с поиском строк во второй.
Чтобы поиск не тормозил на больших объёмах, вторую таблицу нужно проиндексировать по полю связи. Метод НайтиСтроки без индекса перебирает таблицу целиком на каждой итерации, и на десятках тысяч строк обработка растягивается на минуты.
ТаблицаОстатков.Индексы.Добавить("Номенклатура");
Отбор = Новый Структура("Номенклатура");
Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл
ЗаполнитьЗначенияСвойств(Отбор, СтрокаТовара);
Найденные = ТаблицаОстатков.НайтиСтроки(Отбор);
Для Каждого СтрокаОстатка Из Найденные Цикл
СтрокаТовара.Остаток = СтрокаОстатка.Количество;
КонецЦикла;
КонецЦикла;
Альтернатива — построить соответствие: ключ — значение поля связи, значение — строка таблицы или массив строк. Поиск в соответствии работает быстрее поиска по индексу и не требует отдельного индексирования. Этот приём стандартен при загрузке данных из файлов, когда нужно сопоставить строки файла с элементами справочника.
- 1Определите поле-ключ, общее для обеих таблиц
- 2Проиндексируйте вторую таблицу по ключу или постройте соответствие
- 3Пройдите циклом по первой таблице и подтяните данные из второй
- 4Обработайте случаи, когда пара не найдена (значение по умолчанию)
- 5Проверьте итоговое количество строк и контрольные суммы
Связь таблиц на форме и в динамических списках
На управляемой форме таблицы связываются декларативно, без кода. Типовой сценарий — список договоров, показывающий только договоры выбранного контрагента. Для этого у поля владельца настраивается «Связь параметров выбора», а для динамического списка — отбор по полю связи через свойства элемента формы.
Для двух динамических списков на одной форме (например, «Заказы» и «Строки заказа») используется свойство основной таблицы и связь по ключу текущей строки: у второго списка в свойствах устанавливается связь с реквизитом первого. При смене активной строки в первом списке второй автоматически переотфильтруется.
Если связь на форме «не срабатывает», первым делом проверьте типы полей: ссылка на справочник не сравнится со строкой, содержащей наименование, даже если наименования совпадают. Связывать нужно ссылки со ссылками, а не представления.
Проверка результата и типичные ошибки
После построения связи результат нужно верифицировать, а не считать готовым. Минимальный контроль: сравнить количество строк до и после соединения и проверить контрольную сумму по числовому полю (например, сумма остатков до группировки и после).
Как проверить результат
Совпадает с числом строк левой таблицы (для левого соединения с уникальным ключом)
Строк стало больше — ключ не уникален, данные задвоились
NULL обработаны через ЕСТЬNULL или значения по умолчанию
Пустые ячейки там, где ожидались нули или значения
Сумма совпадает с суммой исходной таблицы
Сумма выросла кратно — строки продублированы
Когда какой способ выбрать
Как выбрать способ связи
Общее правило: чем ближе связь к базе данных, тем лучше. Соединение в запросе выполняет СУБД с оптимизацией, а программный обход всегда медленнее и требует больше кода. Программную связь оставляйте для случаев, когда запрос невозможен — внешние данные, разные информационные базы, сложная логика сопоставления.
Частые вопросы
Чем левое соединение отличается от внутреннего на практике?
Внутреннее вернёт только пары, где ключ есть в обеих таблицах: товары без остатков из результата исчезнут. Левое сохранит все товары, а в полях остатков даст NULL. Для справочника с подтягиванием данных из регистра почти всегда нужно левое соединение.
Почему после соединения суммы в отчёте удвоились?
Ключ связи не уникален в одной из таблиц: каждой строке левой таблицы соответствует несколько строк правой, и строки перемножаются. Решение — сгруппировать правую таблицу по ключу с суммированием перед соединением или добавить в условие связи недостающие поля.
Можно ли связать таблицы по наименованию, а не по ссылке?
Технически да, но это ненадёжно: наименования могут отличаться пробелами, регистром или дублироваться. Такая связь работает медленно и даёт ложные несовпадения. По наименованию связывают только при первичной загрузке данных из внешних файлов, где ссылок ещё нет, и с обязательной ручной проверкой неоднозначных совпадений.
Как связать таблицы из разных информационных баз?
Одним запросом напрямую — никак. Данные одной базы выгружают в таблицу значений (через COM, веб-сервис или файл), помещают во временную таблицу запроса и соединяют уже с таблицами текущей базы, либо связывают программно через соответствие.
Что быстрее: поиск по индексу таблицы значений или соответствие?
Соответствие обычно быстрее, особенно при большом числе обращений, потому что поиск по ключу в нём не зависит от размера коллекции. Индекс таблицы значений тоже даёт приемлемую скорость, но требует предварительного создания и уступает соответствию на очень больших объёмах.
Что важно запомнить
Связь двух таблиц в 1С строится по общему ключу: в запросе — соединением, в коде — через индекс или соответствие, на форме — настройкой свойств. Контролируйте уникальность ключа, обрабатывайте NULL и сверяйте количество строк и контрольные суммы после соединения.