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

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

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

Анализ проблемы: почему данные не заполняются автоматически?

Часто программисты используют стандартный механизм передачи параметров через структуру ЗначенияЗаполнения. Код может выглядеть следующим образом:


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

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

Способ №1: Свойство реквизитов «Заполнение из данных заполнения»

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

  1. Откроем дерево метаданных и найдем целевой документ (в нашем примере — ПротоколПоЭБ).
  2. Перейдем к списку реквизитов.
  3. Для каждого реквизита, который мы передаем (КарточкаСлушателя, Дата), откроем палитру свойств.
  4. Найдем свойство «Заполнение из данных заполнения» (Fill from filling values) и установим для него флажок.

Если этот флажок не установлен, платформа просто игнорирует переданные значения при стандартном открытии формы. Проанализируем ситуацию: этот метод идеален для простых случаев, когда имена ключей в структуре точно совпадают с именами реквизитов документа.

Способ №2: Обработчик «ОбработкаЗаполнения» в модуле объекта

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

Рассмотрим пример кода в Модуле объекта документа ПротоколПоЭБ:


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

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

Способ №3: Передача произвольных параметров в форму

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

На стороне вызывающей формы:


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

На стороне вызываемой формы (в модуле формы документа ПротоколПоЭБ):


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

Важный нюанс: если вы устанавливаете дату документа в ПриСозданииНаСервере, помните, что платформа может попытаться перезаписать ее текущей датой, если это новый объект. Проверяйте свойство Параметры.Ключ.Пустая(), чтобы убедиться, что создается именно новый документ.

Способ №4: Использование механизма «Ввод на основании»

Если один документ логически всегда создается на основании другого (как ПротоколПоЭБ на основании РеестрПоЭБ), лучше всего использовать встроенный конструктор ввода на основании. Это позволит избежать написания лишнего кода и сделает систему более стандартной для пользователя.

  1. В конфигураторе у документа-приемника откройте вкладку «Ввод на основании».
  2. Добавьте документ-источник в список «Является основанием для».
  3. Нажмите кнопку «Конструктор заполнения» и сопоставьте поля.

После этого программный вызов станет максимально простым. Платформа сама упакует ссылку в параметр Основание:


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

Подведем итоги

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

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

← На главную