Как запретить интерактивное изменение документов, сохранив возможность их программного создания в 1С

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

В практике разработки на платформе 1С:Предприятие 8 часто возникает специфическая задача: необходимо предоставить пользователю строго ограниченный интерфейс для ввода данных. Типичный сценарий — создание специальной «виртуальной» формы или мастера, где пользователь заполняет необходимые поля и нажимает кнопку «Сформировать». После этого система должна программно создать документ, но сам пользователь не должен иметь возможности зайти в этот документ через стандартный список и что-то там исправить. При попытке стандартного изменения или создания документа напрямую система должна выдавать отказ.

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

Метод 1: Использование привилегированного общего модуля

Проанализируем наиболее надежный и архитектурно правильный способ — перенос логики записи документа в привилегированную среду. В 1С существует понятие привилегированного модуля. Код, исполняемый в таком модуле, игнорирует проверку прав доступа текущего пользователя. Это идеальное решение для нашей задачи.

Разберем по шагам, как это реализовать:

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

Посмотрим на пример кода в общем модуле:


Процедура СоздатьДокументПрограммно(СтруктураДанных) Экспорт
    // Код выполняется без проверки прав текущего пользователя
    НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
    НовыйДок.Дата = ТекущаяДата();
    // Заполнение реквизитов из структуры
    ЗаполнитьЗначенияСвойств(НовыйДок, СтруктураДанных);
    
    // Даже если у пользователя нет прав на "Изменение", 
    // этот вызов сработает успешно из-за привилегированности модуля
    НовыйДок.Записать(РежимЗаписиДокумента.Запись);
КонецПроцедуры

Теперь в вашей произвольной форме достаточно вызвать эту процедуру, и документ будет создан, несмотря на то, что в роли пользователя права на интерактивное создание сняты.

Метод 2: Использование ДополнительныхСвойств объекта

Выясним причину, почему иногда метод с привилегированным модулем кажется избыточным, и рассмотрим альтернативу. Если вы хотите оставить права на Изменение в роли (например, чтобы работали какие-то другие механизмы), но запретить именно ручную правку, можно использовать структуру ДополнительныеСвойств.

Этот способ позволяет пометить объект флагом «Я создаюсь программно из правильной формы». В модуле объекта документа мы будем проверять этот флаг.

Шаг 1. В вашей обработке или произвольной форме, где происходит создание документа, пишем следующий код:


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

Шаг 2. В модуле объекта самого документа (например, ЗаказПокупателя) в обработчике ПередЗаписью добавим проверку:


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

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

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

Метод 3: Блокировка на уровне интерфейса (Обычные формы, УПП 1.3)

Рассмотрим ситуацию, когда права у пользователя все же есть (для программной работы), но нам нужно «связать ему руки» в самом интерфейсе. В УПП 1.3 на обычных формах это делается через обработку события ПриОткрытии.

Проанализируем, как ограничить доступ к полям:


Процедура ПриОткрытии()
    // Проверяем условия блокировки
    Если НЕ ЭтоНовый() И НЕ РольДоступна("ПолныеПрава") Тогда
        // Делаем форму только для просмотра
        ЭтаФорма.ТолькоПросмотр = Истина;
        
        // Если нужно оставить доступными кнопки печати, можно не ставить ТолькоПросмотр,
        // а программно обойти элементы управления:
        Для Каждого Элемент Из ЭлементыФормы Цикл
            // Блокируем всё, кроме кнопок печати и закрытия
            Если ТипЗнч(Элемент) = Тип("Кнопка") Тогда
                // Здесь можно оставить кнопки печати активными
            Иначе
                Элемент.Доступность = Ложь;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Важный момент: установка ЭтаФорма.ТолькоПросмотр = Истина — это «мягкая» защита. Опытный пользователь может попытаться изменить данные через групповую обработку или внешнюю обработку. Поэтому этот метод всегда стоит комбинировать с проверками в ПередЗаписью модуля объекта.

Метод 4: Флаг ОбменДанными.Загрузка

Иногда программисты используют свойство ОбменДанными.Загрузка = Истина. Рассмотрим, стоит ли это делать. Когда этот флаг установлен, платформа отключает большинство проверок в модуле объекта (включая те, что написаны разработчиками в ПередЗаписью).

Если вы программно создаете документ и устанавливаете НовыйДок.ОбменДанными.Загрузка = Истина;, вы сможете записать его даже при наличии программных ограничений. Однако помните, что при этом не выполнятся стандартные проверки заполнения, расчеты итогов и прочая бизнес-логика. Используйте этот метод только если вы абсолютно уверены, что ваш программный код полностью и корректно формирует документ «под ключ».

Резюме и рекомендации

Для реализации задачи «создать программно, запретить интерактивно» мы рекомендуем следующую комбинацию действий:

  1. Минимизация прав в Роли: Снимите галочки Интерактивное добавление, Интерактивное изменение, Интерактивная пометка удаления.
  2. Привилегированный код: Создайте общий модуль с признаком Привилегированный, в котором будет описана функция СоздатьДокумент(...). Это позволит записывать объект даже без прав Добавление и Изменение у пользователя.
  3. Контроль в модуле объекта: В процедуре ПередЗаписью добавьте проверку на наличие специального флага в ДополнительныеСвойства. Это подстрахует систему, если права на изменение всё же будут выданы пользователю в будущем через другие роли.
  4. Интерфейс: В основной форме документа в процедуре ПриОткрытии устанавливайте ТолькоПросмотр = Истина, чтобы пользователь сразу видел, что редактирование невозможно.

Такой комплексный подход гарантирует целостность данных и защищает логику бизнес-процесса от несанкционированного вмешательства со стороны пользователя, при этом сохраняя работоспособность ваших автоматизированных инструментов ввода.

← На главную