К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как работает отказ в 1С: механизм прерывания операций

Как работает параметр Отказ в обработчиках событий 1С: где доступен, как прерывает запись и проведение, типовые ошибки и примеры кода для разработчика.

Параметр «Отказ» — один из ключевых механизмов встроенного языка 1С, который позволяет прервать стандартную обработку события: записи документа, проведения, записи элемента справочника, интерактивного действия пользователя. Когда в обработчике события разработчик присваивает Отказ = Истина, платформа останавливает выполнение операции и возвращает объект в исходное состояние.

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

Типовая ситуация: при проведении документа нужно проверить остатки, заполненность реквизитов или согласование, и при нарушении условий не дать документу провестись. Именно для этого и существует параметр «Отказ» — он превращает обработчик события в точку контроля бизнес-логики.

Что такое параметр Отказ и где он доступен

«Отказ» — это параметр типа Булево, который платформа передаёт в обработчики событий объектов. Значение по умолчанию — Ложь, то есть операция разрешена. Разработчик в коде обработчика может установить значение Истина, и тогда платформа прервёт выполнение операции после завершения обработчика.

Параметр доступен не во всех событиях. Его наличие определяется тем, может ли операция быть отменена логически. Например, в событии «ПриЗаписи» отказ есть — запись можно прервать. А в событии «ПриОткрытии» формы отказ тоже существует: установка Отказ = Истина не даст форме открыться. Но в событии «ПриИзменении» реквизита отказа нет, потому что изменение уже произошло.

Основные события с параметром «Отказ»:

  • ПередЗаписью, ПриЗаписи — модули объектов и форм;
  • ОбработкаПроведения — документы;
  • ОбработкаУдаленияПроведения — документы;
  • ПередУдалением — справочники, документы и другие объекты;
  • ПередЗаписью, ПриОткрытии — управляемые формы;
  • ОбработкаПроверкиЗаполнения — проверка обязательных реквизитов.

Как платформа обрабатывает отказ при записи и проведении

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

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

Важно понимать: установка Отказ = Истина не прерывает выполнение самого обработчика. Код после присвоения продолжит работать до конца процедуры, если вы явно не добавите Возврат;. Это частая причина ошибок — после отказа код продолжает обращаться к данным, которые считались невалидными.

Примеры кода: отказ в типовых сценариях

Простейший пример — проверка заполненности реквизита перед записью элемента справочника:

Процедура ПередЗаписью(Отказ)

Если Не ЗначениеЗаполнено(ИНН) Тогда

Отказ = Истина;

Сообщить("Не заполнен ИНН контрагента. Запись отменена.");

Возврат;

КонецЕсли;

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

Пример отказа при проведении документа с проверкой остатков:

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

Для Каждого Строка Из Товары Цикл

Остаток = ПолучитьОстаток(Строка.Номенклатура, Склад);

Если Остаток < Строка.Количество Тогда

Отказ = Истина;

Сообщить("Недостаточно товара: " + Строка.Номенклатура);

КонецЕсли;

КонецЦикла;

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

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

bsl
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    Если СуммаДокумента > 100000 И Не ЗначениеЗаполнено(Договор) Тогда
        Отказ = Истина;
        Сообщить("При сумме свыше 100000 договор обязателен");
    КонецЕсли;
КонецПроцедуры

Отказ в формах и интерактивных действиях

В управляемых формах параметр «Отказ» работает в событиях «ПриОткрытии», «ПередЗаписью», «ПриЗаписи», «ПередЗакрытием». Например, в «ПриОткрытии» можно запретить открытие формы документа пользователю без нужной роли, установив Отказ = Истина — форма просто не появится.

Особенность форм: события формы вызываются в дополнение к событиям модуля объекта, а не вместо них. Если проверка реализована в модуле объекта, она сработает и при интерактивной записи, и при программной. Если проверка только в форме — программная запись её обойдёт. Поэтому бизнес-контроль правильно размещать в модуле объекта, а в форме делать только интерфейсные проверки.

Проверки, критичные для целостности данных, всегда размещайте в модуле объекта или в подписках на события. Код в форме защищает только от интерактивного ввода и легко обходится обработками, обменами и программной записью.
ПЗ
Практическое замечание

Подписки на события и отказ

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

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

Ограничение: порядок вызова нескольких подписок на одно событие не гарантирован. Если логика одной проверки зависит от результата другой, объединяйте их в одну подписку или в модуль объекта.

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

Типичные ошибки при работе с отказом

Первая ошибка — отсутствие Возврат после установки отказа. Код продолжает выполняться, обращается к незаполненным данным и падает с ошибкой вместо аккуратного сообщения пользователю.

Вторая ошибка — проверки только в форме. Обмен данными, групповая обработка или программная запись обходят такую защиту, и в базе появляются некорректные документы.

Третья ошибка — использование ВызватьИсключение вместо параметра «Отказ». Исключение прерывает операцию с техническим сообщением и в клиент-серверном варианте может выглядеть для пользователя как сбой программы. Для штатной бизнес-проверки правильный инструмент — именно Отказ плюс Сообщить.

Типичные ошибки
01
Отказ = Истина без Возврат — код продолжает работать с невалидными данными и вызывает исключение
02
Проверка только в модуле формы — программная запись и обмены обходят контроль
03
ВызватьИсключение вместо Отказ — пользователь видит техническую ошибку вместо понятного сообщения
04
Установка Отказ в событии, где параметр недоступен — ошибка компиляции или игнорирование логики
05
Молчаливый отказ без Сообщить — пользователь не понимает, почему документ не проводится

Как проверить, что отказ работает правильно

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

Дополнительно убедитесь, что при отказе в базе не осталось частичных изменений: откройте связанные регистры и объекты, которые код мог изменить до отказа. Транзакционность платформы обычно гарантирует чистый откат, но если в обработчике использовались вызовы вне транзакции (например, запись в файлы или внешние системы), их платформа не откатит.

Контрольные точки

Как проверить результат

Документ с нарушением условия
Норма

Проведение отменено, выведено понятное сообщение, данных в регистрах нет

Тревожный признак

Документ провёлся или появились частичные движения

Программная запись объекта
Норма

Метод Записать() завершился с отказом, исключения нет

Тревожный признак

Запись прошла в обход проверки

Сообщение пользователю
Норма

Текст указывает причину и проблемный объект

Тревожный признак

Техническая ошибка или отсутствие сообщения

FAQ

Можно ли отменить отказ, установленный в другом обработчике?

Надёжного способа нет. Технически в событии, которое вызывается позже, можно установить Отказ = Ложь, но порядок вызова подписок не гарантирован, и такая логика хрупкая. Правильнее — скорректировать условие в исходной проверке или отключить соответствующую подписку.

Почему отказ в ОбработкаПроведения отменяет и запись документа?

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

Чем отказ отличается от исключения?

Отказ — штатный механизм: операция прерывается, транзакция откатывается, пользователь видит ваше сообщение через Сообщить. Исключение — аварийное прерывание с техническим текстом. Для бизнес-проверок используйте Отказ, исключения оставьте для действительно нештатных ситуаций.

Работает ли отказ при обмене данными?

Если проверка находится в модуле объекта или подписке — да, она сработает и при загрузке данных, если в обмене не отключён режим проверки. Проверки в формах при обмене не выполняются, так как форма не открывается.

Как сообщить пользователю о нескольких ошибках сразу?

Не прерывайте обработчик после первого нарушения: соберите все проблемы в цикле, для каждой вызовите Сообщить, а Отказ = Истина установите один раз. Пользователь увидит полный список ошибок и исправит их за одну итерацию.

Можно ли установить отказ в событии ПриИзменении реквизита?

Нет, в этом событии параметр «Отказ» отсутствует — изменение уже произошло. Если нужно запретить ввод значения, используйте событие «ОбработкаВыбора» или проверку при записи через ОбработкаПроверкиЗаполнения.

Итог

Что важно запомнить

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