Разработка и Конфигурация · 12 мин
Как в 1С проверить, что документ успешно записан
Как в 1С проверить, что документ успешно записан: методы Записать, Записывается, ПроверитьЗаполнение, обработка исключений. Примеры кода на встроенном языке.
Проверка того, что документ действительно записан в базу, — одна из самых частых задач при доработке конфигураций 1С. Она возникает при программном создании документов из обработок, при обмене данными, при массовом проведении и в любых сценариях, где от результата записи зависит дальнейшая логика: отправка печатной формы, регистрация к обмену, создание связанных объектов.
Ошибка здесь типична: разработчик вызывает метод Записать() и считает, что документ сохранён, хотя на самом деле запись могла не выполниться из-за отказа проверки заполнения, нарушения прав доступа, блокировки данных другим пользователем или ошибки в подписках на события. Если не обработать эту ситуацию, учётная система получит «потерянные» документы, а пользователи — расхождения в данных.
Ниже разобраны рабочие способы проверки: от простого анализа исключения до проверки через ссылку и запрос к базе. Каждый вариант сопровождается примером кода на встроенном языке 1С и указанием, когда его применять.
Что происходит при записи документа в 1С
Метод Записать() объекта документа запускает целую цепочку событий: обработчики ПередЗаписью, ПриЗаписи, проверку заполнения (если она включена), запись движений при проведении, срабатывание подписок на события и триггеров расширений. Отказ на любом из этих этапов приводит к исключению, и транзакция записи откатывается целиком — документ в базе не появляется.
Важно понимать: если код выполняется без обработки исключений, ошибка записи просто прерывает выполнение и показывает пользователю сообщение. Но в фоновых заданиях, регламентных операциях и обменах такое исключение может «проглотиться» или прервать пакетную обработку посередине. Поэтому проверка результата записи — не формальность, а обязательная часть устойчивого кода.
Отдельный случай — режим ОбменДанными.Загрузка = Истина. В этом режиме проверки и бизнес-логика отключаются, документ записывается «как есть». Здесь проверять нужно не бизнес-корректность, а сам факт физической записи и целостность данных.
Проверка через Попытка/Исключение — базовый приём
Самый распространённый способ убедиться, что документ записан, — перехватить исключение. Если исключения не было, запись прошла; если было — получаем текст ошибки и решаем, что делать дальше.
НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДатаСеанса();
НовыйДок.Организация = Организация;
// ... заполнение реквизитов и табличных частей
Попытка
НовыйДок.Записать(РежимЗаписиДокумента.Проведение);
ДокументЗаписан = Истина;
Исключение
ДокументЗаписан = Ложь;
ТекстОшибки = ОписаниеОшибки();
ЗаписьЖурналаРегистрации("Запись документа",
УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);
КонецПопытки;
Обратите внимание на две детали. Во-первых, результат фиксируется в отдельной переменной — это удобно при пакетной обработке, когда нужно собрать статистику успешных и неуспешных записей. Во-вторых, текст ошибки обязательно пишется в журнал регистрации: без этого диагностика причин отказа в рабочей базе превращается в гадание.
Проверка заполнения до записи
Часть отказов при записи связана не с техническими проблемами, а с незаполненными обязательными реквизитами. Такие ошибки логично отлавливать заранее методом ПроверитьЗаполнение() — он возвращает Ложь, если проверка не пройдена, и выводит пользователю конкретные сообщения о проблемных полях.
Если НЕ НовыйДок.ПроверитьЗаполнение() Тогда
// Документ содержит ошибки заполнения, записывать бессмысленно
Возврат;
КонецЕсли;
НовыйДок.Записать(РежимЗаписиДокумента.Запись);
Такое разделение полезно ещё и тем, что позволяет различить классы ошибок: «документ не прошёл проверку данных» и «документ не удалось физически записать». В первом случае нужно исправлять данные, во втором — разбираться с блокировками, правами или кодом подписок.
Учтите ограничение: ПроверитьЗаполнение() вызывает обработчики проверки заполнения, определённые в модуле объекта, поэтому его выполнение может быть небесплатным по времени на больших документах. В массовых обработках это обычно приемлемо, но в тонких местах производительности стоит замерять.
Проверка по ссылке после записи
Косвенный, но надёжный признак успешной записи нового документа — заполненная ссылка. У только что созданного объекта до записи ссылка пустая (точнее, не установлена); после успешной записи платформа присваивает объекту ссылку, и она становится доступна через свойство Ссылка.
НовыйДок.Записать();
Если НовыйДок.Ссылка.Пустая() Тогда
// Запись не выполнена
Иначе
// Документ записан, ссылка получена
КонецЕсли;
Для документа, который уже должен существовать в базе (например, пришла ссылка из обмена или из параметра), применяется обратная проверка — существует ли объект по ссылке. Классический способ: Ссылка.ПолучитьОбъект() возвращает Неопределено, если объекта нет. Более лёгкий вариант без выборки всего объекта — запрос или функция общего назначения типа ОбщегоНазначения.СсылкаСуществует() в конфигурациях на БСП.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Реализация.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", ПроверяемаяСсылка);
Если Запрос.Выполнить().Пустой() Тогда
// Документа в базе нет
КонецЕсли;
Проверка проведения и контроль в транзакциях
Записанный документ — не всегда проведённый. Если логика требует именно проведения, после записи проверяйте свойство Проведен у объекта или у ссылки. Отказ проведения (например, из-за контроля остатков) приводит к исключению, но если проведение выполнялось в отдельной попытке, состояние стоит проконтролировать явно.
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение,
РежимПроведенияДокумента.Оперативный);
Если НЕ ДокОбъект.Проведен Тогда
// Проведение не выполнено — анализируем причины
КонецЕсли;
Особая ситуация — запись внутри явной транзакции (НачатьТранзакцию()). В этом случае даже успешно выполненный Записать() не гарантирует, что документ останется в базе: при откате транзакции запись исчезнет. Поэтому финальную проверку наличия документа (запросом по ссылке) имеет смысл делать уже после ЗафиксироватьТранзакцию(), если от этого зависят внешние действия — например, отправка данных в другую систему.
- 1Заполните объект документа и вызовите ПроверитьЗаполнение() — отсеките ошибки данных
- 2Выполните Записать() внутри Попытка/Исключение с нужным режимом записи
- 3При исключении зафиксируйте ОписаниеОшибки() в журнале регистрации и прервите сценарий
- 4После успешной записи убедитесь, что Ссылка не пустая
- 5Если требуется проведение — проверьте свойство Проведен
- 6При записи в транзакции финальную проверку существования выполните после фиксации транзакции
Диагностика причин, почему документ не записался
Когда проверка показала, что документ не записан, следующий шаг — определить причину. Текст исключения в большинстве случаев содержит прямое указание: конфликт блокировки, нарушение прав доступа, отказ в обработчике, ошибка проверки заполнения.
| Текст или признак ошибки | Вероятная причина | Что делать |
|---|---|---|
| «Конфликт блокировки при выполнении транзакции» | Документ или связанные данные редактируются другим сеансом | Повторить попытку позже, сократить длительность транзакции |
| «Нарушение прав доступа» | У пользователя нет прав на запись или проведение | Проверить роли и RLS, выполнить от имени привилегированного задания |
| Сообщение из подписки на событие | Отказ в обработчике ПередЗаписью/ПриЗаписи | Анализировать код подписки, проверить входные данные |
| «Поле ... не заполнено» | Не пройдена проверка заполнения | Заполнить обязательные реквизиты до записи |
| Ошибок нет, но документа в базе нет | Откат транзакции вызывающим кодом | Проверить логику НачатьТранзакцию/ОтменитьТранзакцию |
Полезный инструмент диагностики — журнал регистрации с отбором по событию и пользователю. Если запись инициируется фоновым заданием, смотрите также состояние самого задания: аварийно завершённое фоновое задание часто означает необработанное исключение до или после записи.
Проверка с клиентской стороны и в управляемых формах
В управляемой форме документа запись обычно выполняется стандартными командами, и платформа сама сообщает пользователю об отказе. Если нужна программная проверка — например, после команды «Записать» запустить дополнительную обработку, — используйте обработчики ПослеЗаписи на клиенте и на сервере. Сам факт вызова этих обработчиков уже означает, что запись состоялась.
Для тонкого клиента и веб-клиента помните про разделение контекстов: объектные методы (Записать() объекта) доступны только на сервере, на клиенте работают с данными формы. Типовой приём — вызвать серверную процедуру, которая выполнит запись и вернёт структуру с признаком успеха и текстом ошибки, а клиент уже решит, что показать пользователю.
В массовых обработках удобно собирать результат записи каждого документа в таблицу значений: ссылка, признак успеха, текст ошибки. По завершении такая таблица показывается пользователю или пишется в журнал — это избавляет от разбора сотен однотипных сообщений.
Частые вопросы
Метод Записать() не выдал ошибку — значит ли это, что документ точно в базе?
Если запись выполнялась вне явной транзакции — да, документ сохранён. Если внутри транзакции, начатой вашим кодом, — окончательная гарантия появится только после ЗафиксироватьТранзакцию(). При откате транзакции запись исчезнет, поэтому ответственные проверки делайте после фиксации.
Чем ПроверитьЗаполнение() отличается от записи в попытке?
ПроверитьЗаполнение() проверяет только корректность данных документа и возвращает Истина/Ложь без записи в базу. Записать() в попытке выполняет реальное сохранение со всеми обработчиками и может упасть по техническим причинам — блокировки, права, ошибки подписок. Методы дополняют друг друга, а не заменяют.
Как проверить существование документа по ссылке без выборки всего объекта?
Используйте запрос с конструкцией ПЕРВЫЕ 1 по таблице документа с условием по ссылке — если результат пустой, объекта нет. В конфигурациях на базе Библиотеки стандартных подсистем есть готовая функция ОбщегоНазначения.СсылкаСуществует(), которая делает то же самое.
Почему документ записывается, но остаётся непроведённым?
Запись и проведение — разные операции. Если вызван Записать(РежимЗаписиДокумента.Запись), документ сохраняется без проведения. Если проведение было запрошено, но отменено из-за ошибок контроля (например, остатков), возникает исключение. Проверяйте свойство Проведен после записи, чтобы отличить эти состояния.
Как проверить запись документа при загрузке через ОбменДанными.Загрузка?
В этом режиме проверки заполнения и бизнес-обработчики отключены, поэтому контролируйте только технический результат: отсутствие исключения при Записать() и существование объекта по ссылке после загрузки. Корректность данных при необходимости проверяйте отдельной процедурой после окончания обмена.
Что делать при ошибке «Конфликт блокировки» в регламентном задании?
Организуйте повторные попытки с паузой (обычно несколько попыток с интервалом), сократите объём данных в одной транзакции и проверьте, не пересекается ли задание по времени с интерактивной работой пользователей или другими фоновыми заданиями, изменяющими те же документы.
Что важно запомнить
Проверка записи документа строится на трёх опорах: Попытка/Исключение вокруг Записать() с журналированием ошибки, контроль заполненности ссылки после записи и проверка свойства Проведен, если требуется проведение. При работе в транзакции финальную проверку переносите за точку фиксации, а ошибки данных отсекайте заранее через ПроверитьЗаполнение().