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