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

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

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

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

Подчиненные документы в 1С — это документы, введенные на основании другого документа: например, «Реализация товаров и услуг» на основании «Заказа покупателя» или «Счет-фактура» на основании «Реализации». Получить их программно нужно при построении отчетов, проверке комплектности цепочки документов, регламентных обработках и при выводе печатных форм со ссылками на связанные объекты.

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

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

Как устроена связь документов в конфигурации

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

Второй механизм — критерий отбора. В типовых решениях («Управление торговлей», «ERP», «Комплексная автоматизация») есть критерий отбора «СвязанныеДокументы», который объединяет документы по цепочке ввода на основании. Если он присутствует в конфигурации, это самый удобный способ получить всю цепочку одним запросом.

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

Запрос по реквизиту «ДокументОснование»

Самый прямой способ — выбрать все документы, у которых реквизит основания равен нужной ссылке. Это работает быстро, если по реквизиту есть индекс (в типовых конфигурациях для «ДокументОснование» он обычно создан), и покрывает большинство задач вида «найти все реализации по заказу».

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

Запрос.Текст =

"ВЫБРАТЬ

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

| Реализация.Номер КАК Номер,

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

|ИЗ

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

|ГДЕ

| Реализация.ДокументОснование = &Основание

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

Запрос.УстановитьПараметр("Основание", ДокументОснование);

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

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

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

Получение связанных документов через критерий отбора

Критерий отбора «СвязанныеДокументы» в типовых конфигурациях собирает всю цепочку: и документы, введенные на основании текущего, и те, на основании которых введен текущий. Запрос к критерию отбора выглядит так:

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

Запрос.Текст =

"ВЫБРАТЬ

| СвязанныеДокументы.Ссылка КАК Ссылка

|ИЗ

| КритерийОтбора.СвязанныеДокументы(&Документ) КАК СвязанныеДокументы";

Запрос.УстановитьПараметр("Документ", ТекущийДокумент);

Выборка = Запрос.Выполнить().Выбрать();

Результат содержит ссылки разных типов, поэтому перед обращением к реквизитам проверяйте тип каждой ссылки через ТипЗнч(). Для вывода пользователю удобно получать представление ссылки — оно вычисляется платформой автоматически при обращении к свойству.

Если в вашей конфигурации такого критерия нет, его можно создать в конфигураторе: добавьте объект «Критерий отбора», включите в состав нужные реквизиты документов (все реквизиты-основания), и платформа начнет отслеживать связи автоматически. Это потребует обновления конфигурации базы данных и реструктуризации.

Обход всей цепочки связей (дерево документов)

Задача «найти все документы вниз по цепочке» — например, от заказа дойти до оплат и возвратов — решается рекурсивным обходом. На каждом шаге запросом находятся прямые подчиненные, затем для каждого из них процедура вызывается повторно.

Чтобы не делать запрос в цикле по одному документу (это медленно на больших цепочках), собирайте текущий уровень в массив и выбирайте подчиненные сразу для всего массива условием ДокументОснование В (&МассивСсылок). Так количество обращений к базе равно глубине цепочки, а не числу документов.

bsl
Процедура НайтиПодчиненные(МассивОснований, ВсеНайденные)
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Документ.РеализацияТоваровУслуг
	|ГДЕ ДокументОснование В (&Основания)";
	Запрос.УстановитьПараметр("Основания", МассивОснований);
	Найденные = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
	Если Найденные.Количество() > 0 Тогда
		Для Каждого Ссылка Из Найденные Цикл
			ВсеНайденные.Добавить(Ссылка);
		КонецЦикла;
		НайтиПодчиненные(Найденные, ВсеНайденные);
	КонецЕсли;
КонецПроцедуры

Обязательно защититесь от зацикливания: если в данных встретится циклическая ссылка (документ ссылается сам на себя через цепочку), рекурсия уйдет в бесконечность. Храните уже обработанные ссылки в соответствии и пропускайте повторные.

Выбор подхода под конкретную задачу

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

Маршрут решения

Как выбрать действие

Нужны прямые подчиненные одного типаИспользуйте запрос по реквизиту ДокументОснование с отбором по ссылке
Нужна вся цепочка в типовой конфигурацииИспользуйте запрос к критерию отбора СвязанныеДокументы
Связей несколько уровней и типов в самописной конфигурацииРеализуйте обход по уровням с массивом ссылок и защитой от циклов
Нужна разовая проверка без кодаОткройте структуру подчиненности документа в пользовательском режиме

Для отчетов на СКД связь удобно закладывать прямо в набор данных: соединение таблиц документов по реквизиту основания дает результат без написания кода обхода. Это быстрее и проще в сопровождении, если структура связей фиксирована.

Типичные ошибки и проверка результата

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

Вторая группа ошибок — производительность. Запрос в цикле по каждому документу, отсутствие индекса по реквизиту основания и выборка всех полей вместо только ссылки заметно замедляют работу на больших базах. Выбирайте минимум полей и используйте параметризованные запросы.

Типичные ошибки
01
Запрос без отбора по пометке удаления — в результат попадают «мертвые» документы и искажают отчеты
02
Запрос в цикле по одному документу вместо отбора по массиву ссылок — резкое падение производительности
03
Обращение к реквизитам ссылки без проверки типа при выборке из критерия отбора — ошибка «Поле не найдено»
04
Рекурсивный обход без защиты от циклических ссылок — зависание сеанса
05
Ожидание связей там, где ввод на основании не настроен — пустой результат при корректном коде
Контрольные точки

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

Количество найденных документов
Норма

Совпадает со структурой подчиненности в интерфейсе

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

В коде документов меньше, чем видно пользователю

Состав выборки
Норма

Нет помеченных на удаление, если они не нужны

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

Присутствуют непроведенные или удаленные документы

Скорость выполнения
Норма

Запросы выполняются пакетно по массиву ссылок

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

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

FAQ

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

В типовых конфигурациях откройте документ и нажмите кнопку «Связанные документы» или «Структура подчиненности» (обычно в меню «Еще» формы документа). Платформа покажет дерево связанных документов вверх и вниз по цепочке ввода на основании.

Почему запрос по ДокументОснование возвращает пустой результат?

Чаще всего реквизит просто не заполнен: документы создавались копированием, загрузкой из обмена или ввод на основании для этой пары не настроен. Откройте подчиненный документ вручную и проверьте значение реквизита основания.

Можно ли получить подчиненные документы разных типов одним запросом?

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

Как найти документы, введенные на основании, в обычных формах (8.2)?

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

Влияет ли пометка удаления основания на подчиненные документы?

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

Итог

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

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