Заполнение значениями по умолчанию для документов и справочников (универсальный механизм)

10.07.15

Разработка - Универсальные функции

В данном материале рассматривается процесс разработки механизма заполнения документов и справочников по шаблону.
Материал большой, букв много, так что не судите строго. :)
Данный механизм подойдет как для типовых конфигураций, так и для отраслевых и самописных.
В типовых конфигурациях есть некоторые алгоритмы заполнения предопределенными значениями при создании нового документа или справочника (например, организация по умолчанию, склад по умолчанию), и т.п.
Но что если в поступлении нам надо подставлять один склад, в реализации - другой, а в самописном документе - третий? Именно такую механику предусматривает данный механизм.
Он не претендует на полноценное решение, но может стать хорошей основой для дальнейшей разработки.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Конфигурация Заполнение по шаблонам
.cf 29,31Kb
14
14 Скачать (1 SM) Купить за 1 850 руб.

В типовых конфигурациях (например, УТ 10.3, УПП, Комплексная автоматизация) механизм значений по умолчанию основан на плане видов характеристик  НастройкиПользователей и связанном с ним регистре.

Однажды в одной светлой голове возникла мысль - а почему бы не сделать свои значения по умолчанию для каждого документа или справочника? И процесс пошел.

Рецепт не такой уж и сложный. Судите сами.

Нам понадобятся:

Общий неглобальный модуль  - 1 шт. (Я создал новый и назвал ПодпискиНаСобытия, вы можете использовать любой удобный)

Подписки на события ОбработкаЗаполнения- 2 шт. Одна - на документы, одна - на справочники.

Регистр сведений - 1 шт.

Я назвал его ПользовательскиеШаблоныЗаполнения (или как вам угодно назвать).

Измерения:

Пользователь - справочник Пользователи

Настройка - Строка, 255 знаков (В большинстве случаев должно хватать)

Ресурсы:

Значение - ХранилищеЗначения

Реквизиты:

ВидНастройки - Строка, 20  (В нашем примере там будет всегда записано либо слово "Справочники" либо "Документы")

Все просто. Мы заполняем реквизиты шапки нужными нам значениями, записываем в храилище значения, и при создании нового документа или справочника подставляем их.

Но дьявол, как известно, кроется в деталях.

Для начала разберемся с формой записи нашего регистра.

Прежде всего, поясню, почему вид настройки и настройка были выбраны в виде строки. Это сделано с целью обращения к метаданным через квадратные скобки - т.е. из конструкции Метаданные[ВидНастройки][Настройка] мы получим например

Метаданные.Справочники.Номенклатура или Метаданные.Документа.РеализацияТоваровУслуг.

 

Чтобы все работало корректно, нам понадобится немного докрутить поведение элементов управления.

ВидНастройки мы представим в виде переключателя, и укажем список выбора с двумя значениями "Документы" и "Справочники"

Поле Настройка заполним программно:

&НаСервере
Процедура ЗаполнитьПоМетаданнымНаСервере(ВидНастройки)
	
	Элементы.Настройка.СписокВыбора.Очистить();
	ТЗМетаданных.Очистить();
	ПредставлениеНастройки = "";
	ТаблицаШаблонаЗаполнения.Очистить();
	
	Для Каждого ВидМетаданных Из Метаданные[ВидНастройки] Цикл
		
		Элементы.Настройка.СписокВыбора.Добавить(ВидМетаданных.Синоним);
		СтрТЗ = ТЗМетаданных.Добавить();
		СтрТЗ.Имя = ВидМетаданных.Имя;
		СтрТЗ.Синоним = ВидМетаданных.Синоним;
	КонецЦикла;
	
КонецПроцедуры

ТЗМетаданных - это таблица значений, которую мы используем для сопоставления имени и синонима метаданных, чтобы пользователь выбирал привычные "Договоры контрагентов", а в настройку записывался идентификатор ДоговорыКонтрагентов.

На форму мы вынесем реквизит ПредставлениеНастройки, и при его изменении будем менять настройку.

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

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

 

&НаСервере
Процедура НастройкаПриИзмененииНаСервере()
	
	ОбъектМетаданных = Метаданные[Запись.ВидНастройки][Запись.Настройка];
	ТаблицаШаблонаЗаполнения.Очистить();
	Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты цикл
		
		ЭтоНужныйТип = Ложь;
		Для Каждого МетаТип Из МетаРеквизит.Тип.типы() Цикл
			ЭтоСправочник = Справочники.ТипВсеСсылки().СодержитТип(МетаТип);
			ЭтоДокумент = Документы.ТипВсеСсылки().СодержитТип(МетаТип);
			ЭтоПеречисление = Перечисления.ТипВсеСсылки().СодержитТип(МетаТип);
			
			Если ЭтоСправочник ИЛИ ЭтоДокумент ИЛИ ЭтоПеречисление Тогда
				СтрТЗ = ТаблицаШаблонаЗаполнения.Добавить();
				СтрТЗ.Поле = МетаРеквизит.Имя;
				СтрТЗ.ПредставлениеПоля = МетаРеквизит.Синоним;
				СтрТЗ.Значение = Новый (МетаТип);
				Прервать;
			КонецЕсли;
		КонецЦикла;	
		
	КонецЦикла;
	
КонецПроцедуры

И при записи мы помещаем заполненный шаблон в хранилище:

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
	
	ТекущийОбъект.Значение = Новый ХранилищеЗначения(ТаблицаШаблонаЗаполнения.Выгрузить());
	
КонецПроцедуры

Полный листинг всего модуля формы я приведу в конце материала.

 

С формой разобрались, осталось совсем чуть-чуть.

 

У нас есть две подписки на события. В первой тип источника указываем "ДокументСсылка", во второй "СправочикСсылка".

 

В общем модуле пишем обработчик:

Процедура РС_ЗаполнениеСправочниковИзНастроекПользователя(Источник, ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка) Экспорт
	
	Если ДанныеЗаполнения = Неопределено Тогда
		ДанныеЗаполнения = Новый Структура;
	КонецЕсли;
	
	Запрос = Новый Запрос("ВЫБРАТЬ
	|	РС_НастройкиПользователей.Пользователь,
	|	РС_НастройкиПользователей.Настройка,
	|	РС_НастройкиПользователей.Значение,
	|	РС_НастройкиПользователей.ВидНастройки
	|ИЗ
	|	РегистрСведений.РС_НастройкиПользователей КАК РС_НастройкиПользователей
	|ГДЕ
	|	РС_НастройкиПользователей.Пользователь = &Пользователь
	|	И РС_НастройкиПользователей.Настройка = &Настройка
	|	И РС_НастройкиПользователей.ВидНастройки = &ВидНастройки");
	Запрос.УстановитьПараметр("Пользователь", ПользователиКлиентСервер.АвторизованныйПользователь());
	Запрос.УстановитьПараметр("Настройка", Источник.Метаданные().Имя);
	Запрос.УстановитьПараметр("ВидНастройки", "Справочники");
						  
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Хранилище = Выборка.Значение;
		ТаблицаШаблонаЗаполнения = Хранилище.Получить();
		Для Каждого СтрокаШаблона Из ТаблицаШаблонаЗаполнения Цикл
			Если ЗначениеЗаполнено(СтрокаШаблона.Значение) Тогда
				ДанныеЗаполнения.Вставить(СтрокаШаблона.Поле, СтрокаШаблона.Значение);
				Если Метаданные.Справочники[Источник.Метаданные().Имя].Реквизиты[СтрокаШаблона.Поле].ЗаполнятьИзДанныхЗаполнения Тогда
					ДанныеЗаполнения.Вставить(СтрокаШаблона.Поле, СтрокаШаблона.Значение);
				Иначе
					Источник[СтрокаШаблона.Поле] = СтрокаШаблона.Значение;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

 

Вот здесь-то нам и пригодятся наши строковые реквизиты "Настройка" и "ВидНастройки".

 

На этом все.

 

P.S.:

Как и обещал, листинг модуля формы записи регистра сведений.

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

&НаСервере
Процедура НастройкаПриИзмененииНаСервере()
	
	ОбъектМетаданных = Метаданные[Запись.ВидНастройки][Запись.Настройка];
	ТаблицаШаблонаЗаполнения.Очистить();
	Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты цикл
		
		ЭтоНужныйТип = Ложь;
		Для Каждого МетаТип Из МетаРеквизит.Тип.типы() Цикл
			ЭтоСправочник = Справочники.ТипВсеСсылки().СодержитТип(МетаТип);
			ЭтоДокумент = Документы.ТипВсеСсылки().СодержитТип(МетаТип);
			ЭтоПеречисление = Перечисления.ТипВсеСсылки().СодержитТип(МетаТип);
			
			Если ЭтоСправочник ИЛИ ЭтоДокумент ИЛИ ЭтоПеречисление Тогда
				СтрТЗ = ТаблицаШаблонаЗаполнения.Добавить();
				СтрТЗ.Поле = МетаРеквизит.Имя;
				СтрТЗ.ПредставлениеПоля = МетаРеквизит.Синоним;
				СтрТЗ.Значение = Новый (МетаТип);
				Прервать;
			КонецЕсли;
		КонецЦикла;	
		
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Если Не ЗначениеЗаполнено(Запись.ВидНастройки) Тогда
		Запись.ВидНастройки = "Документы";
		ЗаполнитьПоМетаданнымНаСервере(Запись.ВидНастройки);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПоМетаданнымНаСервере(ВидНастройки)
	
	Элементы.Настройка.СписокВыбора.Очистить();
	ТЗМетаданных.Очистить();
	ПредставлениеНастройки = "";
	ТаблицаШаблонаЗаполнения.Очистить();
	
	Для Каждого ВидМетаданных Из Метаданные[ВидНастройки] Цикл
		
		Элементы.Настройка.СписокВыбора.Добавить(ВидМетаданных.Синоним);
		СтрТЗ = ТЗМетаданных.Добавить();
		СтрТЗ.Имя = ВидМетаданных.Имя;
		СтрТЗ.Синоним = ВидМетаданных.Синоним;
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ВидНастройкиПриИзменении(Элемент)
	
	ЗаполнитьПоМетаданнымНаСервере(Запись.ВидНастройки);

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

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
	
	ТекущийОбъект.Значение = Новый ХранилищеЗначения(ТаблицаШаблонаЗаполнения.Выгрузить());
	
КонецПроцедуры

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	//Вставить содержимое обработчика
	Если Не ЗначениеЗаполнено(Параметры.Ключ.Пользователь) Тогда
		Запись.Пользователь = ПользователиКлиентСервер.АвторизованныйПользователь();
	КонецЕсли;
	Если Не Пользователи.ЭтоПолноправныйПользователь() Тогда
		Элементы.Пользователь.ТолькоПросмотр = Истина;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
	
	Запрос = Новый Запрос("ВЫБРАТЬ
	|	РС_НастройкиПользователей.Пользователь,
	|	РС_НастройкиПользователей.Настройка,
	|	РС_НастройкиПользователей.Значение,
	|	РС_НастройкиПользователей.ВидНастройки
	|ИЗ
	|	РегистрСведений.РС_НастройкиПользователей КАК РС_НастройкиПользователей");
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		ХЗ = Выборка.Значение;
		ТЗ = ХЗ.Получить();
	КонецЦикла;
	ХЗ = ТекущийОбъект.Значение;
	ТЗ = ХЗ.Получить();
	ТаблицаШаблонаЗаполнения.Загрузить(ТЗ);
	Попытка
		Для Каждого ВидМетаданных Из Метаданные[Запись.ВидНастройки] Цикл
			
			Элементы.Настройка.СписокВыбора.Добавить(ВидМетаданных.Синоним);
			СтрТЗ = ТЗМетаданных.Добавить();
			СтрТЗ.Имя = ВидМетаданных.Имя;
			СтрТЗ.Синоним = ВидМетаданных.Синоним;
		КонецЦикла;
		
		ПредставлениеНастройки = Метаданные[Запись.ВидНастройки][Запись.Настройка].Синоним;
		
	Исключение
	КонецПопытки;
	
КонецПроцедуры
 

Всем спасибо за потраченное время! Буду рад любой критике и комментариям.

Универсальная обработка заполнение по шаблону заполнение реквизитов заполнение по умолчанию обработка заполнения

См. также

Механизмы типовых конфигураций Программист Платформа 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Расчет себестоимости в типовых конфигурациях 1С – для многих «черный ящик», работающий по жестко зашитым в него алгоритмам. Реализация этого «черного ящика» может меняться в зависимости от конкретной конфигурации – УПП, БП 3.0, ERP. Но принцип работы везде одинаковый. Расскажем о том, как устроен расчет себестоимости, как его дорабатывать, и какие методы могут быть эффективны и без доработок.

27.12.2024    12759    Begemoth80    32    

87

Универсальные функции Программист Платформа 1С v8.3 1C:Бухгалтерия Бесплатно (free)

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

21.05.2024    28406    dimanich70    83    

151

Универсальные функции Программист Стажер Платформа 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    30388    atdonya    25    

59

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Программист Стажер Платформа 1С v8.3 1С:Бухгалтерия 3.0 Бесплатно (free)

Используются для создания новых объектов в конфигурации, чтобы не забыть, что нужно сделать. Сделано на примере 1С:Бухгалтерия предприятия, в других конфигурациях могут быть другие, а могут быть и похожие объекты.

28.12.2023    7467    mrXoxot    11    

113

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    6354    ke.92@mail.ru    17    

66

Механизмы типовых конфигураций Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Россия Управленческий учет Бесплатно (free)

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

08.11.2023    15776    ids79    26    

84
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. aspirator23 340 06.06.15 15:43 Сейчас в теме
Вроде бы и ничего гениального, но в практике пригодится.
Оставьте свое сообщение