Как автоматически подставлять вид договора контрагента в зависимости от пользователя в 1С 8.3?

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

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

Разберем, почему простой код в форме может не сработать, проанализируем ошибки начинающих разработчиков и рассмотрим наиболее надежные варианты реализации данной задачи с точки зрения стандартов разработки «1С».

Почему не срабатывает простое присвоение в процедуре ПриСозданииНаСервере?

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

  1. Обращение к реквизиту объекта формы: В управляемых формах реквизиты объекта не являются глобальными переменными контекста. Чтобы изменить данные, необходимо явно обращаться к основному реквизиту формы: Объект.ВидДоговора. Обращение просто как ВидДоговора = ... либо вызовет ошибку компиляции, либо изменит локальную переменную, не затронув данные объекта.
  2. Отсутствие проверки на создание нового элемента: Процедура ПриСозданииНаСервере вызывается как при создании нового договора, так и при открытии уже существующего. Если не проверить, новый это элемент или нет, значение вида договора будет перезаписываться при каждом просмотре ранее сохраненных документов.
  3. Динамическая логика типовой формы: В «1С:Бухгалтерии» форма договора динамически скрывает и показывает поля, группы и страницы в зависимости от выбранного вида договора. При простой установке значения на клиенте без вызова служебных обработчиков интерфейс формы может не перестроиться.

Вариант 1. Использование события ОбработкаЗаполнения в модуле объекта или расширении (Рекомендуемый способ)

Рассмотрим наиболее универсальный и методически верный вариант — переопределение логики заполнения в модуле объекта справочника. Событие ОбработкаЗаполнения выполняется как при программном создании объекта, так и при интерактивном нажатии кнопки «Создать» в списке.

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


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

Плюсы данного подхода:

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

Вариант 2. Использование подписки на событие

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

Разберем по шагам создание подписки:

  1. В дереве метаданных в ветке Общие -> Подписки на события создаем новую подписку.
  2. В качестве источника указываем СправочникОбъект.ДоговорыКонтрагентов.
  3. Событие выбираем ОбработкаЗаполнения.
  4. В обработчике в общем модуле пишем следующий код:

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

Вариант 3. Доработка модуля формы элемента

Если требуется изменить поведение исключительно в контексте интерактивной работы с конкретной формой элемента, настроим обработчик ПриСозданииНаСервере. Обязательно проверяем, что форма открыта для создания нового элемента через свойство Параметры.Ключ.Пустая().

Посмотрим на пример кода в модуле формы (или расширении формы с аннотацией &После):


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

Как правильно определять пользователя: рекомендации

Проанализируем распространенную ошибку, когда в коде прописывают жесткое условие по имени: ПользователиИнформационнойБазы.ТекущийПользователь().Имя = "Иванов". Делать так крайне не рекомендуется, поскольку при смене сотрудника или изменении его учетной записи придется снова вносить изменения в код конфигурации.

Для надежного разграничения логики рекомендуется использовать один из следующих подходов:

  1. Проверка через метод РольДоступна("ИмяРоли"): Создается отдельная роль (например, «Юрист» или «Снабжение»), которая назначается нужным пользователям через стандартные группы доступа.
  2. Использование регистра сведений: Создается простой непериодический регистр сведений (например, «НастройкиПользователейПоУмолчанию»), где для каждого пользователя указывается требуемый вид договора по умолчанию. В обработчике заполнения выполняется чтение данных из этого регистра.
← На главную