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