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