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