Работа с связанными документами в 1С:Предприятие 8.3 — одна из самых востребованных задач при разработке отчётов, обработок и интеграционных решений. Часто требуется не просто выгрузить список документов, а получить их «окружение»: связанные заказы, счёта, платежи или корректировки. Без правильно составленного запроса такая выборка может занять часы ручной обработки или привести к ошибкам в данных.

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

Все примеры приведены для актуальных версий платформы (8.3.20+), но большинство подходов работают и в более ранних релизах. Если вы используете Управление торговлей 11, ERP 2 или Бухгалтерию 3.0, приведённые ниже техники адаптируются под специфику вашей конфигурации.

📊 С какой конфигурацией 1С вы чаще работаете?
Управление торговлей
Бухгалтерия
ERP
Зарплата и кадры
Самописная
Другая

1. Базовые принципы связей между документами в 1С

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

  • 🔗 Реквизиты типа «Ссылка» — например, поле ЗаказПокупателя в документе РеализацияТоваровУслуг.
  • 📋 Табличные части — например, список товаров в заказе, где каждая строка может ссылаться на номенклатуру или договор.
  • 🔄 Движения документов — связи через регистры (например, РегистрНакопления.Взаиморасчеты).
  • 📎 Подчинённые объекты — например, ДополнительныеСоглашения к договору.

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

  1. Откройте конфигуратор (Файл → Открыть конфигурацию).
  2. Найдите нужный документ в дереве объектов (например, Документ.ЗаказПокупателя).
  3. Проверьте реквизиты и табличные части на наличие ссылочных типов.

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

💡

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

2. Простой запрос: выборка документов по прямой ссылке

Начнём с самого распространённого сценария: получение документов, связанных через реквизит-ссылку. Например, найдём все счета на оплату, привязанные к конкретному заказу покупателя.

Допустим, у нас есть документ ЗаказПокупателя с идентификатором 000000001, и нам нужно найти все счета (СчетНаОплатуПокупателю), где в реквизите Заказ хранится ссылка на этот заказ.

ВЫБРАТЬ

СчетНаОплатуПокупателю.Ссылка КАК Счет,

СчетНаОплатуПокупателю.Номер КАК НомерСчета,

СчетНаОплатуПокупателю.Дата КАК ДатаСчета

ИЗ

Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю

ГДЕ

СчетНаОплатуПокупателю.Заказ = &СсылкаНаЗаказ

Здесь &СсылкаНаЗаказ — параметр запроса, который нужно передать из кода . Пример вызова:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ... ГДЕ СчетНаОплатуПокупателю.Заказ = &СсылкаНаЗаказ";

Запрос.УстановитьПараметр("СсылкаНаЗаказ", Документы.ЗаказПокупателя.НайтиПоНомеру("000000001"));

Результат = Запрос.Выполнить();

Если связь реализована через табличную часть (например, в заказе есть таблица СчетаКОплате), запрос упрощается:

ВЫБРАТЬ

ЗаказПокупателяСчетаКОплате.Счет КАК Счет

ИЗ

Документ.ЗаказПокупателя.СчетаКОплате КАК ЗаказПокупателяСчетаКОплате

ГДЕ

ЗаказПокупателяСчетаКОплате.Ссылка = &СсылкаНаЗаказ

Что делать, если запрос возвращает пустой результат?

Если запрос не находит связанные документы, проверьте:

1. Правильность передачи ссылки (используйте Ссылка.УникальныйИдентификатор() для отладки).

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

3. Состояние объекта (не удалён ли он помечен на удаление).

4. Версию конфигурации — в некоторых обновлениях меняется структура хранения связей.

3. Связи через регистры: сложные сценарии

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

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

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

ПлатежноеПоручениеИсходящее.Ссылка КАК Платеж

ИЗ

Документ.ПлатежноеПоручениеИсходящее КАК ПлатежноеПоручениеИсходящее

ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(

&ДатаОплаты,

Контрагент = &Контрагент,

Договор = &Договор

) КАК Взаиморасчеты

ПО ПлатежноеПоручениеИсходящее.Ссылка = Взаиморасчеты.Регистратор

ГДЕ

Взаиморасчеты.Заказ = &СсылкаНаЗаказ

Здесь используются параметры:

  • &ДатаОплаты — дата, на которую проверяются остатки (обычно дата платежа).
  • &Контрагент и &Договор — реквизиты из заказа для фильтрации.
  • &СсылкаНаЗаказ — ссылка на исходный заказ.

Такой запрос вернёт все платежи, которые погасили долг по указанному заказу. Обратите внимание на использование ВНУТРЕННЕЕ СОЕДИНЕНИЕ — оно гарантирует, что в результат попадут только те платежи, которые действительно связаны с заказом через регистр.

💡

При работе с регистрами всегда указывайте дату среза (Остатки(&Дата)), иначе запрос может вернуть неактуальные данные или работать крайне медленно.

4. Рекурсивные запросы: обход цепочек документов

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

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

ВЫБРАТЬ

ЗаказПокупателя.Ссылка КАК Документ,

"Заказ" КАК ТипДокумента

ПОМЕСТИТЬ ВТ_СвязанныеДокументы

ИЗ

Документ.ЗаказПокупателя КАК ЗаказПокупателя

ГДЕ

ЗаказПокупателя.Ссылка = &СсылкаНаЗаказ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

СчетНаОплатуПокупателю.Ссылка КАК Документ,

"Счет" КАК ТипДокумента

ИЗ

Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю

ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_СвязанныеДокументы КАК СвязанныеДокументы

ПО СчетНаОплатуПокупателю.Заказ = СвязанныеДокументы.Документ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

ПлатежноеПоручениеИсходящее.Ссылка КАК Документ,

"Платеж" КАК ТипДокумента

ИЗ

Документ.ПлатежноеПоручениеИсходящее КАК ПлатежноеПоручениеИсходящее

ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&ДатаОплаты) КАК Взаиморасчеты

ПО ПлатежноеПоручениеИсходящее.Ссылка = Взаиморасчеты.Регистратор

ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_СвязанныеДокументы КАК СвязанныеДокументы

ПО Взаиморасчеты.Заказ = СвязанныеДокументы.Документ

ИНДЕКСИРОВАТЬ ПО Документ

;

Этот запрос:

  1. Сначала добавляет исходный заказ во временную таблицу ВТ_СвязанныеДокументы.
  2. Затем находит все счета, связанные с заказом, и добавляет их в ту же таблицу.
  3. На третьем шаге ищет платежи, погасившие долг по этим счётам.

Результат — единая таблица со всеми связанными документами и их типами. Для визуализации цепочки можно использовать дерево связей в отчёте.

⚠️ Внимание: Рекурсивные запросы могут сильно нагружать сервер, особенно если в цепочке сотни документов. Для больших баз ограничьте глубину обхода (например, только заказ → счёт → платеж) или используйте пакетное выполнение с разбивкой по типам документов.

5. Оптимизация производительности запросов

Неоптимизированные запросы к связанным документам — одна из главных причин тормозов в 1С. Следующие техники помогут ускорить работу:

Проблема Решение Пример
Полнотекстовый поиск по всем документам Используйте индексируемые поля (номер, дата) ГДЕ Номер = "123" вместо ГДЕ ПРЕДСТАВЛЕНИЕ() ПОДОБНО "%заказ%"
Избыточные соединения (ЛЕВОЕ СОЕДИНЕНИЕ) Заменяйте на ВНУТРЕННЕЕ, если не нужны пустые строки ВНУТРЕННЕЕ СОЕДИНЕНИЕ вместо ЛЕВОЕ СОЕДИНЕНИЕ
Выборка всех полей (ВЫБРАТЬ *) Указывайте только необходимые колонки ВЫБРАТЬ Документ.Ссылка, Документ.Дата
Отсутствие фильтра по дате Ограничивайте период выборки ГДЕ Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
Рекурсия без ограничений Используйте ПЕРВЫЕ 100 для тестирования ВЫБРАТЬ ПЕРВЫЕ 100

Для сложных запросов рекомендуется:

  • 📊 Использовать план запроса (Запрос.Выполнить().ПолучитьПлан()) для анализа «узких мест».
  • 🔄 Разбивать запрос на части — сначала получить IDs документов, затем детализировать.
  • 🗃️ Создавать индексы на часто используемые поля (в конфигураторе, Индексировать = Истина).

Критическая ошибка: использование функций в условиях (например, ГДЕ ГОД(Дата) = 2023) блокирует использование индексов. Всегда фильтруйте по полному значению даты (ГДЕ Дата МЕЖДУ ...).

☑️ Оптимизация запроса

Выполнено: 0 / 5

6. Практические примеры для типовых конфигураций

Разберём конкретные сценарии для популярных конфигураций .

6.1. УТ 11: Связь заказа с реализацией и отгрузкой

Чтобы найти все реализации (РеализацияТоваровУслуг) по заказу:

ВЫБРАТЬ

РеализацияТоваровУслуг.Ссылка КАК Реализация

ИЗ

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

ГДЕ

РеализацияТоваровУслуг.ЗаказПокупателя = &СсылкаНаЗаказ

6.2. ERP 2: Связь заказа на производство с заказами на покупку

В ERP заказ на производство (ЗаказНаПроизводство) может порождать заказы поставщикам (ЗаказПоставщику) на сырьё. Запрос:

ВЫБРАТЬ

ЗаказПоставщику.Ссылка КАК ЗаказПоставщику

ИЗ

Документ.ЗаказПоставщику КАК ЗаказПоставщику

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЗаказНаПроизводство.Материалы КАК Материалы

ПО ЗаказПоставщику.Ссылка = Материалы.ЗаказПоставщику

ГДЕ

Материалы.Ссылка = &СсылкаНаЗаказНаПроизводство

6.3. Бухгалтерия 3.0: Связь платежки с банковской выпиской

Чтобы найти банковскую выписку (БанковскаяВыписка), которой проведён платеж:

ВЫБРАТЬ

БанковскаяВыписка.Ссылка КАК Выписка

ИЗ

Документ.БанковскаяВыписка КАК БанковскаяВыписка

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.БанковскаяВыписка.ДвиженияДенежныхСредств КАК Движение

ПО БанковскаяВыписка.Ссылка = Движение.Ссылка

ГДЕ

Движение.ПлатежныйДокумент = &СсылкаНаПлатежку

⚠️ Внимание: В Бухгалтерии 3.0 структуры документов могут отличаться в зависимости от версии. Например, в некоторых релизах платежи связываются с выписками через регистр ДенежныеСредства, а не через табличную часть. Всегда проверяйте актуальную структуру в вашей базе!

7. Ошибки и их решение

При работе со связанными документами часто возникают типичные ошибки. Разберём самые распространённые:

  • 🔴 Ошибка: "Поле не найдено"

    Причина: опечатка в имени реквизита или табличной части. Решение: проверьте структуру документа в конфигураторе (Документ.ИмяДокумента.Реквизиты()).

  • 🔴 Запрос выполняется слишком долго

    Причины:

    • Отсутствие индексов на полях соединения.
    • Использование ЛЕВОЕ СОЕДИНЕНИЕ вместо ВНУТРЕННЕГО.
    • Выборка всех колонок (ВЫБРАТЬ *).

    Решение: оптимизируйте запрос по методикам из раздела 5.

  • 🔴 В результате пустая таблица

    Возможные причины:

    • Неверно передан параметр-ссылка (проверьте через Ссылка.УникальныйИдентификатор()).
    • Документы связаны через регистр, но в запросе не учтена дата среза.
    • Отсутствуют права на чтение связанных документов.
  • 🔴 Ошибка: "Недостаточно прав"

    Решение: проверьте роли пользователя в Администрирование → Пользователи или выполните запрос от имени администратора.

Если запрос возвращает неожиданные данные (например, лишние документы), используйте пошаговую отладку:

  1. Выполните запрос без фильтров, чтобы увидеть все возможные связи.
  2. Добавьте условия по одному, проверяя результат на каждом шаге.
  3. Используйте ПОКАЗАТЬ ПЛАН ЗАПРОСА для анализа логики выполнения.
Как отладить запрос с временными таблицами?

Для отладки запросов с ПОМЕСТИТЬ ВТ_...:

1. Разбейте запрос на части и выполните каждую отдельно.

2. Проверьте промежуточные результаты во временных таблицах через ВЫБРАТЬ * ИЗ ВТ_ИмяТаблицы.

3. Используйте Сообщить(Запрос.Текст) перед выполнением, чтобы убедиться, что параметры подставлены корректно.

8. Альтернативные подходы: когда запросы не помогают

В некоторых случаях запросы неэффективны или невозможны. Рассмотрим альтернативы:

  • 🔄 Обход по ссылкам в коде

    Если документов мало, можно в цикле пройти по ссылкам:

    Для Каждого ТекущийСчет Из Заказ.СчетаКОплате Цикл
    

    Сообщить(ТекущийСчет.Ссылка);

    КонецЦикла;

    Минус: медленно работает на больших объёмах данных.
  • 📊 Отчёты с предопределёнными связями

    В типовых конфигурациях есть готовые отчёты, например:

    • Анализ субконто (для связей через регистры).
    • Карточка счёта (для бухгалтерских документов).
    • Анализ выполнения заказов (в УТ 11).
  • 🔗 Внешние обработки

    Готовые решения:

    • «Анализ связей документов» (доступна на Инфостарт).
    • «Построитель маршрутов документов» (для ERP).
  • 🗃️ Хранение связей в отдельном регистре

    Если связи сложные, можно создать регистр сведений для их явного хранения. Например:

    РегистрСведений.СвязиДокументов:
    

    Измерения: Источник (Ссылка), ЦелевойДокумент (Ссылка)

    Ресурсы: ТипСвязи (Строка)

    Плюс: ускоряет выборку, упрощает аналитику.

Для интеграции с внешними системами (например, выгрузка цепочки документов в Excel или BI-систему) лучше использовать HTTP-сервисы или REST API, если они поддерживаются вашей конфигурацией. Это позволит избежать нагрузки на клиентское приложение.

Часто задаваемые вопросы

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

Используйте запрос с фильтрацией по полю Договор в документах. Пример для заказов и реализаций:

ВЫБРАТЬ

ЗаказПокупателя.Ссылка КАК Документ,

"Заказ" КАК ТипДокумента

ИЗ

Документ.ЗаказПокупателя КАК ЗаказПокупателя

ГДЕ

ЗаказПокупателя.Договор = &СсылкаНаДоговор

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

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

"Реализация" КАК ТипДокумента

ИЗ

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

ГДЕ

РеализацияТоваровУслуг.Договор = &СсылкаНаДоговор

Для связей через регистры (например, платежи) добавьте соединение с РегистрНакопления.Взаиморасчеты.

Можно ли получить связанные документы для удалённого (помеченного на удаление) заказа?

Да, но нужно явно указать в запросе, что требуются все документы, включая помеченные на удаление:

ВЫБРАТЬ

СчетНаОплатуПокупателю.Ссылка КАК Счет

ИЗ

Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю

ГДЕ

СчетНаОплатуПокупателю.Заказ = &СсылкаНаЗаказ

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

Если нужно включить и удалённые документы, уберите условие И НЕ ПометкаУдаления.

⚠️ Внимание: Работа с удалёнными объектами может привести к неконсистентности данных. Используйте этот подход только для аналитики, не для модификации!
Как экспортировать цепочку документов в Excel?

Используйте следующий код для выгрузки результата запроса в Excel:

Результат = Запрос.Выполнить();

ТаблицаРезультата = Результат.Выгрузить();

Excel = Новый COMОбъект("Excel.Application");

Книга = Excel.Workbooks.Add();

Лист = Книга.Worksheets(1);

Для НомСтроки = 1 По ТаблицаРезультата.КоличествоКолонок Цикл

Лист.Cells(1, НомСтроки).Value = ТаблицаРезультата.Колонки[НомСтроки-1].Имя;

КонецЦикла;

Для НомСтроки = 0 По ТаблицаРезультата.КоличествоСтрок() - 1 Цикл

Для НомКолонки = 0 По ТаблицаРезультата.КоличествоКолонок() - 1 Цикл

Лист.Cells(НомСтроки + 2, НомКолонки + 1).Value = ТаблицаРезультата[НомСтроки][НомКолонки];

КонецЦикла;

КонецЦикла;

Excel.Visible = Истина;

Для больших объёмов данных используйте пакетную выгрузку или специализированные обработки (например, «ВыгрузкаВExcel» с Инфостарта).

Почему запрос к регистру работает медленно?

Основные причины:

  1. Отсутствие индексов на измерениях регистра. Решение: добавьте индексы в конфигураторе.
  2. Слишком широкий период. Ограничьте дату среза (Остатки(&ДатаНачала, &ДатаОкончания)).
  3. Сложные условия в ГДЕ. Перенесите фильтрацию в код после выполнения запроса.
  4. Большой объём данных. Используйте ПЕРВЫЕ 1000 для тестирования.

Для ускорения также поможет денормализация — хранение часто запрашиваемых связей в отдельных регистрах.

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

Запрос для поиска документов (заказы, реализации, поступления), где встречается указанная номенклатура:

ВЫБРАТЬ

Документ.Ссылка КАК Документ,

Документ.Вид() КАК ВидДокумента,

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