Как сохранить общие настройки внешней обработки для всех пользователей в обычном приложении 1С

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

При разработке внешних обработок для конфигураций на обычных формах (например, УПП 1.3, КА 1.1, ЗУП 2.5) разработчики часто сталкиваются с задачей: администратор должен один раз задать общие параметры работы (например, путь к сетевой папке обмена), а обычные пользователи без административных прав должны успешно считывать эту настройку. Попытка решить задачу через стандартные хранилища настроек с указанием фиксированного пользователя или через установку привилегированного режима часто приводит к ошибке Нарушение прав доступа!. Разберем подробнее, почему возникает эта ошибка и какие существуют проверенные способы решения без изменения метаданных конфигурации.

Почему возникает ошибка прав доступа и не работает привилегированный режим

Проанализируем типовую ситуацию: в модуле объекта обработки пишется код сохранения или чтения настройки под конкретным служебным пользователем:


УстановитьПривилегированныйРежим(Истина);
Результат = ХранилищеНастроекДанныхФорм.Загрузить(, ИмяНастройки, , "Автобот");
УстановитьПривилегированныйРежим(Ложь);

При выполнении этого фрагмента под учетной записью с ограниченными правами платформа выбрасывает исключение при вызове метода Загрузить. Выясним причину такого поведения платформы 1С:

  1. Контекст выполнения в обычном приложении: в толстом клиенте обычных форм код модуля объекта обработки по умолчанию исполняется на стороне клиента. Метод УстановитьПривилегированныйРежим имеет доступность «Сервер, внешнее соединение» (а также файловый вариант). При вызове на клиенте в клиент-серверной базе этот метод просто игнорируется платформой и не переключает права сеанса.
  2. Ограничения внешних обработок: внешняя обработка запускается в контексте текущего сеанса и не имеет собственных серверных общих привилегированных модулей. Выполнить код с игнорированием прав доступа из внешней обработки без обращения к уже существующим в конфигурации экспортным методам невозможно.
  3. Требования к правам при работе с хранилищами настроек: методы ХранилищеНастроекДанныхФорм и ХранилищеОбщихНастроек позволяют читать и перезаписывать настройки других пользователей (когда заполнен параметр ИмяПользователя) только при наличии роли с правом Администрирование данных или Администрирование. Если у пользователя такой роли нет, чтение настроек другого пользователя («Автобот») блокируется платформой на уровне прав доступа.

Вариант 1. Использование типового справочника «СохраненныеНастройки»

Рассмотрим самое надежное решение для классических конфигураций на обычных формах (УПП, Комплексная автоматизация, ЗУП). В этих конфигурациях присутствует встроенный справочник СохраненныеНастройки, на чтение и запись которого у базовой роли Пользователь обычно уже назначены необходимые права.

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


// Функция чтения общей настройки
Функция ПрочитатьОбщуюНастройку(ИмяПараметра) Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	Спр.ХранилищеНастроек КАК Данные
    |ИЗ
    |	Справочник.СохраненныеНастройки КАК Спр
    |ГДЕ
    |	Спр.Наименование = &Наименование
    |	И Спр.НастраиваемыйОбъект = &НастраиваемыйОбъект";
    
    Запрос.УстановитьПараметр("Наименование", ИмяПараметра);
    Запрос.УстановитьПараметр("НастраиваемыйОбъект", "МояВнешняяОбработка_ОбщиеПараметры");
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат Выборка.Данные.Получить();
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

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

Такой подход не требует вмешательства в конфигуратор, работает под любым пользователем и полностью изолирован внутри внешней обработки.

Вариант 2. Запись настроек администратором персонально каждому пользователю

Разберем еще один способ, при котором сохраняется работа со штатным механизмом ХранилищеОбщихНастроек или ХранилищеНастроекДанныхФорм, но исключается конфликт прав.

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


// Код выполняется под администратором при сохранении пути
Процедура СохранитьНастройкуДляВсехПользователей(ИмяНастройки, Значение)
    МассивПользователей = ПользователиИнформационнойБазы.ПолучитьПользователей();
    
    Для Каждого ПользовательИБ Из МассивПользователей Цикл
        // Администратор имеет право указывать имя пользователя
        ХранилищеОбщихНастроек.Сохранить("МояВнешняяОбработка", ИмяНастройки, Значение, , ПользовательИБ.Имя);
    КонецЦикла;
КонецПроцедуры

// Код чтения настройки рядовым пользователем при открытии обработки
Функция ЗагрузитьНастройкуТекущегоПользователя(ИмяНастройки)
    // Чтение настройки ТЕКУЩЕГО пользователя без передачи имени не требует прав администрирования
    Возврат ХранилищеОбщихНастроек.Загрузить("МояВнешняяОбработка", ИмяНастройки);
КонецФункции

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

Вариант 3. Использование общего файла конфигурации

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

  1. Администратор размещает в общедоступном сетевом каталоге файл конфигурации, например \\server\share\settings.json.
  2. В коде внешней обработки фиксируется сетевой путь к файлу.
  3. При открытии обработки выполняется чтение файла через ЧтениеТекста или ЧтениеJSON:

Функция ПрочитатьПутьИзСетевогоФайла(ПутьКФайлуКонфигурации)
    Файл = Новый Файл(ПутьКФайлуКонфигурации);
    Если Не Файл.Существует() Тогда
        Возврат "";
    КонецЕсли;
    
    Текст = Новый ЧтениеТекста(ПутьКФайлуКонфигурации, КодировкаТекста.UTF8);
    СтрокаНастройки = Текст.ПрочитатьСтроку();
    Текст.Закрыть();
    
    Возврат СокрЛП(СтрокаНастройки);
КонецФункции

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

← На главную