При разработке конфигураций и внешних обработок в 1С часто возникает необходимость сохранить произвольный набор параметров (например, настройки подключения к FTP, параметры авторизации или пользовательские фильтры) в единый реквизит или константу. Для этих целей платформа 1С предоставляет специальный объект ХранилищеЗначения. Разберем по шагам, как правильно упаковать структуру данных в хранилище, записать ее в константу, безопасно извлечь обратно и избежать распространенных ошибок контекста выполнения.
Объект ХранилищеЗначения предназначен для хранения двоичных данных или сериализуемых объектов платформы в сжатом виде. Чтобы поместить произвольный набор реквизитов в константу с типом ХранилищеЗначения, сначала сформируем структуру, а затем передадим ее в конструктор хранилища.
Посмотрим на пример формирования структуры и записи в константу:
&НаСервере
Процедура СохранитьНастройкиВКонстантуНаСервере()
// 1. Формируем структуру с необходимыми параметрами
Настройки = Новый Структура();
Настройки.Вставить("Путь", Объект.Путь);
Настройки.Вставить("Порт", Объект.Порт);
Настройки.Вставить("Пользователь", Объект.Пользователь);
Настройки.Вставить("Пароль", Объект.Пароль);
Настройки.Вставить("ПассивноеСоединение", Объект.ПассивноеСоединение);
Настройки.Вставить("ИмяФайла", Объект.ИмяФайла);
Настройки.Вставить("ВидДК", Объект.ВидДК);
// 2. Упаковываем структуру в ХранилищеЗначения со сжатием (уровень от 0 до 9)
ХранилищеВКонстанту = Новый ХранилищеЗначения(Настройки, Новый СжатиеДанных(9));
// 3. Записываем полученный объект в константу
Константы.ПП_ПараметрыПодключенияКFTP.Установить(ХранилищеВКонстанту);
КонецПроцедуры
Параметр Новый СжатиеДанных(9) указывает степень компрессии данных (максимальное сжатие), что помогает экономить место в базе данных при хранении объемных массивов или таблиц.
Проанализируем процесс обратного чтения. Важно помнить, что обращение к константе через Константы.ИмяКонстанты.Получить() возвращает сам объект ХранилищеЗначения, а не исходную структуру. Чтобы добраться до самих данных, необходимо вызвать метод Получить() уже у самого объекта хранилища. Метода Прочитать() у объекта ХранилищеЗначения не существует.
Разберем пример корректного получения данных и заполнения реквизитов объекта:
&НаСервере
Процедура ЗагрузитьНастройкиИзКонстантыНаСервере()
// 1. Получаем объект ХранилищеЗначения из константы
ХранилищеИзКонстанты = Константы.ПП_ПараметрыПодключенияКFTP.Получить();
// 2. Проверяем, что в константе действительно есть хранилище
Если ХранилищеИзКонстанты = Неопределено Тогда
ВызватьИсключение "Настройки подключения еще не были сохранены в константе.";
КонецЕсли;
// 3. Извлекаем исходную структуру методом Получить()
Настройки = ХранилищеИзКонстанты.Получить();
// 4. Проверяем тип извлеченных данных
Если ТипЗнч(Настройки) = Тип("Структура") Тогда
Объект.Путь = Настройки.Путь;
Объект.Порт = Настройки.Порт;
Объект.Пользователь = Настройки.Пользователь;
Объект.Пароль = Настройки.Пароль;
Объект.ПассивноеСоединение = Настройки.ПассивноеСоединение;
Объект.ИмяФайла = Настройки.ИмяФайла;
Объект.ВидДК = Настройки.ВидДК;
Иначе
Сообщить("Хранилище не содержит структуры параметров или повреждено.");
КонецЕсли;
КонецПроцедуры
Выясним причину частой ошибки начинающих разработчиков: {Форма(79,30)}: Тип не определен (ХранилищеЗначения) (Проверка: Тонкий клиент).
Типы ХранилищеЗначения, СжатиеДанных, а также менеджер Константы недоступны на тонком и веб-клиенте. Любые операции создания хранилища, обращения к константам и распаковки данных должны выполняться строго на стороне сервера (в процедурах или функциях с директивами компиляции &НаСервере или &НаСервереБезКонтекста), либо в толстом клиенте.
Пример правильной организации вызова из клиентского события формы:
&НаКлиенте
Процедура ЗагрузитьНастройки(Команда)
ЗагрузитьНастройкиНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗагрузитьНастройкиНаСервере()
Хранилище = Константы.ПП_ПараметрыПодключенияКFTP.Получить();
Если Хранилище <> Неопределено Тогда
Настройки = Хранилище.Получить();
Если ТипЗнч(Настройки) = Тип("Структура") Тогда
// Заполняем реквизиты формы или объекта
ЗаполнитьЗначенияСвойств(Объект, Настройки);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Рассмотрим несколько практических советов, которые помогут избежать ошибок при дальнейшей поддержке и обновлении конфигурации:
ЗаполнитьЗначенияСвойств(Объект, Настройки) вместо построчного присваивания каждого реквизита.Настройки.Свойство("ИмяКлюча", ПеременнаяПриемник), чтобы предотвратить аварийное завершение с ошибкой «Поле объекта не обнаружено».ХранилищеЗначения можно помещать только сериализуемые типы данных (числа, строки, даты, ссылки, структуры, массивы, таблицы значений). Несериализуемые объекты (например, открытые COM-соединения или потоки файлов) поместить в хранилище невозможно.ХранилищеОбщихНастроек (методы Сохранить() и Загрузить()).