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