Почему при вводе на основании в 1С:УТ 10.3 затирается реквизит «Ответственный» и как это исправить?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке и доработке конфигураций на базе обычных форм (например, «1С:Управление торговлей 10.3», «1С:Комплексная автоматизация 1.1» или «1С:Управление производственным предприятием 1.3») разработчики часто сталкиваются с ситуацией, когда при вводе на основании реквизиты документа заполняются корректно в модуле объекта, но после открытия формы документа на экране значения сбрасываются или заменяются стандартными.

Типичный пример: при создании документа РеализацияТоваровУслуг на основании документа ЗаказПокупателя требуется перенести сотрудника из реквизита Ответственный заказа в реализацию. Разработчик добавляет код в событие модуля объекта ОбработкаЗаполнения, отладчик подтверждает присвоение нужного значения, однако при открытии созданного документа в поле «Ответственный» снова подставляется текущий пользователь либо поле оказывается пустым. Разберем механизм работы платформы и типовых конфигураций, выясним причину такого поведения и рассмотрим надежные способы решения проблемы.

В чем причина перезаписи реквизита?

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

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

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

Внутри процедуры ЗаполнениеДокументов.ЗаполнитьШапкуДокумента происходит жесткая инициализация шапки документа значениями по умолчанию. Реквизит Ответственный принудительно перезаписывается значением текущего авторизованного пользователя системы (или значением из настроек пользователя), не проверяя, было ли значение уже установлено на этапе ОбработкаЗаполнения.

Способ 1. Переопределение значения в модуле формы документа

Рассмотрим самый быстрый локальный способ решения, который применяется непосредственно в форме создаваемого документа (например, формы документа РеализацияТоваровУслуг). Для этого перенесем или продублируем логику установки ответственного в процедуру ПриОткрытии формы документа, разместив ее строго после вызова процедуры ЗаполнитьШапкуДокумента.

Посмотрим на пример реализации такого кода:


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

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

В данном случае после того, как типовой механизм заполнит реквизит текущим пользователем, наш код проверит наличие заполненного документа-основания в реквизите Сделка (или ПараметрОснование) и восстановит ответственного из заказа.

Способ 2. Системная корректировка в общем модуле «ЗаполнениеДокументов»

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

Найдем процедуру ЗаполнитьШапкуДокумента в общем модуле ЗаполнениеДокументов и добавим проверку на заполненность поля перед перезаписью:


// Было:
// Документ.Ответственный = Пользователь;

// Стало:
Если НЕ ЗначениеЗаполнено(Документ.Ответственный) Тогда
    Документ.Ответственный = Пользователь;
КонецЕсли;

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

Способ 3. Передача контекста через свойство «ДополнительныеСвойства»

Рассмотрим еще один гибкий вариант, позволяющий избежать случайных перезаписей. В модуле объекта в процедуре ОбработкаЗаполнения можно передать признак того, что ответственного менять не требуется:


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

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

Затем в модуле формы документа проверяем наличие данного свойства:


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

Важные нюансы при работе с правами доступа (RLS)

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

← На главную