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

Если конфигурация типовая, то, наверное, самый простой способ решения такой задачи – создать внешнюю обработку вида "Заполнение объекта".

Заполнение формы объекта с помощью внешней обработки

Строка с соответствующим параметром в модуле обработки:

ПараметрыРегистрации.Вставить("Вид", "ЗаполнениеОбъекта");

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

  • ВызовСерверногоМетода – обработчик команды располагается в модуле обработки;
  • ВызовКлиентскогоМетода – обработчик команды располагается в модуле формы обработки;
  • ЗаполнениеФормы – обработчик команды располагается в модуле обработки и позволяет работать с данными формы. Также позволяет вызвать серверную процедуру из модуля формы объекта. При этом можно заполнить форму не записывая объект.

Возможность заполнить форму не записывая объект – это то, что нужно. Ведь пользователь скорее всего ожидает, что по нажатию кнопки форма заполнится, а записываться будет позднее, после проверки результата заполнения. Поэтому выбираем тип команды – ЗаполнениеФормы.

В конечном итоге код в модуле обработки будет выглядеть примерно так:

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


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


Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры


// Обработчик команды
Процедура ВыполнитьКоманду(ИмяКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
	
	 Форма = ПараметрыВыполнения.ЭтаФорма; //Данные формы доступны через ПараметрыВыполнения
	 
	 Форма.Объект.Поставщик = // ... Заполняем нужные реквизиты.
	 
	 Форма.Модифицированность = Истина;
	
КонецПроцедуры

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

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

Заполнение формы объекта посредством обработчика команды в модуле формы

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

Над серверной процедурой нужно подумать. В ней у нас будет объект формы с типом "ДанныеФормыСтуктура". Что-либо менять или заполнять в этом объекте не получится, возникнет ошибка "Объект недоступен для изменения".

Можно получить объект документа Объект.Ссылка.ПолучитьОбъект() , и заполнить его данными. Но тогда, чтобы увидеть данные в открытой форме, объект придётся записать, а это не очень хорошо.

Будет лучше, если данные добавятся без записи, и мы можем это сделать с помощью метода РеквизитФормыВЗначение. Этот метод преобразует реквизит формы в объект прикладного типа, и вот этот объект прикладного типа мы можем заполнить, а затем, уже заполненный, преобразовать обратно с помощью метода ЗначениеВРеквизитФормы. Выглядеть это будет примерно так:

&НаКлиенте
Процедура ЗаполнитьФормуДокумента(Команда)
		
	ЗаполнитьФормуДокументаНаСервере();
	
	ОбновитьОтображениеДанных();
	
КонецПроцедуры


&НаСервере
Процедура ЗаполнитьФормуДокументаНаСервере()
	
	ДокументОбъект = РеквизитФормыВЗначение("Объект");
	
	ТЧ_Товары = ДокументОбъект.Товары; // Табличная часть Товары
	ТЧ_Товары.Очистить();
	
	Запрос = Новый Запрос;
	Запрос.Текст = //Текст запроса
	;
	
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	
	Пока Выборка.Следующий() Цикл
		
		СтрТЧ = ТЧ_Товары.Добавить();
		ЗаполнитьЗначенияСвойств(СтрТЧ, Выборка);
				
	КонецЦикла;
	
	ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
	
	Модифицированность = Истина;
	
КонецПроцедуры

Вот теперь и форма заполнена, и кнопка команды там, где хочется.