Как получить ссылку на созданный элемент справочника в управляемых формах 1С 8.3

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

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

В этой статье мы подробно разберем, почему стандартный подход «в лоб» не работает, и рассмотрим несколько эффективных способов решения этой задачи, одобренных сообществом разработчиков 1С.

Почему нельзя получить ссылку сразу в вызывающей функции

Проанализируем типичную ситуацию. Когда мы вызываем метод ОткрытьФорму, платформа инициирует создание окна на стороне клиента. Если мы используем режим открытия окна БлокироватьОкноВладельца, пользователь действительно не может взаимодействовать с основной формой, пока не закроет новую. Однако выполнение программного кода в функции, вызвавшей открытие, продолжается сразу после вызова ОткрытьФорму (или завершается, если это был последний вызов).

На момент выполнения следующей строки кода после открытия формы объект в базе данных еще не создан, запись не произведена, а значит, и ссылки (UUID) в базе еще нет. Именно поэтому попытка прочитать Форма.Объект.Ссылка вернет пустую ссылку.

Решение 1: Использование механизма «ОписаниеОповещения»

Это наиболее правильный и современный подход для работы в управляемом приложении, особенно учитывая требования к асинхронности в веб-клиенте и мобильном клиенте. Идея состоит в том, чтобы разделить алгоритм на две части: до открытия формы и после её закрытия.

Рассмотрим по шагам, как это реализовать:

  1. Создадим процедуру-обработчик, которая будет вызвана платформой автоматически, когда форма создания элемента закроется.
  2. В основном коде инициализируем объект ОписаниеОповещения, указав в нем нашу процедуру-обработчик.
  3. Передадим это описание в метод ОткрытьФорму.

Посмотрим на пример реализации кода:


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

&НаКлиенте
Процедура ОбработатьЗавершениеСозданияАнкеты(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
    
    // РезультатЗакрытия обычно содержит ссылку, если в форме объекта 
    // был вызван метод Закрыть(Объект.Ссылка) или ОповеститьОВыборе(Объект.Ссылка)
    
    Если ЗначениеЗаполнено(РезультатЗакрытия) Тогда
        // Здесь мы наконец-то имеем ссылку и можем продолжать логику
        ПоказатьОповещениеПользователя("Успех", , "Создан элемент: " + РезультатЗакрытия);
        // Продолжаем выполнение алгоритма...
    КонецЕсли;
    
КонецПроцедуры

Решение 2: Предварительная генерация ссылки (Метод УстановитьСсылкуНового)

Иногда бизнес-логика требует, чтобы мы знали ссылку на объект еще до того, как форма будет открыта. Например, если нам нужно сразу передать эту ссылку в другие связанные структуры или подготовить файлы в хранилище, привязанные к этому ID. В 1С есть возможность сгенерировать уникальный идентификатор заранее.

Выясним, как реализовать этот метод:

  1. На сервере получаем новую пустую ссылку для нужного справочника с помощью метода ПолучитьСсылку() менеджера справочника.
  2. Передаем эту ссылку в форму нового элемента через параметры.
  3. В форме нового элемента в событии ПриСозданииНаСервере или в модуле объекта в ПередЗаписью вызываем метод УстановитьСсылкуНового().

Пример серверного кода для подготовки ссылки:


&НаСервереБезКонтекста
Функция ПодготовитьНовуюСсылку()
    НоваяСсылка = Справочники.КонтактнаяИнформация.ПолучитьСсылку(Новый УникальныйИдентификатор);
    Возврат НоваяСсылка;
КонецФункции

Теперь при открытии формы вы передаете эту ссылку. В самой форме анкеты нужно добавить обработку:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("ПредопределеннаяСсылка") Тогда
        ЭтотОбъект.УстановитьСсылкуНового(Параметры.ПредопределеннаяСсылка);
    КонецЕсли;
КонецПроцедуры

Важно: При таком подходе вызывающая функция сразу знает будущую ссылку, но объект физически появится в базе только после того, как пользователь нажмет «Записать».

Решение 3: Использование глобальных оповещений

Проанализируем ситуацию, когда пользователь может нажать «Записать» в форме справочника, но не закрывать её сразу. Если мы полагаемся только на ОписаниеОповещения при закрытии, наш алгоритм в основной форме не узнает о записи до момента закрытия окна. Чтобы сделать интерфейс более отзывчивым, используем метод Оповестить().

В модуле формы справочника (который мы открываем) добавим стандартный обработчик события ПослеЗаписи:


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    Оповестить("ЗаписанНовыйКонтакт", Объект.Ссылка, ЭтаФорма);
КонецПроцедуры

В основной форме (владельце) добавим обработчик события ОбработкаОповещения:


&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ЗаписанНовыйКонтакт" Тогда
        // Параметр содержит ссылку на созданный элемент
        СсылкаНаНовыйОбъект = Параметр;
        // Можем обновить данные на текущей форме, не дожидаясь закрытия справочника
    КонецЕсли;
КонецПроцедуры

Рекомендации по заполнению данных

В исходном вопросе автор пытался вручную копировать данные через КопироватьДанныеФормы. Рассмотрим более изящный способ — использование параметра ЗначенияЗаполнения. Когда вы передаете структуру в этот параметр при вызове ОткрытьФорму, платформа автоматически вызывает событие ОбработкаЗаполнения в модуле объекта справочника на сервере. Это позволяет избежать лишних вызовов &НаСервереБезКонтекста и делает код чище.

Пример правильной передачи параметров:


ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("МобильныйТелефон", Телефон);
ПараметрыЗаполнения.Вставить("Наименование", "Новый клиент");

ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);

ОткрытьФорму("Справочник.КонтактнаяИнформация.ФормаОбъекта", ПараметрыОткрытия, ЭтаФорма);

Резюме

Разберем основные выводы. Для получения ссылки на созданный элемент справочника в 1С 8.3 следует придерживаться следующих правил:

  1. Не пытайтесь получить ссылку сразу в коде после ОткрытьФорму — она будет пустой.
  2. Используйте ОписаниеОповещения для обработки результата закрытия формы.
  3. Если ссылка нужна мгновенно для связанных действий, используйте механизм УстановитьСсылкуНового.
  4. Для оперативного реагирования на запись (без закрытия формы) применяйте метод Оповестить.
  5. Всегда предпочитайте передачу данных через ЗначенияЗаполнения ручному копированию данных формы.

Эти подходы обеспечат стабильную работу вашего кода во всех типах клиентов (тонкий, веб, мобильный) и избавят от распространенных ошибок, связанных с асинхронностью платформы 1С:Предприятие.

← На главную