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

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

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

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

---

Метод 1. Использование штатного механизма платформы (Для записанных объектов)

Если элемент справочника уже сохранен в базе данных, платформа «1С:Предприятие 8» способна самостоятельно и без единой строчки кода заполнить измерение новой записи регистра. Для реализации этого поведения должны быть выполнены два простых условия в конфигураторе.

Шаг 1. Настройка отбора в динамическом списке на форме

Связь между справочником и списком регистра должна быть жестко определена через отбор. Для этого перейдем в свойства динамического списка на форме элемента справочника и настроим элемент отбора:

Шаг 2. Настройка свойств измерения регистра сведений

Теперь откроем свойства самого регистра сведений в дереве метаданных конфигуратора. Перейдем на вкладку «Данные», выделим нужное измерение (ссылающееся на наш справочник) и настроим его свойства:

Если эти условия выполнены, при нажатии на кнопку «Создать» в динамическом списке платформа перехватит установленный отбор по Объект.Ссылка и автоматически подставит его в открывшуюся форму записи регистра.

---

Метод 2. Использование механизма «УстановитьСсылкуНового()» и его подводные камни

Что делать, если пользователь только что нажал кнопку «Создать» в самом справочнике, форма открыта, но элемент еще ни разу не записывался в базу данных? В этот момент физической ссылки в базе данных еще не существует (Объект.Ссылка пуста).

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

Рассмотрим код, который генерирует GUID и назначает его еще не созданному объекту:


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

ВНИМАНИЕ: Почему этот метод использовать НЕ РЕКОМЕНДУЕТСЯ?

Несмотря на кажущуюся элегантность решения без предварительного сохранения, данный метод содержит критический недостаток, нарушающий ссылочную целостность базы данных:

Представим ситуацию: пользователь создает элемент справочника, переходит к списку регистра, нажимает «Создать». Благодаря методу УстановитьСсылкуНового(), форма записи регистра успешно открывается и в нее подставляется сгенерированная ссылка. Пользователь записывает строку регистра сведений, а затем... передумывает заполнять карточку основного справочника и просто закрывает форму элемента без сохранения.

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

---

Метод 3. Лучшие практики разработки (Best Practices)

Чтобы избежать появления битых ссылок и сделать поведение системы предсказуемым и безопасным, в типовых конфигурациях 1С (таких как ERP, КА, УТ) применяется подход с обязательной предварительной записью основного объекта.

Рассмотрим, как правильно реализовать данный механизм с использованием асинхронных вызовов в управляемых формах.

Вариант А. Блокировка добавления с интерактивным предложением записать объект

Мы перехватим событие таблицы динамического списка ПередНачаломДобавления на клиенте. Если объект справочника еще не записан, мы отменим стандартное создание записи и предложим пользователю автоматически сохранить элемент.


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

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

Вариант Б. Ручное программное открытие формы записи регистра

Для завершения реализации Варианта А нам необходимо программно открыть форму записи регистра сведений и передать туда параметры заполнения. Этот же метод применим, если ваш динамический список построен на базе сложного произвольного запроса и штатное автозаполнение по отборам платформы не отрабатывает.

Добавим в модуль формы элемента справочника вспомогательную процедуру открытия формы записи:


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

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

← На главную