Как передать владельца в подчиненный справочник и вернуть созданный адрес в форму организации

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке конфигураций на платформе 1С:Предприятие 8.3 часто возникает классическая задача: из формы основного объекта (например, справочника Организации) нужно создать подчиненный объект (например, Адреса) и сразу подставить созданную ссылку в реквизит основной формы. Основная сложность здесь заключается в том, что если основной объект еще не записан, у него нет ссылки, а значит, подчиненный элемент не может «узнать» своего владельца.

В этой статье мы разберем несколько способов решения этой задачи: от использования классических подчиненных справочников до более гибкого механизма с регистрами сведений.

Способ 1. Использование подчиненного справочника и ОписанияОповещения

Рассмотрим ситуацию, когда нам необходимо открыть форму подчиненного справочника Адреса, передать туда ссылку на текущую Организацию и получить результат обратно. Основная проблема новичков — попытка получить результат сразу после метода ОткрытьФорму. В управляемом приложении код на клиенте не останавливается, поэтому нужно использовать механизм обратного вызова (callback).

Разберем по шагам, как это реализовать в модуле формы владельца:

  1. Запись владельца: Чтобы у подчиненного справочника был владелец, объект-владелец должен быть физически записан в базу данных.
  2. Подготовка параметров: Мы передаем структуру параметров, которую справочник Адреса использует при создании.
  3. Создание оповещения: Указываем процедуру, которая выполнится после закрытия формы адреса.

Пример реализации в форме организации:


&НаКлиенте
Процедура ЮридическийАдресСоздание(Элемент, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // 1. Сначала записываем текущий объект, чтобы получить ссылку
    Если Объект.Ссылка.Пустая() Тогда
        Если НЕ ЭтаФорма.Записать() Тогда
            Возврат; // Если запись не удалась (например, не заполнены обязательные поля)
        КонецЕсли;
    КонецЕсли;

    // 2. Подготавливаем параметры для новой формы
    // Используем фиксированный ключ "ЗначениеЗаполнения" для автоматической подстановки владельца
    ПараметрыЗаполнения = Новый Структура("Владелец", Объект.Ссылка);
    ПараметрыФормы = Новый Структура("ЗначениеЗаполнения", ПараметрыЗаполнения);

    // 3. Создаем описание оповещения о закрытии
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияФормыАдреса", ЭтаФорма);

    // 4. Открываем форму
    ОткрытьФорму("Справочник.Адреса.Форма.ФормаЭлемента", 
                 ПараметрыФормы, 
                 Элемент, 
                 УникальныйИдентификатор, 
                 , 
                 , 
                 Оповещение, 
                 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
                 
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияФормыАдреса(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
    
    // Если пользователь сохранил адрес, РезультатЗакрытия будет содержать Ссылку
    Если ЗначениеЗаполнено(РезультатЗакрытия) Тогда
        Объект.ЮридическийАдрес = РезультатЗакрытия;
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: В форме самого справочника Адреса при закрытии (в обработчике команды записи или закрытия) необходимо убедиться, что вызывается Закрыть(Объект.Ссылка), чтобы ссылка передалась в РезультатЗакрытия.

Способ 2. Решение через Регистр Сведений (архитектурно верный подход)

Как отмечают опытные разработчики, хранить адреса в подчиненном справочнике не всегда удобно, если предполагается хранение истории или разных типов контактной информации (телефон, email, Skype). Использование Регистра Сведений позволяет гибко управлять данными. Выясним причину, почему это лучше: в регистре можно задать уникальность по измерениям Организация + ВидАдреса.

Проанализируем пример кода, предложенный в обсуждении, где адрес собирается в текстовую строку после записи данных в регистр:


&НаКлиенте
Процедура ЗаписатьИОбновитьАдрес(Команда)
    
    // Открываем форму записи регистра модально (для простоты) или через Оповещение
    // Передаем параметры владельца и вида адреса
    ПараметрыЗаписи = Новый Структура;
    ПараметрыЗаписи.Вставить("Организация", Объект.Ссылка);
    ПараметрыЗаписи.Вставить("ВидАдреса", ПредопределенноеЗначение("Перечисление.ВидыАдресов.Юридический"));
    
    ОткрытьФорму("РегистрСведений.Адреса.Форма.ФормаЗаписи", Новый Структура("ЗначениеЗаполнения", ПараметрыЗаписи), ЭтаФорма);
    
    // После закрытия формы обновляем представление адреса на форме владельца
    ОбновитьПредставлениеАдресаНаСервере();
    
КонецПроцедуры

&НаСервере
Процедура ОбновитьПредставлениеАдресаНаСервере()
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Адреса.Индекс,
        |   Адреса.Страна,
        |   Адреса.Город,
        |   Адреса.Улица
        |ИЗ
        |   РегистрСведений.Адреса КАК Адреса
        |ГДЕ
        |   Адреса.Организация = &Организация И Адреса.ВидАдреса = &Вид";
    
    Запрос.УстановитьПараметр("Организация", Объект.Ссылка);
    Запрос.УстановитьПараметр("Вид", Перечисления.ВидыАдресов.Юридический);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Объект.ЮридическийАдресТекст = Выборка.Индекс + ", " + Выборка.Страна + ", " + Выборка.Город + ", " + Выборка.Улица;
    КонецЕсли;
    
КонецПроцедуры

Проблема «Битых ссылок» и метод ПолучитьСсылкуНового()

Разберем ситуацию, когда мы не хотим принудительно записывать Организацию до создания адреса. В 1С существует метод Объект.ПолучитьСсылкуНового(). Мы можем заранее сгенерировать уникальный идентификатор (GUID) для еще не созданной организации и передать его как владельца в форму адреса.

Однако будьте осторожны: если пользователь заполнит адрес и нажмет «Ок», а затем передумает и закроет форму организации без сохранения, в базе данных останется запись об адресе, ссылающаяся на несуществующую организацию («битая ссылка»). Именно поэтому в типовых конфигурациях чаще всего используется принудительная запись основного объекта перед вводом контактной информации.

Рекомендации по профессиональной разработке

Рассмотрим подробнее, как этот функционал реализован в БСП (Библиотека стандартных подсистем):

Подводя итог, можно сказать: для учебных целей использование ОписаниеОповещения в связке с ОткрытьФорму — отличный способ понять логику работы асинхронных вызовов в 1С. Но для реальных бизнес-задач лучше использовать структуру регистров или готовые блоки БСП.

← На главную