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

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

1. Стандартные механизмы платформы: движение по ссылкам

Самый очевидный способ — использовать встроенные ссылки между документами. В большинстве типовых конфигураций (1С:Бухгалтерия, 1С:УТ, 1С:ERP) документы автоматически ссылаются друг на друга через реквизиты типа СсылкаНаДокумент или Основание.

Например, в документе "Реализация товаров и услуг" есть реквизит ЗаказКлиента, а в документе "Поступление безналичных ДС" — реквизит Основание, который может ссылаться на реализацию. Чтобы получить цепочку программно, достаточно рекурсивно обходить эти ссылки:

Процедура ПолучитьЦепочкуДокументов(НачальныйДокумент)

Цепочка = Новый Массив;

ТекущийДокумент = НачальныйДокумент;

Пока ТекущийДокумент <> Неопределено Цикл

Цепочка.Добавить(ТекущийДокумент);

// Проверяем возможные типы оснований

Если ТипЗнч(ТекущийДокумент.Основание) = Тип("ДокументСсылка") Тогда

ТекущийДокумент = ТекущийДокумент.Основание.ПолучитьОбъект();

ИначеЕсли ТипЗнч(ТекущийДокумент.ЗаказКлиента) = Тип("ДокументСсылка") Тогда

ТекущийДокумент = ТекущийДокумент.ЗаказКлиента.ПолучитьОбъект();

Иначе

ТекущийДокумент = Неопределено;

КонецЕсли;

КонецЦикла;

Возврат Цепочка;

КонецПроцедуры

Этот метод работает быстро и не требует сложных конструкций, но имеет ограничения:

  • 🔹 Подходит только для документов с явными ссылками (не все конфигурации поддерживают полную цепочку)
  • 🔹 Не учитывает документы, связанные через регистры (например, заказы поставщикам, привязанные к заказам клиентов через регистр ЗаказыПоставщикам)
  • 🔹 Может зациклиться, если в цепочке есть кольцевые ссылки (нужна защита от рекурсии)
💡

Всегда добавляйте в рекурсивные процедуры счетчик итераций (например, Если Цепочка.Количество() > 100 Тогда Прервать;), чтобы избежать зависания при кольцевых ссылках.

2. Использование запроса: универсальный подход для любых связей

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

Рассмотрим пример для конфигурации 1С:Управление торговлей, где нужно получить цепочку: Заказ клиента → Реализация → Оплата → Возврат. Здесь связи хранятся в разных местах:

- Заказ и реализация связаны через реквизит ЗаказКлиента в документе реализации.

- Реализация и оплата — через регистр ВзаиморасчетыСКлиентами.

- Возврат ссылается на реализацию через реквизит Реализация.

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

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

"ВЫБРАТЬ

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

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

| Оплаты.Ссылка КАК Оплата,

| Возвраты.Ссылка КАК Возврат

|ИЗ

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

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

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

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

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

| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеБезналичныхДС КАК Оплаты

| ПО Остатки.Партнер = Оплаты.Контрагент И Остатки.Договор = Оплаты.Договор

| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ВозвратТоваровОтКлиента КАК Возвраты

| ПО Возвраты.Реализация = Реализации.Ссылка

|ГДЕ

| Заказы.Ссылка = &СсылкаНаЗаказ";

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

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

Этот подход гибкий, но требует глубокого знания структуры базы. Основные сложности:

  • 📌 Нужно точно знать, в каких регистрах хранятся связи (в разных конфигурациях они могут отличаться)
  • 📌 Запросы с множеством соединений могут тормозить на больших базах
  • 📌 Не все связи можно выразить через SQL-подобный синтаксис (иногда нужны временные таблицы)
📊 Какой метод получения связей вы используете чаще?
Стандартные ссылки
Запросы
Временные таблицы
Внешние обработки
Свой вариант

3. Временные таблицы: обработка сложных иерархий

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

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

- Счета на оплату поставщику

- Поступления товаров

- Корректировки поступлений

- Возвраты поставщику

Алгоритм будет таким:

  1. Создать временную таблицу для хранения цепочки
  2. Добавить в нее начальный документ (заказ поставщику)
  3. Поочередно искать связанные документы каждого типа и добавлять их в таблицу
  4. Исключать дубли и кольцевые ссылки
Процедура ПостроитьЦепочкуПоставщика(СсылкаНаЗаказ)

// Создаем временную таблицу

ТаблицаЦепочки = Новый ТаблицаЗначений;

ТаблицаЦепочки.Колонки.Добавить("Документ", Новый ОписаниеТипов("ДокументСсылка"));

ТаблицаЦепочки.Колонки.Добавить("ТипСвязи", Новый ОписаниеТипов("Строка"));

// Добавляем начальный документ

НоваяСтрока = ТаблицаЦепочки.Добавить();

НоваяСтрока.Документ = СсылкаНаЗаказ;

НоваяСтрока.ТипСвязи = "Заказ поставщику";

// Ищем связанные счета на оплату

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

Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ Счета.Ссылка

|ИЗ Документ.СчетНаОплатуПоставщику КАК Счета

|ГДЕ Счета.ЗаказПоставщику = &Ссылка";

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

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

Пока Результат.Следующий() Цикл

НоваяСтрока = ТаблицаЦепочки.Добавить();

НоваяСтрока.Документ = Результат.Ссылка;

НоваяСтрока.ТипСвязи = "Счет на оплату";

КонецЦикла;

// Аналогично добавляем поступления, корректировки и возвраты

// ...

Возврат ТаблицаЦепочки;

КонецПроцедуры

Преимущества этого метода:

  • 🔧 Позволяет обрабатывать связи любой сложности
  • 🔧 Легко расширяется для новых типов документов
  • 🔧 Можно добавлять дополнительные колонки (даты, суммы, статусы)

Создать структуру таблицы с нужными колонками|Добавить защиту от дублей|Определить все возможные типы связей|Проверить производительность на тестовых данных|Обработать исключения (например, отсутствие прав)

-->

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

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

Пример: в конфигурации 1С:ERP заказ клиента может содержать подзаказы (документы "Заказ клиента" с установленным флагом ЭтоПодзаказ и ссылкой на родительский заказ). Чтобы получить полное дерево, напишем рекурсивную процедуру:

Функция ПолучитьДеревоЗаказов(РодительскийЗаказ, Уровень = 0)

Результат = Новый Структура("Заказ, Подзаказы");

Результат.Заказ = РодительскийЗаказ;

// Ищем подзаказы

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

Запрос.Текст = "ВЫБРАТЬ Ссылка

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

|ГДЕ РодительскийЗаказ = &Родитель И ЭтоПодзаказ = ИСТИНА";

Запрос.УстановитьПараметр("Родитель", РодительскийЗаказ);

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

Подзаказы = Новый Массив;

Пока Выборка.Следующий() Цикл

Подзаказ = ПолучитьДеревоЗаказов(Выборка.Ссылка, Уровень + 1);

Подзаказы.Добавить(Подзаказ);

КонецЦикла;

Результат.Подзаказы = Подзаказы;

Возврат Результат;

КонецФункции

Этот метод идеален для визуализации иерархии, но имеет нюансы:

  • 🌳 Глубина рекурсии ограничена (в 1С по умолчанию — 500 уровней)
  • 🌳 При большом количестве подзаказов может возникнуть переполнение стека
  • 🌳 Для оптимизации можно использовать не рекурсию, а стек или очередь
Как обойти ограничение на глубину рекурсии?

Вместо рекурсивной функции используйте цикл с явным управлением стека:

Стек = Новый Очередь;

Стек.Поместить(НачальныйЗаказ);

Пока Стек.Количество() > 0 Цикл

ТекущийЗаказ = Стек.Извлечь();

// Обработка текущего заказа

// ...

// Добавляем подзаказы в стек

Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Документ.ЗаказКлиента ГДЕ РодительскийЗаказ = &Текущий");

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

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

Пока Выборка.Следующий() Цикл

Стек.Поместить(Выборка.Ссылка);

КонецЦикла;

КонецЦикла;

5. Внешние обработки и расширения: готовые решения

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

Популярные решения:

  • 📄 "Анализ связей документов" — показывает цепочки по всем возможным связям, включая регистры
  • 📄 "Дерево документов" — визуализирует иерархию в виде дерева с возможностью фильтрации
  • 📄 "Поиск дублей и связей" — находит неочевидные связи через регистры накопления

Преимущества внешних обработок:

Преимущество Недостаток
🔹 Не нужно писать код ❌ Может не подходить под вашу конфигурацию
🔹 Часто содержат дополнительные функции (экспорт в Excel, графическая схема) ❌ Требуют проверки на безопасность (особенно бесплатные)
🔹 Поддерживаются сообществом (обновления, исправления багов) ❌ Могут тормозить на больших базах
💡

Перед использованием внешней обработки всегда проверяйте ее в тестовой базе — некоторые решения могут конфликтовать с вашими доработками или типовыми механизмами.

Если вы решили написать свою обработку, обратите внимание на следующие моменты:

  • 🛠 Используйте Управляемые формы для удобного интерфейса
  • 🛠 Добавьте возможность сохранения результатов в файл (Excel, JSON)
  • 🛠 Реализуйте фильтры по датам, контрагентам, типам документов
💡

Для визуализации связей между документами можно использовать библиотеку D3.js через механизм ВнедрениеHTML в 1С. Это позволит строить интерактивные графические схемы прямо в форме обработки.

Типичные ошибки и как их избежать

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

1. Зацикливание при рекурсивном обходе

Если в цепочке документов есть кольцевые ссылки (например, документ А ссылается на документ Б, а документ Б — обратно на А), рекурсивная функция зависнет. Решение:

Процедура ОбойтиЦепочку(Документ, История = Новый Массив)

Если История.Найти(Документ) <> Неопределено Тогда

Возврат; // Уже обрабатывали этот документ

КонецЕсли;

История.Добавить(Документ);

// Далее обработка документа

// ...

КонецПроцедуры

2. Некорректная работа с правами доступа

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

  • 🔐 Используйте Попытка...Исключение для обработки ошибок доступа
  • 🔐 Проверяйте права перед выполнением запросов
  • 🔐 В внешних обработках запрашивайте повышенные права при необходимости

3. Долгая обработка больших цепочек

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

  • ⏳ Разбивайте обработку на части (например, по 50 документов за раз)
  • ⏳ Используйте Фоновые задания для длительных операций
  • ⏳ Кэшируйте промежуточные результаты
💡

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

Практические примеры применения

Знание структуры подчиненности документов пригодится в самых разных задачах. Рассмотрим несколько реальных кейсов:

1. Анализ просроченных оплат

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

  1. Получить все заказы с просроченной датой оплаты
  2. Для каждого заказа найти связанные реализации
  3. Для каждой реализации проверить оплаты в регистре ВзаиморасчетыСКлиентами
  4. Вывести заказы, по которым сумма оплат меньше суммы реализаций

2. Построение отчета по логистике

Задача: проследить путь товара от заказа поставщику до отгрузки клиенту. Цепочка может включать:

  • 📦 Заказ поставщику → Поступление товаров → Перемещение на склад → Отгрузка клиенту
  • 📦 Возвраты от клиента → Возврат поставщику

3. Автоматическое формирование пакетов документов

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

  • 📑 Найти шаблоны документов в справочнике ШаблоныДокументов
  • 📑 Создать новые документы на основе текущей реализации
  • 📑 Заполнить реквизиты (контрагент, сумма, номенклатура) из родительского документа
  • 📑 Сохранить связи в реквизитах Основание или СвязанныйДокумент

4. Проверка корректности цепочек

Задача: найти документы с разорванными связями (например, реализация без заказа или оплата без реализации). Это помогает выявить ошибки ввода данных. Алгоритм:

  1. Получить все документы за период
  2. Для каждого документа проверить наличие обязательных связей
  3. Вывести список документов с отсутствующими ссылками
Как найти документы без связей?

Используйте запрос с условием ЕСТЬ NULL:

ВЫБРАТЬ

Реализации.Ссылка КАК Документ

ИЗ

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

ГДЕ

Реализации.ЗаказКлиента ЕСТЬ NULL

FAQ: Ответы на частые вопросы

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

Да, в некоторых конфигурациях есть встроенные отчеты, показывающие связи между документами. Например, в 1С:ERP есть отчет "Анализ связей документов", а в 1С:УТ"Движения документа". Однако эти отчеты обычно показывают только прямые связи и не позволяют гибко настраивать вывод.

Для сложных сценариев (например, построение цепочки из 10+ документов разных типов) без программирования не обойтись.

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

В 1С:Фреш и других облачных решениях доступ к базе ограничен, но вы можете:

  • Использовать встроенные отчеты (если они есть в вашей конфигурации)
  • Написать внешнюю обработку на 1Script (язык для облака)
  • Экспортировать данные в Excel и анализировать связи там

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

Почему запрос возвращает не все связи?

Это может происходить по нескольким причинам:

  • 🔍 Ограничения прав доступа — пользователь не видит некоторые документы
  • 🔍 Неправильные соединения в запросе — например, используется ВНУТРЕННЕЕ СОЕДИНЕНИЕ вместо ЛЕВОЕ
  • 🔍 Связи хранятся в неочевидных регистрах — проверьте структуру метаданных
  • 🔍 Документы помечены на удаление — они не попадают в выборку без специальных условий

Чтобы диагностировать проблему, выполните запрос в консоли запросов (меню Все функции → Запросы) и проверьте промежуточные результаты.

Как визуализировать цепочку документов?

Есть несколько способов:

  1. Табличный вывод — простейший вариант, подходит для небольших цепочек. Можно использовать ТаблицаЗначений с колонками "Уровень", "Тип документа", "Номер", "Дата".
  2. Дерево значений — в 1С есть объект ДеревоЗначений, который позволяет отображать иерархию с раскрывающимися узлами.
  3. Графическая схема — для этого понадобится внешняя компонента (например, GanttChart или OrgChart) или интеграция с Excel/Power BI.
  4. HTML-визуализация — с помощью ВнедрениеHTML и библиотек вроде D3.js или Vis.js можно строить интерактивные графики прямо в 1С.

Для быстрого прототипирования удобно использовать внешнюю обработку "Дерево документов" с портала Infostart.

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

Да, но с оговорками:

  • 🗑 Помеченные на удаление документы не попадают в стандартные выборки. Чтобы их увидеть, добавьте в запрос условие ПометкаУдаления = ЛОЖЬ ИЛИ ПометкаУдаления ЕСТЬ NULL.
  • 🗑 Удаленные документы (те, что уже физически удалены из базы) восстановить нельзя — их связи теряются безвозвратно.
  • 🗑 В некоторых конфигурациях удаленные документы хранятся в архиве — проверьте наличие регистра АрхивДокументов.

Если документ помечен на удаление, но вам нужны его связи, используйте метод ПолучитьОбъект() с флагом ПропускатьПомеченныеНаУдаление = Ложь:

ДокументОбъект = ДокументСсылка.ПолучитьОбъект(Ложь); // Второй параметр - пропускать помеченные на удаление

Теперь вы знаете все основные способы программного получения структуры подчиненности документов в 1С. Выбор метода зависит от задачи: для простых цепочек подойдут стандартные ссылки, для сложных анализа — запросы или временные таблицы, а для визуализации — внешние обработки. Не забывайте тестировать решения на реальных данных и учитывать особенности вашей конфигурации!