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