Как сохранить структуру в ХранилищеЗначения и прочитать её из константы в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке конфигураций и внешних обработок в 1С часто возникает необходимость сохранить произвольный набор параметров (например, настройки подключения к FTP, параметры авторизации или пользовательские фильтры) в единый реквизит или константу. Для этих целей платформа 1С предоставляет специальный объект ХранилищеЗначения. Разберем по шагам, как правильно упаковать структуру данных в хранилище, записать ее в константу, безопасно извлечь обратно и избежать распространенных ошибок контекста выполнения.

Помещение структуры в ХранилищеЗначения и запись в константу

Объект ХранилищеЗначения предназначен для хранения двоичных данных или сериализуемых объектов платформы в сжатом виде. Чтобы поместить произвольный набор реквизитов в константу с типом ХранилищеЗначения, сначала сформируем структуру, а затем передадим ее в конструктор хранилища.

Посмотрим на пример формирования структуры и записи в константу:


&НаСервере
Процедура СохранитьНастройкиВКонстантуНаСервере()

    // 1. Формируем структуру с необходимыми параметрами
    Настройки = Новый Структура();
    Настройки.Вставить("Путь",                 Объект.Путь);
    Настройки.Вставить("Порт",                 Объект.Порт);
    Настройки.Вставить("Пользователь",         Объект.Пользователь);
    Настройки.Вставить("Пароль",               Объект.Пароль);
    Настройки.Вставить("ПассивноеСоединение",  Объект.ПассивноеСоединение);
    Настройки.Вставить("ИмяФайла",             Объект.ИмяФайла);
    Настройки.Вставить("ВидДК",                Объект.ВидДК);

    // 2. Упаковываем структуру в ХранилищеЗначения со сжатием (уровень от 0 до 9)
    ХранилищеВКонстанту = Новый ХранилищеЗначения(Настройки, Новый СжатиеДанных(9));

    // 3. Записываем полученный объект в константу
    Константы.ПП_ПараметрыПодключенияКFTP.Установить(ХранилищеВКонстанту);

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

Параметр Новый СжатиеДанных(9) указывает степень компрессии данных (максимальное сжатие), что помогает экономить место в базе данных при хранении объемных массивов или таблиц.

Извлечение и чтение структуры из константы

Проанализируем процесс обратного чтения. Важно помнить, что обращение к константе через Константы.ИмяКонстанты.Получить() возвращает сам объект ХранилищеЗначения, а не исходную структуру. Чтобы добраться до самих данных, необходимо вызвать метод Получить() уже у самого объекта хранилища. Метода Прочитать() у объекта ХранилищеЗначения не существует.

Разберем пример корректного получения данных и заполнения реквизитов объекта:


&НаСервере
Процедура ЗагрузитьНастройкиИзКонстантыНаСервере()

    // 1. Получаем объект ХранилищеЗначения из константы
    ХранилищеИзКонстанты = Константы.ПП_ПараметрыПодключенияКFTP.Получить();

    // 2. Проверяем, что в константе действительно есть хранилище
    Если ХранилищеИзКонстанты = Неопределено Тогда
        ВызватьИсключение "Настройки подключения еще не были сохранены в константе.";
    КонецЕсли;

    // 3. Извлекаем исходную структуру методом Получить()
    Настройки = ХранилищеИзКонстанты.Получить();

    // 4. Проверяем тип извлеченных данных
    Если ТипЗнч(Настройки) = Тип("Структура") Тогда
        Объект.Путь                = Настройки.Путь;
        Объект.Порт                = Настройки.Порт;
        Объект.Пользователь        = Настройки.Пользователь;
        Объект.Пароль              = Настройки.Пароль;
        Объект.ПассивноеСоединение = Настройки.ПассивноеСоединение;
        Объект.ИмяФайла            = Настройки.ИмяФайла;
        Объект.ВидДК               = Настройки.ВидДК;
    Иначе
        Сообщить("Хранилище не содержит структуры параметров или повреждено.");
    КонецЕсли;

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

Устранение ошибки «Тип не определен (ХранилищеЗначения)»

Выясним причину частой ошибки начинающих разработчиков: {Форма(79,30)}: Тип не определен (ХранилищеЗначения) (Проверка: Тонкий клиент).

Типы ХранилищеЗначения, СжатиеДанных, а также менеджер Константы недоступны на тонком и веб-клиенте. Любые операции создания хранилища, обращения к константам и распаковки данных должны выполняться строго на стороне сервера (в процедурах или функциях с директивами компиляции &НаСервере или &НаСервереБезКонтекста), либо в толстом клиенте.

Пример правильной организации вызова из клиентского события формы:


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

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

Рекомендации по надежной работе с хранилищем

Рассмотрим несколько практических советов, которые помогут избежать ошибок при дальнейшей поддержке и обновлении конфигурации:

  1. Групповое заполнение свойств: Если имена ключей в структуре полностью совпадают с именами реквизитов формы или объекта, используйте встроенную процедуру ЗаполнитьЗначенияСвойств(Объект, Настройки) вместо построчного присваивания каждого реквизита.
  2. Безопасное чтение ключей: Если со временем состав структуры может измениться (добавятся новые параметры или удалятся старые), используйте метод Настройки.Свойство("ИмяКлюча", ПеременнаяПриемник), чтобы предотвратить аварийное завершение с ошибкой «Поле объекта не обнаружено».
  3. Ограничения типов: В ХранилищеЗначения можно помещать только сериализуемые типы данных (числа, строки, даты, ссылки, структуры, массивы, таблицы значений). Несериализуемые объекты (например, открытые COM-соединения или потоки файлов) поместить в хранилище невозможно.
  4. Альтернатива константам: Если вам требуется сохранять персональные настройки конкретных пользователей или обработок без добавления новых объектов метаданных, используйте системный механизм ХранилищеОбщихНастроек (методы Сохранить() и Загрузить()).
← На главную