Представление настроек программы в 1С. Один из способов

от автора


Здравствуйте.
В данной статье я хочу рассказать о своем опыте работы с настройками в 1С – их представлении и сохранении. Этот способ особенно актуален для внешних обработок и отчетов, которые либо не завязаны на конкретную конфигурацию, либо просто не хотят хранить свои настройки в каких-либо объектах конфигурации. Никаких особых технических открытий предлагаемый способ не содержит, просто он делает более переносимым и упорядоченным применение стандартных решений – вся нудная и кропотливая работа может быть проделана единожды, а затем полученный шаблон можно с минимальными изменениями использовать во всех своих проектах. Суть метода как раз в этом.

Просматривая в Интернете различные примеры программ на 1С (исходники), я часто отмечал, что подход к работе с настройками в большинстве случаев достаточно небрежен. Стандартные подпрограммы (СохранитьЗначение, ВосстановитьЗначение) используются повсеместно в коде и никак не сгруппированы. Для каждого сохраняемого значения создается отдельный идентификатор в базе (строковый параметр вышеуказанных подпрограмм), даже если таких значений сотни. Особенно показательно выглядит реализация какого-либо диалогового окна с массовым редактированием значений настроек. Длинная вереница вызовов (ВосстановитьЗначение, СохранитьЗначение) при открытии и закрытии такого окна соответственно. Такой подход в принципе понятен – в первую очередь разработчики сосредотачиваются на решении конкретной задачи, времени как всегда нет, и работа с настройками воспринимается примерно также, как работа с обычными арифметическими выражениями – эти вызовы вставляются в код по мере необходимости. Конечно, если разработчика это не напрягает, то кому какое дело. Однако в тех случаях, когда в программе происходит массовая переделка – не просто нужно добавить еще несколько десятков значений в настройки (что в большинстве случаев и делается), а еще и удалить что-то, у некоторых параметров поменять значения (тип значений), да и просто обнулить значения параметров (в целях тестирования например) – выполнить такие действия с кучей отдельных параметров становится малореальным – проще забить и выполнять всё тестирование в голове, а не под отладчиком.

А что если один единственный раз создать инструмент для работы с настройками – универсальный и переносимый? Так, чтобы его можно было легко, не задумываясь копировать между своими программами (ну естественно изменяя собственно сам набор конкретных параметров). Попробуем…

В реализации будем использовать описанный ранее технический прием «самодельного ООП в 1С». Создадим в виде отдельного класса хранилище настроек программы (если нужно как-то обособить группы настроек, то программа может иметь несколько таких классов-хранилищ). Стандартные вызовы (ВосстановитьЗначение, СохранитьЗначение) будет использоваться один раз за всю программу, т.к. все содержимое нашего хранилища будет сериализовано в XML-формат. Таким образом, можно обеспечить представление разветвленной структуры, а не просто «плоский набор» значений (по типу INI-файлов). В нашем примере, однако, будем рассматривать тот самый «плоский набор» для упрощения, т.к. структура набора принципиального значения не имеет.

К примеру, пусть у нас имеется следующий набор параметров:

Название Тип Начальное значение
Парам1 Число 0
Парам2 Строка «»
Парам3 СправочникСсылка.Номенклатура Неопределено
Парам4 Булево Ложь
Парам5 Дата Неопределено

Условно рассматриваем только простейшие типы, чтобы не привязываться ни к каким конкретным конфигурациям. Но также рассмотрим и ссылочный тип (Справочник «Номенклатура» есть во многих типовых конфигурациях), чтобы показать идею сериализации в строку и восстановления из строки более сложного объекта.

Структура полей класса будет выглядеть следующим образом:

Функция НастрПрогр_СоздатьОбъект()  	НастрПрогр = Новый Структура; 	НастрПрогр.Вставить("ChangeInfo", Ложь);     // Признак наличия несохраненных изменений в наборе 	НастрПрогр.Вставить("ErrMsg", "");           // Сообщение о последней ошибке 	// Общие параметры, хранящиеся в настройках 	НастрПрогр.Вставить("Set_Парам1", Неопределено); // Параметр настроек 1 	НастрПрогр.Вставить("Set_Парам2", Неопределено); // Параметр настроек 2 	НастрПрогр.Вставить("Set_Парам3", Неопределено); // Параметр настроек 3 	НастрПрогр.Вставить("Set_Парам4", Неопределено); // Параметр настроек 4 	НастрПрогр.Вставить("Set_Парам5", Неопределено); // Параметр настроек 5  	Возврат НастрПрогр;  КонецФункции 

Как видим, кроме непосредственно целевых параметров, в составе класса есть и служебные поля. Целевые поля имеют специальное соглашение в наименовании – начинаются с префикса «Set_». Это нужно, для того чтобы автоматически отличать целевые поля от служебных при обходе полей структуры (имитирующей объект класса) в цикле. Снаружи эти изменения в именах не видны и используются обычные названия параметров (без префикса «Set_»).

Теперь приведем код данного класса полностью:

Класс НастройкиПрограммы

//////////////////////////////////////////////////////////////////////////////// // Реализация класса НастройкиПрограммы (НастрПрогр)  // Создание полей объекта в виде структуры // // Параметры: //  Нет. // Возврат: //  Возвращает созданную структуру // Функция НастрПрогр_СоздатьОбъект() Экспорт 	 	НастрПрогр = Новый Структура; 	НастрПрогр.Вставить("ChangeInfo", Ложь);     // Признак наличия несохраненных изменений в наборе 	НастрПрогр.Вставить("ErrMsg", "");           // Сообщение о последней ошибке 	// Общие параметры, хранящиеся в настройках 	НастрПрогр.Вставить("Set_Парам1", Неопределено); // Параметр настроек 1 	НастрПрогр.Вставить("Set_Парам2", Неопределено); // Параметр настроек 2 	НастрПрогр.Вставить("Set_Парам3", Неопределено); // Параметр настроек 3 	НастрПрогр.Вставить("Set_Парам4", Неопределено); // Параметр настроек 4 	НастрПрогр.Вставить("Set_Парам5", Неопределено); // Параметр настроек 5  	Возврат НастрПрогр; 	 КонецФункции  // Имитирует конструктор объекта // // Параметры: //  Нет. // Возврат: //  (Структура) - Структура с полями объекта // Функция НастрПрогр_Конструктор() Экспорт 	 	НастрПрогр = НастрПрогр_СоздатьОбъект(); 	// Инициализируем поля объекта 	НастрПрогр_SetDefAttr(НастрПрогр); 	 	Возврат НастрПрогр; 	 КонецФункции  // Имитирует деструктор объекта - освобождает память // // Параметры: //  НастрПрогр - ссылка на объект // Процедура НастрПрогр_Деструктор(НастрПрогр) Экспорт 	 	 КонецПроцедуры  // Инициализирует атрибуты объекта значениями по умолчанию. // // Параметры: //  НастрПрогр - ссылка на объект // Процедура НастрПрогр_SetDefAttr(НастрПрогр) Экспорт 	 	НастрПрогр.ErrMsg = ""; 	НастрПрогр.Set_Парам1 = 0; 	НастрПрогр.Set_Парам2 = ""; 	НастрПрогр.Set_Парам3 = Неопределено; 	НастрПрогр.Set_Парам4 = Ложь; 	НастрПрогр.Set_Парам5 = Неопределено; 	 КонецПроцедуры  // Копирует значения полей объекта НастрПрогр2 в текущий НастрПрогр1. // Все предыдущие значения из НастрПрогр1 будут утеряны. // // Параметры: //  НастрПрогр1 - ссылка на объект //  НастрПрогр2 - ссылка на другой копируемый объект // Процедура НастрПрогр_Assign(НастрПрогр1, НастрПрогр2) Экспорт 	 	Если (НастрПрогр1 <> Неопределено) И 		 (НастрПрогр2 <> Неопределено) И 		 (НастрПрогр_IsEqual(НастрПрогр1, НастрПрогр2) = Ложь) Тогда 		Для Каждого Поле Из НастрПрогр1 Цикл 			Если Найти(Поле.Ключ, "Set_") = 1 Тогда 				// Копируем только значения полей параметров (не служебные поля) 				НастрПрогр1[Поле.Ключ] = НастрПрогр2[Поле.Ключ] 			КонецЕсли 		КонецЦикла;			 		НастрПрогр1.ChangeInfo = Истина 	КонецЕсли 	  КонецПроцедуры  // Сравнивает два набора параметров между собой. // // Параметры: //  НастрПрогр1 - ссылка на объект //  НастрПрогр2 - ссылка на другой сравниваемый объект // Возврат //  Истина, если объект НастрПрогр2 содержит теже данные, что и //  текущий НастрПрогр1 и Ложь - в противном случае // Функция НастрПрогр_IsEqual(НастрПрогр1, НастрПрогр2) Экспорт 	 	Рез = Ложь; 	 	Если (НастрПрогр1 <> Неопределено) И 		 (НастрПрогр2 <> Неопределено) Тогда 		ФлагСравн = Истина; 		Для Каждого Поле Из НастрПрогр1 Цикл 			Если Найти(Поле.Ключ, "Set_") = 1 Тогда 				// Сравниваем только значения полей параметров (не служебные поля) 				Если Поле.Значение <> НастрПрогр2[Поле.Ключ] Тогда 					ФлагСравн = Ложь; 					Прервать 				КонецЕсли 			КонецЕсли 		КонецЦикла; 		Рез = ФлагСравн 	КонецЕсли; 	 	Возврат Рез 	 КонецФункции  // Инициализирует атрибуты объекта значениями по умолчанию. // // Параметры: //  НастрПрогр - ссылка на объект // Функция НастрПрогр_GetErrorMsg(НастрПрогр) Экспорт 	 	Возврат НастрПрогр.ErrMsg 	 КонецФункции  // Возвращает значение параметра в наборе. // // Параметры: //  НастрПрогр - ссылка на объект //  PrmName - название параметра // Возврат //  Значение параметра PrmName или Неопределено, если такой параметр не найден // Функция НастрПрогр_GetPrm(НастрПрогр, PrmName) Экспорт 	 	Рез = Неопределено; 	НастрПрогр.ErrMsg = ""; 	 	Попытка 		Рез = НастрПрогр["Set_" + PrmName]; 	Исключение 		НастрПрогр.ErrMsg = "НастрПрогр_GetPrm: Не найден параметр: " + PrmName; 	КонецПопытки; 	 	Возврат Рез 	 КонецФункции  // Устанавливает значение параметра в наборе. // // Параметры: //  НастрПрогр - ссылка на объект //  PrmName - название параметра //  PrmVal - устанавливаемое значение параметра // Процедура НастрПрогр_SetPrm(НастрПрогр, PrmName, PrmVal) Экспорт 	 	НастрПрогр.ErrMsg = ""; 	 	Попытка 		Если НастрПрогр["Set_" + PrmName] <> PrmVal Тогда 			НастрПрогр["Set_" + PrmName] = PrmVal; 			НастрПрогр.ChangeInfo = Истина 		КонецЕсли 	Исключение 		НастрПрогр.ErrMsg = "НастрПрогр_SetPrm: Не найден параметр: " + PrmName; 	КонецПопытки 	 КонецПроцедуры  // Возвращает строковое значение указанного параметра (предварительно преобразуется в строку). // // Параметры: //  НастрПрогр - ссылка на объект //  PrmName - название параметра // Возврат //  Строковое значение параметра PrmName или Неопределено, если такой параметр не найден // Функция НастрПрогр_GetPrmStrVal(НастрПрогр, PrmName) Экспорт 	 	Рез = Неопределено; 	НастрПрогр.ErrMsg = ""; 	 	Попытка 		ИсхЗнач = НастрПрогр["Set_" + PrmName]; 		// Преобразование в зависимости от типа параметра 		Если PrmName = "Парам1" Тогда 			// Параметр настроек №1 (Число) 			Рез = Формат(ИсхЗнач, "ЧГ=0; ЧН=''") 		ИначеЕсли PrmName = "Парам2" Тогда 			// Параметр настроек №2 (Строка) 			Рез = ИсхЗнач 		ИначеЕсли PrmName = "Парам3" Тогда 			// Параметр настроек №3 (СправочникСсылка.Номенклатура) 			Если ЗначениеЗаполнено(ИсхЗнач) Тогда 				Рез = ИсхЗнач.Код 			Иначе 				Рез = Неопределено 			КонецЕсли 		ИначеЕсли PrmName = "Парам4" Тогда 			// Параметр настроек №4 (Булево) 			Рез = Формат(ИсхЗнач, "БЛ=0; БИ=1") 		ИначеЕсли PrmName = "Парам5" Тогда 			// Параметр настроек №5 (Дата) 			Рез = Формат(ИсхЗнач, "ДФ=""yyyyMMddHHmmss""") 		КонецЕсли 	Исключение 		НастрПрогр.ErrMsg = "НастрПрогр_GetPrmStrVal: Ошибка сериализации значения: " + PrmName + " : " + ИнформацияОбОшибке().Описание; 	КонецПопытки; 	 	Возврат Рез 	 КонецФункции  // Устанавливает значение параметра в наборе из переданного строкового значения // (предварительно идет преобразование из строкового значения в нужное). // // Параметры: //  НастрПрогр - ссылка на объект //  PrmName - название параметра //  StrPrmVal - строковое представление устанавливаемого значения параметра // Процедура НастрПрогр_SetPrmFromStrVal(НастрПрогр, PrmName, StrPrmVal) Экспорт 	 	НастрПрогр.ErrMsg = ""; 	 	Попытка 		НовЗнач = Неопределено; 		// Преобразование в зависимости от типа параметра 		Если PrmName = "Парам1" Тогда 			// Параметр настроек №1 (Число) 			НовЗнач = Число(StrPrmVal) 		ИначеЕсли PrmName = "Парам2" Тогда 			// Параметр настроек №2 (Строка) 			НовЗнач = StrPrmVal 		ИначеЕсли PrmName = "Парам3" Тогда 			// Параметр настроек №3 (СправочникСсылка.Номенклатура) 			Если ЗначениеЗаполнено(StrPrmVal) Тогда 				НовЗнач = Справочники.Номенклатура.НайтиПоКоду(StrPrmVal); 				Если НЕ ЗначениеЗаполнено(НовЗнач) Тогда 					НовЗнач = Неопределено 				КонецЕсли 			КонецЕсли 		ИначеЕсли PrmName = "Парам4" Тогда 			// Параметр настроек №4 (Булево) 			НовЗнач = Булево(Число(StrPrmVal)) 		ИначеЕсли PrmName = "Парам5" Тогда 			// Параметр настроек №5 (Дата) 			НовЗнач = Дата(StrPrmVal) 		КонецЕсли; 		// Установка значения 		Если НастрПрогр["Set_" + PrmName] <> НовЗнач Тогда 			НастрПрогр["Set_" + PrmName] = НовЗнач; 			НастрПрогр.ChangeInfo = Истина 		КонецЕсли 	Исключение 		НастрПрогр.ErrMsg = "НастрПрогр_SetPrmFromStrVal: Ошибка установки значения: " + PrmName + " : " + ИнформацияОбОшибке().Описание; 	КонецПопытки 	 КонецПроцедуры  // Возвращает признак наличия несохраненных изменений // в наборе параметров // // Параметры: //  НастрПрогр - ссылка на объект // Возврат //  Значение признака несохраненных изменений // Функция НастрПрогр_GetChangeInfo(НастрПрогр) Экспорт 	 	Возврат НастрПрогр.ChangeInfo 	 КонецФункции  // Принудительно устанавливает значение признака наличия несохраненных // изменений в наборе параметров // // Параметры: //  НастрПрогр - ссылка на объект //  ChangeInfo - значение признака несохраненных изменений // Процедура НастрПрогр_SetChangeInfo(НастрПрогр, ChangeInfo) Экспорт 	 	НастрПрогр.ChangeInfo = ChangeInfo 	 КонецПроцедуры  // Загружает структуру из XML-документа, размещенного в объекте ЧтениеXML. // // Параметры: //  НастрПрогр - ссылка на объект //  ЧтениеXML - объект для чтения XML-документа // Возврат //  Истина, если загрузка прошла удачно и Ложь - в противном случае // Функция НастрПрогр_LoadSettingsFromXML(НастрПрогр, ЧтениеXML) Экспорт 	 	Рез = Ложь;  // Еще ничего загрузить не успели 	НастрПрогр.ErrMsg = ""; 	 	Если ЧтениеXML <> Неопределено Тогда 		Попытка 			// Начальная инициализация 			НастрПрогр_SetDefAttr(НастрПрогр); 			 			// Процесс загрузки 			Началась_settings = Ложь; 			НазвПрм = ""; 			Пока ЧтениеXML.Прочитать() Цикл 				Если ЧтениеXML.ЛокальноеИмя = "settings" Тогда 					Если (Началась_settings = Ложь) И 						 (ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента) Тогда 						// Началась секция с набором параметров 						Началась_settings = Истина 					Иначе 						// Закончилась секция с набором параметров 						Началась_settings = Ложь; 						НазвПрм = ""; 						Прервать 					КонецЕсли 				Иначе 					Если Началась_settings Тогда 						// Если находимся в наборе параметров 						Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда 							// Пробуем загрузить очередной параметр 							НазвПрм = ЧтениеXML.ЛокальноеИмя; 						ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда 							Если (НазвПрм <> "") И (НастрПрогр.Свойство("Set_" + НазвПрм)) Тогда 								НастрПрогр_SetPrmFromStrVal(НастрПрогр, НазвПрм, ЧтениеXML.Значение); 							КонецЕсли 						ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда 							НазвПрм = "" 						КонецЕсли 					КонецЕсли 				КонецЕсли 			КонецЦикла; 			// Окончание загрузки 			Если НастрПрогр.ErrMsg = "" Тогда 				НастрПрогр.ChangeInfo = Ложь;  // Нет несохраненных изменений 				Рез = Истина  // Загрузка прошла успешно 			КонецЕсли 		Исключение 			// Ошибка при чтении XML 			НастрПрогр.ErrMsg = "НастрПрогр_LoadSettingsFromXML: " + ИнформацияОбОшибке().Описание; 		КонецПопытки 	Иначе 		// Неверно переданы параметры 		НастрПрогр.ErrMsg = "НастрПрогр_LoadSettingsFromXML: Неверно переданы параметры"; 	КонецЕсли; 			 	Возврат Рез 	 КонецФункции  // Сохраняет структуру в XML-документ, пользуясь объектом ЗаписьXML. // // Параметры: //  НастрПрогр - ссылка на объект //  ЗаписьXML - объект для записи XML-документа // Возврат //  Истина, если сохранение прошло удачно и Ложь - в противном случае // Функция НастрПрогр_SaveSettingsToXML(НастрПрогр, ЗаписьXML) Экспорт 	 	Рез = Ложь;  // Еще ничего сохранить не успели 	НастрПрогр.ErrMsg = ""; 	 	Если ЗаписьXML <> Неопределено Тогда 		Попытка 			// Процесс сохранения 			ЗаписьXML.ЗаписатьОбъявлениеXML(); 			ЗаписьXML.ЗаписатьНачалоЭлемента("settings"); 			// Выгрузить каждый параметр 			Для Каждого Item Из НастрПрогр Цикл 				Если Найти(Item.Ключ, "Set_") = 1 Тогда 					НазвПрм = Сред(Item.Ключ, 5); 					Если НазвПрм <> "" Тогда 						ЗаписьXML.ЗаписатьНачалоЭлемента(НазвПрм); 						ЗаписьXML.ЗаписатьТекст(Строка(НастрПрогр_GetPrmStrVal(НастрПрогр, НазвПрм))); 						ЗаписьXML.ЗаписатьКонецЭлемента()  // параметр 					КонецЕсли 				КонецЕсли 			КонецЦикла; 			// Завершение формирования XML-документа 			ЗаписьXML.ЗаписатьКонецЭлемента();  // settings 			 			Если НастрПрогр.ErrMsg = "" Тогда 				НастрПрогр.ChangeInfo = Ложь;  // Нет несохраненных изменений 				Рез = Истина  // Сохранение прошло успешно 			КонецЕсли 		Исключение 			// Ошибка при записи XML 			НастрПрогр.ErrMsg = "НастрПрогр_SaveSettingsToXML: " + ИнформацияОбОшибке().Описание; 		КонецПопытки 	Иначе 		// Неверно переданы параметры 		НастрПрогр.ErrMsg = "НастрПрогр_SaveSettingsToXML: Неверно переданы параметры"; 	КонецЕсли; 			 	Возврат Рез 	 КонецФункции  // Загружает структуру из XML-документа, размещенного в строке XMLStr. // // Параметры: //  НастрПрогр - ссылка на объект //  XMLStr - строка с XML-документом // Возврат //  Истина, если загрузка прошла удачно и Ложь - в противном случае // Функция НастрПрогр_LoadSettingsFromXMLStr(НастрПрогр, XMLStr) Экспорт 	 	Рез = Ложь;  // Еще ничего загрузить не успели 	НастрПрогр.ErrMsg = ""; 	 	Если (XMLStr <> Неопределено) И (XMLStr <> "") Тогда 		Попытка 			ЧтениеXML = Новый ЧтениеXML(); 			ЧтениеXML.УстановитьСтроку(XMLStr); 			// Выполнить основные операции 			Рез = НастрПрогр_LoadSettingsFromXML(НастрПрогр, ЧтениеXML); 		Исключение 			// Ошибка при чтении XML 			НастрПрогр.ErrMsg = "НастрПрогр_LoadSettingsFromXMLStr: " + ИнформацияОбОшибке().Описание; 		КонецПопытки 	Иначе 		// Неверно переданы параметры 		НастрПрогр.ErrMsg = "НастрПрогр_LoadSettingsFromXMLStr: Неверно переданы параметры"; 	КонецЕсли; 			 	Возврат Рез 	 КонецФункции  // Сохраняет структуру в XML-документ, в строку XMLStr. // // Параметры: //  НастрПрогр - ссылка на объект //  XMLStr - строка, куда помещается XML-документ // Возврат //  Истина, если сохранение прошло удачно и Ложь - в противном случае // Функция НастрПрогр_SaveSettingsToXMLStr(НастрПрогр, XMLStr) Экспорт 	 	Рез = Ложь;  // Еще ничего сохранить не успели 	НастрПрогр.ErrMsg = ""; 	 	Попытка 		ЗаписьXML = Новый ЗаписьXML(); 		ЗаписьXML.УстановитьСтроку(); 		// Выполнить основные операции 		Рез = НастрПрогр_SaveSettingsToXML(НастрПрогр, ЗаписьXML); 		// Возврат XML-документа в текстовой строке 		Если Рез Тогда 			XMLStr = ЗаписьXML.Закрыть(); 		КонецЕсли 	Исключение 		// Ошибка при записи XML 		НастрПрогр.ErrMsg = "НастрПрогр_SaveSettingsToXMLStr: " + ИнформацияОбОшибке().Описание; 	КонецПопытки; 			 	Возврат Рез 	 КонецФункции  // Загружает структуру из XML-файла FName. // // Параметры: //  НастрПрогр - ссылка на объект //  FName - название файла с XML-документом // Возврат //  Истина, если загрузка прошла удачно и Ложь - в противном случае // Функция НастрПрогр_LoadSettingsFromFile(НастрПрогр, Знач FName) Экспорт 	 	Рез = Ложь;  // Еще ничего загрузить не успели 	НастрПрогр.ErrMsg = ""; 	 	Если (FName <> Неопределено) И (FName <> "") Тогда 		Попытка 			ЧтениеXML = Новый ЧтениеXML(); 			ЧтениеXML.ОткрытьФайл(FName); 			// Выполнить основные операции 			Рез = НастрПрогр_LoadSettingsFromXML(НастрПрогр, ЧтениеXML); 		Исключение 			// Ошибка при чтении XML 			НастрПрогр.ErrMsg = "НастрПрогр_LoadSettingsFromFile:" + ИнформацияОбОшибке().Описание; 		КонецПопытки 	Иначе 		// Неверно переданы параметры 		НастрПрогр.ErrMsg = "НастрПрогр_LoadSettingsFromFile: Неверно переданы параметры"; 	КонецЕсли; 			 	Возврат Рез 	 КонецФункции  // Сохраняет структуру в XML-документ, в файл FName. // // Параметры: //  НастрПрогр - ссылка на объект //  FName - название файла, куда помещается XML-документ // Возврат //  Истина, если сохранение прошло удачно и Ложь - в противном случае // Функция НастрПрогр_SaveSettingsToFile(НастрПрогр, Знач FName) Экспорт 	 	Рез = Ложь;  // Еще ничего сохранить не успели 	НастрПрогр.ErrMsg = ""; 	 	Если (FName <> Неопределено) И (FName <> "") Тогда 		Попытка 			ПараметрыЗаписиXML = Новый ПараметрыЗаписиXML("windows-1251",,,, "  "); 			ЗаписьXML = Новый ЗаписьXML(); 			ЗаписьXML.ОткрытьФайл(FName, ПараметрыЗаписиXML); 			// Выполнить основные операции 			Рез = НастрПрогр_SaveSettingsToXML(НастрПрогр, ЗаписьXML); 			// Закрытие файла 			ЗаписьXML.Закрыть(); 		Исключение 			// Ошибка при записи XML 			НастрПрогр.ErrMsg = "НастрПрогр_SaveSettingsToFile: " + ИнформацияОбОшибке().Описание; 		КонецПопытки 	Иначе 		// Неверно переданы параметры 		НастрПрогр.ErrMsg = "НастрПрогр_SaveSettingsToFile: Неверно переданы параметры"; 	КонецЕсли; 			 	Возврат Рез 	 КонецФункции 

Естественно, что для получения и установки значений параметров нужно использовать подпрограммы «НастрПрогр_GetPrm» и «НастрПрогр_SetPrm» соответственно. Просто так присваивать значения элементам структуры, имитирующей класс, нельзя.

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

Использование данного хранилища настроек выглядит следующим образом:

// Процедура - обработчик события "При открытии" формы. Данное событие // возникает при открытии формы до показа окна пользователю. // // Параметры: //  Нет. // Процедура ПриОткрытии()  	// Загрузить настройки программы 	НастрПрогр = НастрПрогр_Конструктор(); 	XMLStr = ВосстановитьЗначение("ТестоваяОбработка_НастройкиПрограммы"); 	Если XMLStr <> Неопределено Тогда 		НастрПрогр_LoadSettingsFromXMLStr(НастрПрогр, XMLStr) 	КонецЕсли; 	 КонецПроцедуры  // Процедура - обработчик события "При закрытии" формы. Данное событие // возникает после закрытия формы. // Освобождение занятых ресурсов. // // Параметры: //  Нет. // Процедура ПриЗакрытии()  	// Сохранить настройки программы 	Если НастрПрогр_GetChangeInfo(НастрПрогр) Тогда 		XMLStr = ""; 		НастрПрогр_SaveSettingsToXMLStr(НастрПрогр, XMLStr); 		СохранитьЗначение("ТестоваяОбработка_НастройкиПрограммы", XMLStr); 	КонецЕсли; 	НастрПрогр_Деструктор(НастрПрогр); 	 КонецПроцедуры  // Процедура - обработчик события "Нажатие" кнопки КнопкаВыводЗначений. // Выводит текущие значения набора параметров. // // Параметры: //  Элемент - элемент формы - кнопка // Процедура КнопкаВыводЗначенийНабораНажатие(Элемент)  	Сообщить("Параметр1 = " + НастрПрогр_GetPrm(НастрПрогр, "Парам1")); 	Сообщить("Параметр2 = " + НастрПрогр_GetPrm(НастрПрогр, "Парам2")); 	Сообщить("Параметр3 = " + НастрПрогр_GetPrm(НастрПрогр, "Парам3")); 	Сообщить("Параметр4 = " + НастрПрогр_GetPrm(НастрПрогр, "Парам4")); 	Сообщить("Параметр5 = " + НастрПрогр_GetPrm(НастрПрогр, "Парам5")); 	 КонецПроцедуры 

Теперь разберем код диалогового окна для редактирования набора настроек. Для нашего демонстрационного набора параметров оно будет выглядеть примерно так:

Разместим на форме соответствующие элементы управления для отображения и редактирования параметров. Создадим у формы реквизиты – для каждого параметра отдельный, и привяжем к ним элементы управления. Обмен данными уже будем вести между хранилищем настроек (объектом класса НастрПрогр) и этими реквизитами.
Исходный код модуля этой формы будет следующим:

Код модуля ФормаНастройкиПараметров

//////////////////////////////////////////////////////////////////////////////// // ДИАЛОГ НАСТРОЙКИ ПАРАМЕТРОВ ПРОГРАММЫ  Перем НастрПрогр;   // Объект с настройками программы   //////////////////////////////////////////////////////////////////////////////// // ОБРАБОТЧИКИ СОБЫТИЙ ФОРМЫ  // Процедура - обработчик события "При открытии" формы. Данное событие // возникает при открытии формы до показа окна пользователю. // // Параметры: //  Нет. // Процедура ПриОткрытии()  	// Перевести фокус на начальное поле ввода 	ТекущийЭлемент = ЭлементыФормы.ПолеВводаПараметр1 	 КонецПроцедуры  // Процедура - обработчик события "Нажатие" кнопки КнопкаOK. // Попытка закрытия диалога с применением настроек. // // Параметры: //  Элемент - кнопка // Процедура ОсновныеДействияФормыКнопкаОК(Кнопка) 	 	Если CheckInput() Тогда 		ЭтаФорма.Закрыть(КодВозвратаДиалога.ОК) 	КонецЕсли 	 КонецПроцедуры   //////////////////////////////////////////////////////////////////////////////// // ВСПОМОГАТЕЛЬНЫЕ ПОДПРОГРАММЫ  // Считывает параметры из полей ввода формы и проверяет параметры на корректность. // // Параметры: //  Нет // Возврат: //  Истина, если параметры заданы корректно и Ложь - в противном случае // Функция CheckInput() 	 	Рез = Ложь; 	ErrMsg = ""; 	 	// Здесь можно выполнить какие-то проверки 	// ******************************** 	 	// Анализируем результат проверки полей ввода 	Если ErrMsg = "" Тогда 		// Все параметры корректны 		ReadSettingsFromInterf();  // Считать из интерфейса сделанные настройки 		Рез = Истина 	Иначе 		Предупреждение(ErrMsg) 	КонецЕсли;  	Возврат Рез 	 КонецФункции  // Загружает все настройки в интерфейс. // // Параметры: //  Нет // Процедура LoadSettingsToInterf() 	 	Если НастрПрогр <> Неопределено Тогда 		// Установить значения 		Парам1 = НастрПрогр_GetPrm(НастрПрогр, "Парам1"); 		Парам2 = НастрПрогр_GetPrm(НастрПрогр, "Парам2"); 		Парам3 = НастрПрогр_GetPrm(НастрПрогр, "Парам3"); 		Парам4 = НастрПрогр_GetPrm(НастрПрогр, "Парам4"); 		Парам5 = НастрПрогр_GetPrm(НастрПрогр, "Парам5"); 	КонецЕсли 	 КонецПроцедуры  // Считать все настройки из интерфейса. // // Параметры: //  Нет // Процедура ReadSettingsFromInterf() 	 	Если НастрПрогр <> Неопределено Тогда 		// Считать значения 		НастрПрогр_SetPrm(НастрПрогр, "Парам1", Парам1); 		НастрПрогр_SetPrm(НастрПрогр, "Парам2", Парам2); 		Если ЗначениеЗаполнено(Парам3) Тогда 			НастрПрогр_SetPrm(НастрПрогр, "Парам3", Парам3) 		Иначе 			НастрПрогр_SetPrm(НастрПрогр, "Парам3", Неопределено) 		КонецЕсли; 		НастрПрогр_SetPrm(НастрПрогр, "Парам4", Парам4); 		НастрПрогр_SetPrm(НастрПрогр, "Парам5", Парам5); 	КонецЕсли 	 КонецПроцедуры   //////////////////////////////////////////////////////////////////////////////// // ПОДПРОГРАММЫ ВНЕШНЕГО ИНТЕРФЕЙСА  // Вызов диалога настройки параметров программы с сохранением их // в наборе НастройкиПрограммы. // // Параметры: //  НастройкиПрограммы - набор настроек программы. // Возврат: //  Истина, если изменения выполнены удачно и применены и Ложь, если пользователь отказался //  вносить изменения // Функция SetMainSettingsDlg(НастройкиПрограммы) Экспорт 	 	Рез = Ложь;  // Еще ничего не настроили 	 	Если НастройкиПрограммы <> Неопределено Тогда 		// Считать имеющиеся настройки 		НастрПрогр = НастройкиПрограммы; 		// Загрузить в интерфейс имеющиеся настройки 		LoadSettingsToInterf(); 		// Вызвать диалог 		Если ЭтаФорма.ОткрытьМодально() = КодВозвратаДиалога.ОК Тогда 			// Параметры установлены корректно 			 			Рез = Истина 		КонецЕсли 	КонецЕсли; 	 	Возврат Рез 	 КонецФункции 

А вот так используется это диалоговое окно (из окна главной формы):

// Процедура - обработчик события "Нажатие" кнопки КнопкаДиалогНастроек. // Вызывает диалог установки основных настроек обработки. // // Параметры: //  Элемент - элемент формы - кнопка // Процедура КнопкаДиалогНастроекНажатие(Элемент) 	 	// Создаем временный набор настроек 	ВремНастрПрогр = НастрПрогр_Конструктор(); 	НастрПрогр_Assign(ВремНастрПрогр, НастрПрогр); 	НастрПрогр_SetChangeInfo(ВремНастрПрогр, Ложь); 	// Вызываем диалог ввода настроек 	ФормаНастройкиПараметров = ЭтотОбъект.ПолучитьФорму("ФормаНастройкиПараметров", ЭтаФорма); 	Если ФормаНастройкиПараметров.SetMainSettingsDlg(ВремНастрПрогр) Тогда 		// Параметры изменены 		Если НЕ НастрПрогр_IsEqual(НастрПрогр, ВремНастрПрогр) Тогда 			// Сохранить настройки в основной набор 			НастрПрогр_Assign(НастрПрогр, ВремНастрПрогр); 		КонецЕсли 	КонецЕсли; 	НастрПрогр_Деструктор(ВремНастрПрогр) 	 КонецПроцедуры 

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

Функция НастрПрогр_СоздатьОбъект() Процедура НастрПрогр_SetDefAttr(НастрПрогр) Функция НастрПрогр_GetPrmStrVal(НастрПрогр, PrmName)  Процедура НастрПрогр_SetPrmFromStrVal(НастрПрогр, PrmName, StrPrmVal) 

Скачать исходные тексты рассмотренных программ (обработка для 1С 8.2) можно здесь.

На этом все. Всем удачи. До встречи.

ссылка на оригинал статьи http://habrahabr.ru/post/272455/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *