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

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

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

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

Задача найти все документы, связанные с конкретным документом 1С, возникает постоянно: нужно показать цепочку «заказ → реализация → счёт-фактура», проверить, проведена ли оплата по поступлению, или собрать структуру подчинённости программно, без действий пользователя. В интерфейсе эту задачу решает команда «Связанные документы», но в запросе и коде приходится выбирать один из нескольких механизмов.

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

Как устроены связи между документами в 1С

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

Первый вариант — реквизит-основание: у документа есть реквизит типа «ДокументСсылка», например «ЗаказКлиента» в реализации или «ДокументОснование» в счёте-фактуре. Это самый частый и самый удобный для запроса случай.

Второй вариант — табличная часть с ссылками: один документ хранит список оснований в табличной части (например, несколько заказов в одной реализации). Третий — критерий отбора «Связанные документы», который конфигуратор строит автоматически по составу реквизитов. Четвёртый — отдельный регистр сведений, где связи хранятся явно, что встречается в самописных и доработанных конфигурациях.

Когда запрос не нужен: критерий отбора в коде

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

СвязанныеДокументы = КритерииОтбора.СвязанныеДокументы.Найти(ДокументСсылка);

Для Каждого СтрокаСвязи Из СвязанныеДокументы Цикл

Сообщить(СтрокаСвязи.Ссылка);

КонецЦикла;

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

Обратите внимание: если в конфигурации критерий называется иначе или его нет вовсе, метод не сработает. Проверьте наличие объекта в дереве конфигурации в ветке «Общие → Критерии отбора».

Получение подчинённых документов запросом по реквизиту-основанию

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

ВЫБРАТЬ

Реализация.Ссылка КАК Реализация,

Реализация.Дата КАК Дата,

Реализация.Проведен КАК Проведен

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ГДЕ

Реализация.ЗаказКлиента = &Заказ

И НЕ Реализация.ПометкаУдаления

Если подчинённых документов нескольких типов, объединяйте выборки через ОБЪЕДИНИТЬ ВСЕ. Чтобы получить цепочку в обе стороны (основание и подчинённые), выполните два запроса: один ищет, на что ссылается документ, второй — кто ссылается на него.

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

Связь через табличную часть

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

ВЫБРАТЬ РАЗЛИЧНЫЕ

ТабЧасть.Ссылка КАК Реализация

ИЗ

Документ.РеализацияТоваровУслуг.Заказы КАК ТабЧасть

ГДЕ

ТабЧасть.ЗаказКлиента = &Заказ

Обязательно используйте РАЗЛИЧНЫЕ или группировку: один документ может содержать несколько строк с одной и той же ссылкой, и без устранения дублей результат раздуется.

Порядок действий для запроса по основанию
  1. 1
    Откройте конфигуратор и найдите реквизит документа, который хранит ссылку на основание (или табличную часть с такими ссылками)
  2. 2
    Проверьте, включено ли индексирование этого реквизита — при больших объёмах это критично для скорости
  3. 3
    Напишите запрос с условием по реквизиту и отбором по пометке удаления
  4. 4
    Выполните запрос в консоли запросов на тестовом документе и сверьте результат с кнопкой «Связанные документы» в интерфейсе

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

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

ВЫБРАТЬ

Заказ.Ссылка КАК Заказ,

Реализация.Ссылка КАК Реализация,

СчетФактура.Ссылка КАК СчетФактура

ИЗ

Документ.ЗаказКлиента КАК Заказ

ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Реализация

ПО Реализация.ЗаказКлиента = Заказ.Ссылка

И НЕ Реализация.ПометкаУдаления

ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетФактураВыданный КАК СчетФактура

ПО СчетФактура.ДокументОснование = Реализация.Ссылка

И НЕ СчетФактура.ПометкаУдаления

Здесь важны два момента. Во-первых, условия по пометке удаления и проведению подчинённого документа размещайте в секции ПО соединения, а не в ГДЕ — иначе левое соединение фактически превратится во внутреннее и заказы без реализаций выпадут из выборки.

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

Типичные ошибки
01
Условие по подчинённому документу в ГДЕ вместо ПО — левое соединение превращается во внутреннее, документы без связей пропадают
02
Отсутствие отбора по пометке удаления — в результат попадают удалённые документы и суммы искажаются
03
Соединение без предварительной свёртки при связи «один ко многим» — суммы и количества задваиваются
04
Попытка использовать критерий отбора как таблицу запроса — он недоступен в языке запросов, только через код

Проверка результата и контроль полноты связей

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

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

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

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

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

Состав ссылок в запросе и в структуре подчинённости
Норма

Наборы документов совпадают

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

В интерфейсе есть документы, которых нет в выборке — не учтена табличная часть или другой реквизит

Количество строк по одному основанию
Норма

Число строк соответствует реальному числу подчинённых документов

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

Строки дублируются — связь через табличную часть без РАЗЛИЧНЫЕ или размножение при соединении

Суммы по связанным документам
Норма

Итоги совпадают с данными документов

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

Суммы завышены кратно — задвоение при соединении один-ко-многим

Производительность и ограничения

Запросы по связям документов чувствительны к объёму данных. Основное правило: реквизит, по которому идёт поиск, должен быть проиндексирован. В типовых конфигурациях реквизиты-основания обычно проиндексированы, но в доработанных — проверьте свойство «Индексировать» в конфигураторе.

Избегайте соединений по табличным частям без отбора по ссылке-основанию и не используйте соединения с виртуальными таблицами регистров без необходимости. Если запрос входит в отчёт на СКД, выносите получение связанных документов во временную таблицу пакетного запроса — это заметно снижает нагрузку.

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

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

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

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

Почему запрос не находит документ, который виден в структуре подчинённости?

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

Как получить и основание, и подчинённые документы одним запросом?

Одним запросом — через ОБЪЕДИНИТЬ ВСЕ двух выборок: первая берёт документы, на которые ссылается текущий (по его реквизитам-ссылкам), вторая — документы, которые ссылаются на него. Добавьте поле-признак направления связи, чтобы различать строки результата.

Как связать документы, если прямой ссылки-основания нет?

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

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

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

Как получить связанные документы в запросе динамического списка?

Динамический список работает с одной основной таблицей, поэтому связанные документы обычно выводят либо отдельным динамическим списком с отбором по текущей строке через реквизит-основание, либо программным обращением к критерию отбора при активизации строки. Встраивать сложные соединения в основную таблицу динамического списка не рекомендуется из-за падения производительности.

Итог

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

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