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