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