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