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

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

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

Проблема перепроведения и лишних проверок

Когда мы работаем с управляемыми формами, стандартная команда «Записать» при определенных настройках может инициировать перепроведение. Даже если мы явно указываем режим записи Запись, платформа все равно вызывает событие ПередЗаписью в модуле объекта и во всех связанных подписках. Если в этих подписках реализован контроль даты запрета или проверка заполнения движений, система выдаст ошибку или заблокирует запись, даже если мы меняем простое текстовое поле комментария или статус «Принят».

Решение 1: Использование параметров записи и флага ОбменДанными.Загрузка

Проанализируем наиболее эффективный метод, который позволяет «тихо» сохранить данные, минуя прикладные проверки. Суть метода заключается в передаче специального флага с клиента на сервер, который в процедуре ПередЗаписьюНаСервере установит свойство объекта ОбменДанными.Загрузка.

Разберем реализацию по шагам:

  1. На клиенте при нажатии кнопки мы вызываем стандартный метод Записать, передавая в него структуру параметров.
  2. На сервере в модуле формы перехватываем этот параметр.
  3. Устанавливаем режим загрузки для записываемого объекта, что отключает большинство стандартных проверок.

Рассмотрим пример кода в модуле управляемой формы:


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

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

Важное замечание: Чтобы этот метод сработал для подписок на события (например, проверки даты запрета), в коде этих подписок первой строкой должно стоять условие:


Если Источник.ОбменДанными.Загрузка Тогда
    Возврат;
КонецЕсли;

Решение 2: Программная запись объекта через ссылку

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

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


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

Решение 3: Управление свойством формы ПриЗаписиПерепроводить

В управляемых формах есть специфическое свойство ПриЗаписиПерепроводить. Оно определяет поведение платформы, когда пользователь нажимает кнопку «Записать» в уже проведенном документе. Если установить это свойство в Ложь, платформа выполнит только запись данных документа.

Рассмотрим ситуацию: нам нужно временно отключить перепроведение при выполнении определенной команды на форме.


&НаСервере
Процедура УстановитьРежимЗаписиБезПерепроведения(Значение)
    ПриЗаписиПерепроводить = Значение;
КонецПроцедуры

&НаКлиенте
Процедура КомандаЗаписатьТолькоДанные(Команда)
    УстановитьРежимЗаписиБезПерепроведения(Ложь);
    Записать();
    УстановитьРежимЗаписиБезПерепроведения(Истина); // Возвращаем стандартное поведение
КонецПроцедуры

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

Архитектурная альтернатива: Регистр сведений

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

Рассмотрим преимущества использования независимого регистра сведений:

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

Резюме

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

← На главную