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