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

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

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

На первый взгляд задача кажется тривиальной — достаточно настроить стандартные роли. Однако на практике разработчики сталкиваются с тем, что простое жонглирование ролями не дает желаемого результата. При ограничении прав на справочник-владелец система автоматически блокирует возможность изменения подчиненных объектов. В этой статье мы подробно разберем, почему так происходит, и рассмотрим эффективные программные и архитектурные способы решения этой проблемы.

Выясняем причину: почему блокируется подчиненный справочник?

На уровне платформы «1С:Предприятие 8» нет жесткого правила, запрещающего редактировать подчиненный справочник при отсутствии прав на изменение владельца. Это ограничение накладывается логикой прикладных решений (особенно построенных на Библиотеке стандартных подсистем — БСП) и механизмами работы управляемых форм:

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

Ниже мы подробно разберем три практических способа решения этой проблемы.

Способ 1. Создание роли в Расширении конфигурации и перехват логики формы (Рекомендуемый способ)

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

Проанализируем шаги реализации:

  1. Создадим новое расширение конфигурации (или используем существующее).
  2. Добавим в расширение справочники Контрагенты и ДоговорыКонтрагентов.
  3. Создадим в расширении новую роль, например, РедактированиеДоговоровБезКонтрагентов.
  4. Настроим права для созданной роли:
    • Для справочника Контрагенты предоставим права: Чтение, Просмотр, Ввод по строке. Права на «Изменение» и «Добавление» должны быть сняты.
    • Для справочника ДоговорыКонтрагентов предоставим полный набор прав: Чтение, Добавление, Изменение, Просмотр, Редактирование.
  5. Добавим форму элемента справочника ДоговорыКонтрагентов в расширение и перехватим процедуру ПриСозданииНаСервере с помощью директивы &После.

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


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

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

Способ 2. Обход через подписку на событие «ПередЗаписью» (Альтернативный вариант)

Если вы не хотите вмешиваться в логику управляемых форм и переопределять их свойства, можно использовать «обратный» подход. Мы оставляем пользователю типовые права, разрешающие изменять и контрагентов, и договоры, но жестко блокируем попытку записи контрагента на уровне сервера базы данных.

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

  1. Создаем в расширении роль РазрешитьРедактированиеКонтрагентов и назначаем ее только ответственным сотрудникам (администраторам НСИ).
  2. Обычным пользователям оставляем стандартные профили доступа, которые дают права на запись контрагентов и договоров.
  3. Создаем в расширении подписку на событие ПередЗаписью для справочника Контрагенты.

Проанализируем код обработчика подписки на событие:


Процедура Расш1_ПередЗаписьюКонтрагентаПередЗаписью(Источник, Отказ, Замещение) Экспорт
    
    // Исключаем проверки при обмене данными (загрузке)
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Если у пользователя нет роли на редактирование контрагентов, проверяем попытку изменения
    Если НЕ РольДоступна("Расш1_РазрешитьРедактированиеКонтрагентов") Тогда
        
        // Разрешаем записывать только абсолютно новые объекты (если это требуется бизнес-логикой)
        // Для существующих объектов проверяем модифицированность
        Если НЕ Источник.ЭтоНовый() Тогда
            
            // Получаем исходные данные из базы данных для сравнения
            СсылкаНаОбъект = Источник.Ссылка;
            ОбъектБД = СсылкаНаОбъект.ПолучитьОбъект();
            
            Если ОбъектБД <> Неопределено Тогда
                // Проверяем, изменились ли значимые реквизиты контрагента
                Для Каждого Реквизит Из Источник.Метаданные().Реквизиты Цикл
                    ИмяРеквизита = Реквизит.Имя;
                    Если Источник[ИмяРеквизита] <> ОбъектБД[ИмяРеквизита] Тогда
                        Отказ = Истина;
                        ВызватьИсключение "У вас нет прав на изменение данных контрагента! Редактирование договоров при этом разрешено.";
                        Возврат;
                    КонецЕсли;
                КонецЦикла;
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Преимущество метода: На уровне интерфейса и стандартных прав БСП система считает, что у пользователя есть полные права на оба справочника. Поэтому формы договоров открываются без каких-либо программных блокировок со стороны БСП. При этом любая попытка интерактивно изменить данные самого контрагента будет пресечена на уровне СУБД с выводом понятного сообщения об ошибке.

Способ 3. Организация прямого доступа к списку договоров

Очень часто проблема кроется в том, что пользователи пытаются создавать договоры исключительно из карточки контрагента. Карточка открыта в режиме "Только просмотр", и этот статус наследуется формой договора.

Чтобы обойти это поведение интерфейса, мы можем настроить прямой доступ к списку договоров:

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

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

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

Каждый из рассмотренных методов имеет свои преимущества:

← На главную