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

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

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

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

Использование обработчика «ОбработкаЗаполнения» в модуле объекта

Основным инструментом для решения подобных задач является событие ОбработкаЗаполнения, которое располагается в модуле объекта справочника. Этот обработчик вызывается платформой в момент создания нового объекта (но до момента открытия его формы).

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

Проанализируем пример кода, который позволяет подставить ВидНоменклатуры из родительской группы:


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

Разбор типичных ошибок и нюансов кода

При реализации этого кода начинающие разработчики часто сталкиваются с трудностями. Разберем наиболее важные моменты:

  1. Проверка на пустую ссылку. В языке 1С некорректно сравнивать ссылку с пустой строкой (Родитель <> ""). Для проверки того, выбрана ли группа, следует использовать универсальную функцию ЗначениеЗаполнено(). Это гарантирует правильную работу с любыми типами данных (ссылками, числами, датами).
  2. Избыточное обращение к базе данных. Использование конструкции ДанныеЗаполнения.Родитель.Ссылка.ВидНоменклатуры является избыточным. Поле Родитель в структуре уже является ссылкой, поэтому обращение к свойству .Ссылка создает лишнюю нагрузку и загромождает код. Достаточно написать ДанныеЗаполнения.Родитель.ВидНоменклатуры.
  3. Типизация параметра. Параметр ДанныеЗаполнения может принимать разные значения. Если объект создается на основании другого документа, туда придет ссылка на документ. Если просто командой «Создать» — значение может быть Неопределено. Поэтому всегда проверяйте тип: ТипЗнч(ДанныеЗаполнения) = Тип("Структура").

Критически важное свойство «Заполнять из данных заполнения»

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

Чтобы платформа «подхватила» программно заполненное значение и отобразила его в форме при создании, необходимо в конфигураторе зайти в свойства реквизита справочника (в нашем случае ВидНоменклатуры) и установить флаг «Заполнять из данных заполнения».

Что дает эта настройка:

Альтернативный способ: Заполнение через параметры формы

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

Рассмотрим пример кода для программного открытия формы нового элемента с предустановленным видом номенклатуры:


ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("ВидНоменклатуры", ПредопределенноеЗначение("Перечисление.ВидыНоменклатуры.Услуга"));
ПараметрыЗаполнения.Вставить("Родитель", СсылкаНаНужнуюГруппу);

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

ОткрытьФорму("Справочник.Номенклатура.ФормаОбъекта", ПараметрыФормы);

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

Особенности работы при копировании объектов

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

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


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

Однако стандартно при копировании 1С переносит все значения из ОбъектКопирования. Если вид номенклатуры у оригинала был верным, он и так перенесется в новый объект без дополнительного кода.

Резюме

Для корректного заполнения реквизита до открытия формы выполните следующие шаги:

  1. Убедитесь, что у реквизита в конфигураторе включено свойство «Заполнять из данных заполнения».
  2. В модуле объекта в процедуре ОбработкаЗаполнения реализуйте логику поиска родителя через структуру ДанныеЗаполнения.
  3. Используйте ЗначениеЗаполнено() для надежной проверки ссылок.
  4. При необходимости программного вызова используйте ключ ЗначенияЗаполнения в параметрах открытия формы.

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

← На главную