Здравствуйте.
В данной статье я хочу рассказать о своем опыте работы с настройками в 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) можно здесь.
На этом все. Всем удачи. До встречи.
Комментарии (2)
Melex
05.12.2015 16:43+3Хорошо, что появляются такого рода статьи, но лучше — если на профильном сайте, там вам хоть подскажут как сделать все правильней.
Ну например — там можно почитать про то, что такое сериализация и десериализация, и убрать половину вашего кода. Ну и многое всякое другое. Красиво оформленный код с комментариями из серии Читаем xml файл, и использование Попытки там, где надо получать свойство структуры…
Это даже не смешно, увы :(
JetMaster