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