Сохранение произвольных значений реквизитов объекта в реквизите формы

03.03.15

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

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

Скачать исходный код

Наименование Файл Версия Размер
ObjectPropertiesSave.epf
.epf 9,30Kb
11
.epf 1.01 9,30Kb 11 Скачать

Хотел написать много красивых и умных слов, но вместо этого решил перейти сразу к делу. По пунктам и коротко:

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

2. Подход к реализации:  Сохранение всех данных в реквизите управляемой формы типа "Список значений". Это удобно тем, что во-первых используется стандартное хранилище и стандартный механизм сохранения, а во-вторых из-за того, что процедуры обработки сохранения и восстановления настроек серверные и мы минимизируем клиентское взаимодействие со сложными типами данных, поддерживаемых не всеми клиентами, и легко добиваемся мультиклиентности.

3. Реализация: Реализация способа сохранения состоит из сохраняемого реквизита управляемой формы типа СписокЗначений с именем "СохраняемыеСвойстваОбъекта" и двух процедур: 1) для Сохранения/Восстановления значений и 2) редактирования списка сохраняемых реквизитов. Указанные процедуры вызываются из обработок стандартных событий формы "ПриСохраненииДанныхВНастройкахНаСервере" и "ПриЗагрузкеДанныхИзНастроекНаСервере" (для Сохранения/Восстановления) и произвольнымобразом для регулирования списка настроек (я добавил команду для командной панели формы). 

4. Конкретно инструкция:

а) Создаем для управляемой формы реквизит типа СписокЗначений с названием (в моем примере): "СохраняемыеСвойстваОбъекта".

б) Создаем кнопку с процедурой или команду для вызова процедуры "РедактироватьСписокСохраняемыхРеквизитов". В примере это команда формы "РедактироватьСохраняемыеРеквизиты". Размещаем кнопочку для вызова на форме или (как в примере) вызов команды из меню.

в) Инициируем стандартные обработчики событий формы "ПриСохраненииДанныхВНастройкахНаСервере" и "ПриЗагрузкеДанныхИзНастроекНаСервере"

пример

г) После всего вышеизложенного в модуль формы добавляем 2 процедуры: "РедактироватьСписокСохраняемыхРеквизитов" и "ОбработатьСохраняемыеРеквизитыОбъекта" и настраиваем вызов процедуры "ОбработатьСохраняемыеРеквизитыОбъекта" из стандартных обработчиков, а процедуры "РедактироватьСписокСохраняемыхРеквизитов" из специальной команды/процедуры связанной с элементом управления или пунктом меню формы. В качестве аргумента СохраняемыйСписокРеквизитФормы передается название списка значений с сохраняемыми настройками (в примере это "СохраняемыеСвойстваОбъекта", в общем случае - как назовете реквизит формы, так и передаете при вызове)

д) собственно пример текста модуля с командами и процедурами:

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

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

&НаСервере
Процедура ПриСохраненииДанныхВНастройкахНаСервере(Настройки)
	// Вставить содержимое обработчика.
	ОбработатьСохраняемыеРеквизитыОбъекта(Настройки, "СохраняемыеСвойстваОбъекта", Истина);
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеДанныхИзНастроекНаСервере(Настройки)
	// Вставить содержимое обработчика.
	ОбработатьСохраняемыеРеквизитыОбъекта(Настройки, "СохраняемыеСвойстваОбъекта", Ложь);	
КонецПроцедуры

&НаКлиенте
Процедура РедактироватьСохраняемыеРеквизиты(Команда)
	// Вставить содержимое обработчика.
	РедактироватьСписокСохраняемыхРеквизитов("СохраняемыеСвойстваОбъекта");
КонецПроцедуры

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

Реквизит объекта сохранение реквизитов реквизит формы настройки формы сохранение настроек

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2920    2    John_d    11    

56

GUID в 1С 8.3 - как с ними быть

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

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

12.02.2024    5171    atdonya    22    

52

Переоткрытие внешних обработок

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

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

30.11.2023    4136    ke.92@mail.ru    16    

62

Валидация JSON через XDTO (включая массивы)

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

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

28.08.2023    9517    YA_418728146    6    

143

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2285    26    progmaster    8    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16403    143    sapervodichka    112    

130

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

18.07.2022    7373    quazare    8    

110
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. u_n_k_n_o_w_n 34 04.03.15 12:24 Сейчас в теме
В описании немного слукавили: пишите через 2 функции - в действительности используете 5 процедур! За идею +!
2. dusha0020 1106 04.03.15 13:06 Сейчас в теме
(1) u_n_k_n_o_w_n, Есть и лукавство, конечно:)
Однако, рабочих процедур всего 2. Остальные 3 распределяют и направляют работу. Не исполнители, а, так сказать, руководители!
Оставьте свое сообщение