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