Связи между данными в 1С: реквизиты, регистры и запросы
Содержание
Связь между объектами в 1С делается одним из трёх способов: ссылочным реквизитом (поле хранит ссылку на другой справочник или документ), подчинением справочника владельцу, либо измерением регистра. Для выборки связанных данных используют обращение через точку или соединение таблиц в запросе на встроенном языке запросов.
Разберём по порядку: где связь задаётся в конфигураторе, как к ней обращаться из запроса и из кода, и почему соединение иногда «теряет» или «задваивает» строки. Примеры даны для платформы 8.3, интерфейс «Такси».
Чем связываются объекты в конфигурации
В 1С почти любая связь сводится к тому, что одно поле хранит ссылку на другой объект. Ссылка — это уникальный идентификатор элемента справочника, документа или значения перечисления. Варианты, которыми пользуются на практике:
- 🔗 Ссылочный реквизит — поле справочника или документа с типом
СправочникСсылка.<Имя>илиДокументСсылка.<Имя>. Самый частый способ: реквизит «Контрагент» документа «РеализацияТоваровУслуг» ссылается на справочник «Контрагенты». - 📁 Подчинённый справочник — у элемента есть владелец. Договоры подчинены контрагентам, виды контактной информации — своим объектам.
- 📊 Измерение регистра — регистр накопления или сведений хранит движения в разрезе объектов: номенклатуры, склада, организации.
- 📄 Табличная часть — строки внутри документа, каждая со своими ссылочными реквизитами (номенклатура, количество, цена).
- 🧩 Составной тип — одно поле может ссылаться на объекты разных типов сразу (например, «Основание» ссылается и на заказ, и на счёт).
Тип реквизита выбирается один раз при проектировании метаданных и меняется только через конфигуратор или расширение. Пользователь связь не «создаёт» — он выбирает готовое значение в уже настроенном поле.
Чтобы понять, как объекты связаны в конкретной базе, откройте конфигуратор и посмотрите состав реквизитов объекта: Конфигурация → Общие → Справочники/Документы → ваш объект → Реквизиты. Тип каждого реквизита и показывает, с чем он связан.
Связь документа или справочника через ссылочный реквизит
Это основной механизм. Чтобы документ «знал» своего контрагента, в метаданных у него должен быть реквизит ссылочного типа.
Как это настраивается в конфигураторе:
- Откройте объект (например, документ) в дереве конфигурации.
- На ветке
Реквизитыдобавьте новый реквизит, задайте имя — скажем,Контрагент. - В свойстве
ТипвыберитеСправочникСсылка.Контрагенты. - Обновите конфигурацию базы данных (
Конфигурация → Обновить конфигурацию базы данных, клавиша F7).
После этого в форме документа появляется поле выбора : пользователь подбирает контрагента, а база хранит ссылку на него. Никакого «ID вручную» — платформа сама связывает запись с элементом справочника.
Для реквизита можно разрешить несколько типов. Тогда в свойстве Тип ставят флажок «Составной тип данных» и отмечают нужные объекты. Так делают, например, для поля «Договор», которое в разных сценариях ссылается на разные справочники.
Составной тип удобен в интерфейсе, но усложняет запросы: к полю составного типа нельзя обратиться через точку напрямую — сначала его приводят к конкретному типу оператором ВЫРАЗИТЬ (об этом ниже).
Подчинённые справочники и связь «владелец → элемент»
Когда один объект логически принадлежит другому, используют подчинение. Классика — договоры принадлежат контрагенту: у одного контрагента несколько договоров, но каждый договор относится ровно к одному контрагенту.
Настройка в конфигураторе:
- Откройте подчинённый справочник (например,
ДоговорыКонтрагентов). - На закладке
Владельцыдобавьте справочник-владелец —Контрагенты. - В свойстве
Использование подчиненияоставьте вариант, при котором владельцем выступает элемент справочника.
После этого у каждого элемента подчинённого справочника автоматически появляется поле Владелец. В списке договоров платформа сама отфильтрует записи по выбранному контрагенту. В запросе владелец доступен как обычный реквизит:
ВЫБРАТЬ
Договоры.Ссылка,
Договоры.Наименование,
Договоры.Владелец КАК Контрагент
ИЗ
Справочник.ДоговорыКонтрагентов КАК Договоры
ГДЕ
Договоры.Владелец = &Контрагент
Подчинение отличается от обычного ссылочного реквизита тем, что связь встроена в структуру справочника и платформа поддерживает её автоматически: нельзя создать элемент подчинённого справочника без владельца.
Связь через регистры накопления
Регистр накопления хранит движения — приход и расход ресурсов в разрезе аналитик. Связь с объектами задаётся через измерения.
Типичный регистр «ТоварыНаСкладах»:
| Элемент регистра | Что хранит | Пример |
|---|---|---|
| Измерение | Разрез аналитики (ссылка на объект) | Номенклатура, Склад |
| Ресурс | Числовой итог | Количество, Сумма |
| Реквизит | Доп. информация без итогов | Партия, Назначение |
| Регистратор | Документ, сделавший движение | Поступление, Реализация |
Измерение «Номенклатура» имеет тип СправочникСсылка.Номенклатура — это и есть связь регистра со справочником. Поле Регистратор имеет составной тип из всех документов, которые пишут в регистр: так движение связано с документом-основанием.
Измерения, по которым вы часто фильтруете и соединяете, имеет смысл индексировать: в свойствах измерения выберите Индексировать → Индексировать. Это ускоряет выборку остатков по конкретному складу или товару.
Записи регистра читают не из основной таблицы движений, а из виртуальных таблиц — так получают готовые остатки и обороты, не суммируя строки вручную.
Соединение таблиц в запросе: виды СОЕДИНЕНИЙ
Когда данные лежат в разных таблицах, их сводят соединением в языке запросов. Синтаксис — СОЕДИНЕНИЕ с условием ПО. Видов четыре:
- ВНУТРЕННЕЕ СОЕДИНЕНИЕ — в результат попадают только строки, у которых есть пара в обеих таблицах.
- ЛЕВОЕ СОЕДИНЕНИЕ — все строки левой таблицы; для непарных строк поля правой будут
NULL. - ПРАВОЕ СОЕДИНЕНИЕ — зеркально левому: все строки правой таблицы.
- ПОЛНОЕ СОЕДИНЕНИЕ — все строки обеих таблиц, непарные дополняются
NULL.
На практике чаще всего нужно ЛЕВОЕ: взять все документы и подтянуть к ним справочные данные, даже если где-то их нет.
ВЫБРАТЬ
Реализация.Ссылка,
Реализация.Контрагент,
Договоры.Наименование КАК Договор
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ДоговорыКонтрагентов КАК Договоры
ПО Реализация.Договор = Договоры.Ссылка
Здесь документы — левая таблица, их берём все; договор подтягиваем, если он заполнен. Условие связи пишут в ПО: равенство ссылок, иногда с дополнительными условиями.
Если в ПО сравнивать поля разных ссылочных типов (например, договор с номенклатурой), запрос вернёт пустое пересечение, а не ошибку. Следите, чтобы типы полей в условии совпадали.
Соединять можно сколько угодно таблиц подряд, выстраивая цепочку. Но каждое лишнее соединение — это нагрузка, поэтому там, где платформа умеет подтянуть данные сама, обходятся без явного СОЕДИНЕНИЯ.
На практике в одном запросе часто связывают документ, его табличную часть, справочник и регистр. Например, собрать строки реализаций с текущим остатком по каждой позиции:
ВЫБРАТЬ
Товары.Номенклатура,
Товары.Количество КАК Продано,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки() КАК Остатки
ПО Товары.Номенклатура = Остатки.Номенклатура
Здесь Документ.РеализацияТоваровУслуг.Товары — это обращение к табличной части как к отдельной таблице; каждая её строка уже связана с шапкой через служебное поле Ссылка.
Обращение к связанным данным через точку
Самый короткий способ достать поле связанного объекта — разыменование через точку. Если реквизит хранит ссылку, можно сразу обратиться к реквизитам этой ссылки:
ВЫБРАТЬ
Реализация.Ссылка,
Реализация.Контрагент.ИНН КАК ИНН,
Реализация.Контрагент.ОсновнойМенеджер КАК Менеджер
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
Платформа сама добавит нужные левые соединения со справочником «Контрагенты». Это удобно и читаемо: не нужно вручную писать СОЕДИНЕНИЕ.
Ограничения, о которых важно помнить:
- Через точку нельзя разыменовать поле составного типа — сначала приведите его к конкретному типу:
ВЫБРАТЬ
ВЫРАЗИТЬ(Задача.Основание КАК Документ.ЗаказПокупателя).Дата КАК ДатаЗаказа
ИЗ
Документ.Задача КАК Задача
- Разыменование через точку — это скрытое левое соединение. Если значение не заполнено, вернётся
NULL, а не пустая ссылка. - Длинные цепочки точек (
Товар.Номенклатура.Производитель.Страна) работают, но каждая точка — отдельное соединение под капотом. На больших выборках это заметно по скорости.
Отдельный случай — обращение из строк табличной части к данным шапки документа. Когда выбираете таблицу вида Документ.Реализация.Товары, в каждой строке доступно поле Ссылка — это ссылка на сам документ. Через неё разыменовывают реквизиты шапки: Товары.Ссылка.Контрагент, Товары.Ссылка.Дата. Так в одной выборке соединяются данные двух уровней — строк и документа — без явного СОЕДИНЕНИЯ.
Виртуальные таблицы регистров
Чтобы связать документ с его итогами, напрямую суммировать движения не нужно — платформа предоставляет виртуальные таблицы. Это готовые наборы данных, рассчитанные из регистра.
Для регистра накопления:
| Виртуальная таблица | Что отдаёт |
|---|---|
Остатки | Остаток ресурсов на момент времени |
Обороты | Приход и расход за период |
ОстаткиИОбороты | Остаток на начало/конец и обороты сразу |
Для регистра сведений — СрезПоследних (последнее значение на дату) и СрезПервых.
Обращение к виртуальной таблице выглядит так:
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.Склад,
Остатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(
&НаДату,
Склад = &Склад) КАК Остатки
В круглых скобках — параметры: период и условие отбора. Отбор лучше задавать прямо в параметрах виртуальной таблицы, а не в секции ГДЕ после выборки. Тогда платформа рассчитает итоги только по нужному срезу, а не поднимет весь регистр и отфильтрует потом.
Виртуальная таблица уже «связана» с измерениями регистра. Поле Остатки.Номенклатура — это ссылка на справочник, и к ней применимо разыменование через точку: Остатки.Номенклатура.Артикул.
Виртуальные таблицы разных регистров соединяют между собой так же, как обычные. Частый приём — к остаткам товара подтянуть актуальную цену из регистра сведений через СрезПоследних:
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.КоличествоОстаток,
Цены.Цена
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&НаДату,) КАК Остатки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&НаДату,) КАК Цены
ПО Остатки.Номенклатура = Цены.Номенклатура
Параметр периода в обеих таблицах один и тот же — тогда остаток и цена берутся на одну дату, а связь по номенклатуре сводит их в одну строку.
Частые ошибки при соединениях и как их найти
Большинство проблем со связями в запросах сводится к нескольким типовым ситуациям. Диагностика:
ГДЕ, а не в ПО. ГДЕ отрабатывает после соединения и отсекает строки с NULL. Перенесите условие на правую таблицу в ПО — тогда левые строки сохранятся.СГРУППИРОВАТЬ ПО.NULL, а NULL в арифметике «заражает» итог. Оберните поле в ЕСТЬNULL(Поле, 0) до суммирования.ВЫРАЗИТЬ(Поле КАК Документ.Имя) и затем точку.ГДЕ, а не в параметрах виртуальной таблицы, либо измерение не проиндексировано. Перенесите условие в скобки виртуальной таблицы и включите индексирование измерения.Для разбора самого запроса удобна консоль запросов (внешняя обработка): в ней видно текст, параметры и результат. А чтобы понять, какие соединения платформа строит за разыменованием через точку, смотрите план запроса через технологический журнал или замер производительности в режиме отладки.
Прежде чем проверять тяжёлый запрос на рабочей базе в разгар дня, помните: длительная выборка создаёт нагрузку на сервер и может замедлить работу пользователей. Тестируйте на копии или в нерабочее время.
Чем разыменование через точку отличается от явного соединения?
СОЕДИНЕНИЕ даёт больше контроля: можно задать тип соединения, дополнительные условия и избежать лишних обращений в длинных цепочках.Как связать документ с его движениями по регистру?
Регистратор виртуальной или основной таблицы регистра — оно ссылается на документ. В запросе соединяют документ с таблицей движений по условию Движения.Регистратор = Документ.Ссылка.Можно ли сделать связь «многие ко многим»?
Почему после соединения справочника с документом строк стало больше?
ПО на уникальность или сверните результат группировкой.Как обратиться к владельцу подчинённого справочника в запросе?
Владелец — это обычный ссылочный реквизит. К нему применимо и разыменование через точку: Договоры.Владелец.ИНН.