Каталог решений - Простой способ программно открыть заполненную форму нового (незаписанного) документа в тонком клиенте

Простой способ программно открыть заполненную форму нового (незаписанного) документа в тонком клиенте

Простой способ программно открыть заполненную форму нового (незаписанного) документа в тонком клиенте

В наличии

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

Категория:

Описание

Итак, сначала нам понадобится добавить немного кода в общие модули.

В серверный общий модуль (в моем примере его имя будет СерверныйОбщийМодуль) добавляем функцию СтруктураПоОбъектуМетаданных() и процедуру ЗаполнитьОбъектИзСтруктурыВоВременномХранилище()

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

	Для Каждого Реквизит Из ОбъектМетаданных.СтандартныеРеквизиты Цикл
		Результат.Вставить(Реквизит.Имя);
	КонецЦикла;

	Для Каждого Реквизит Из ОбъектМетаданных.Реквизиты Цикл
		Результат.Вставить(Реквизит.Имя);
	КонецЦикла;

	Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
		ЭлементСоставаОбщегоРеквизита = ОбщийРеквизит.Состав.Найти(ОбъектМетаданных);
		Если ЭлементСоставаОбщегоРеквизита <> Неопределено И СтрСравнить(Строка(ЭлементСоставаОбщегоРеквизита.Использование), "Использовать") = 0 Тогда
			Результат.Вставить(ОбщийРеквизит.Имя);
		КонецЕсли;
	КонецЦикла;
	
	Для Каждого ТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
		ТЧ = Новый ТаблицаЗначений;
		Для Каждого РеквизитТЧ Из ТабличнаяЧасть.Реквизиты Цикл
			ТЧ.Колонки.Добавить(РеквизитТЧ.Имя);
		КонецЦикла;
		Результат.Вставить(ТабличнаяЧасть.Имя, ТЧ);
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

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

Далее, там где мы хотим открыть форму незаписанного документа с уже заполненными данными пишем


&НаКлиенте
Процедура СоздатьЗаполнитьИОткрытьНовыйДокумент()

	АдресХранилища = СоздатьНовыйДокументНаСервере();
	
	ПараметрыОткрытия = Новый Структура("Основание", АдресХранилища);
	ОткрытьФорму("Документ.РасходныйОрдер.ФормаОбъекта", ПараметрыОткрытия, ЭтаФорма, УникальныйИдентификатор);

КонецПроцедуры

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

Теперь нам нужно чтобы в обработке заполнения открываемого документа вызвалась процедура ЗаполнитьОбъектИзСтруктурыВоВременномХранилище(). Проще всего сделать, это создав подписку на событие ОбработкаЗаполнения. В эту подписку включаем все нужные нам документы (те документы, которые мы хотим открывать и заполнять). В качестве обработчика подписки на событие указываем процедуру ЗаполнитьОбъектИзСтруктурыВоВременномХранилище(). Либо можно непосредственно в процедуре ОбработкаЗаполнения() вызвать СерверныйОбщийМодуль.ЗаполнитьОбъектИзСтруктурыВоВременномХранилище(). 

Вот собственно и все, процедура и функция в общем модуле универсальные и подойдут для любого типа документа/справочника. Добавим их один раз, можно будет открывать подобным образом любой документ/справочник (не забывая включить его в подписку на событие).

has been added to your cart:
Оформление заказа