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

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

Как в 1С проверить, записан ли документ

Как проверить, записан ли документ в 1С: проверка через Проведен, ПометкаУдаления, ЭтоНовый(), запрос к базе и консоль кода. Примеры на встроенном языке 1С.

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

Важно разделять три состояния документа: создан, но не записан (существует только в памяти); записан, но не проведён (есть в базе, но не формирует движения по регистрам); проведён (записан и участвует в учёте). Каждому состоянию соответствуют свои признаки и свои методы проверки.

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

Разница между «записан», «проведён» и «существует в базе»

Документ, который только что создан командой «Создать» или методом Документы.РеализацияТоваровУслуг.СоздатьДокумент(), существует только в оперативной памяти. В базе его нет: у него ещё не присвоены окончательные номер и дата, ссылка временная. Такой объект нельзя найти запросом и нельзя использовать в других документах как основание.

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

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

Как проверить запись документа через интерфейс

Самый простой способ — посмотреть на заголовок формы документа. У незаписанного документа в заголовке обычно присутствует пометка «(не записан)» или подобная, а номер может отображаться как нулевой или отсутствовать. После нажатия «Записать» или «Провести» пометка исчезает, появляются присвоенные номер и дата.

Второй признак — наличие документа в журнале. Откройте журнал соответствующего вида документов и обновите список (F5). Если документ появился в списке — он записан. Пиктограмма в первой колонке покажет состояние: проведён, записан без проведения или помечен на удаление.

Третий способ — команда «Ещё → Изменить форму» не нужна, достаточно пункта «Перейти → Движения документа». Если документ проведён, отобразятся записи регистров. Если кнопка движений недоступна или список пуст при включённом проведении — документ записан, но не проведён.

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

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

Заголовок формы документа
Норма

Нет пометки «не записан», заполнены номер и дата

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

Есть пометка «не записан» — документ только в памяти

Пиктограмма в журнале документов
Норма

Иконка проведённого или записанного документа

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

Документа нет в журнале после обновления списка

Команда «Движения документа»
Норма

Отображаются записи регистров

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

Список пуст при включённом проведении — документ не проведён

Проверка в коде: метод ЭтоНовый() и свойство Проведен

Основной метод проверки существования объекта в базе — ЭтоНовый(). Он возвращает истину, если объект ещё ни разу не записан, и ложь, если документ уже есть в базе. Метод применяется к объекту типа ДокументОбъект, а не к ссылке.

Факт проведения определяется свойством Проведен. Оно доступно и у объекта, и у ссылки (через обращение к реквизиту ссылки). Пометка удаления проверяется свойством ПометкаУдаления.

ДокОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

ЗаполнитьДокумент(ДокОбъект);

Если ДокОбъект.ЭтоНовый() Тогда

// Документ ещё не записан в базу

ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);

КонецЕсли;

Если ДокОбъект.Проведен Тогда

Сообщить("Документ проведён");

Иначе

Сообщить("Документ записан, но не проведён");

КонецЕсли;

Обратите внимание: ЭтоНовый() не работает для ссылки — у ссылки нет такого метода. Если у вас только ссылка, существование документа проверяют иначе (см. следующий раздел).

Проверка существования документа по ссылке

Когда в коде есть только ссылка (например, полученная из реквизита другого объекта), проверить, что документ реально существует в базе, можно несколькими способами. Самый надёжный — запрос к таблице документа: он не вызывает обращения к данным объекта и не генерирует исключений.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Реализация.Проведен КАК Проведен,

| Реализация.ПометкаУдаления КАК ПометкаУдаления

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ДокСсылка);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Сообщить("Документ не записан в базу (битая ссылка)");

Иначе

Выборка = Результат.Выбрать();

Выборка.Следующий();

Если Выборка.Проведен Тогда

Сообщить("Документ проведён");

КонецЕсли;

КонецЕсли;

Альтернатива без запроса — обращение к реквизиту ссылки, например ДокСсылка.Дата. Если ссылка «битая» (объект удалён прямым удалением), такое обращение вернёт неопределено или вызовет ошибку в зависимости от контекста, поэтому в серверном коде предпочтителен запрос.

bsl
Если ДокСсылка.ПолучитьОбъект() = Неопределено Тогда
    Сообщить("Документ не существует в базе");
КонецЕсли;

Проверка в форме документа

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

&НаКлиенте

Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)

Если Объект.Ссылка.Пустая() Тогда

// Документ ещё не записан — предупреждаем пользователя

ТекстПредупреждения = "Документ не записан. Данные будут потеряны.";

КонецЕсли;

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

На сервере в форме доступен и метод ЭтоНовый() через преобразование реквизита формы в объект: РеквизитФормыВЗначение("Объект").ЭтоНовый(). Но чаще достаточно проверки Объект.Ссылка.Пустая() — она не требует серверного вызова и работает на клиенте.

Порядок действий при проверке из формы
  1. 1
    Проверьте Объект.Ссылка.Пустая() — истина означает, что документ не записан
  2. 2
    Если нужен факт проведения, обратитесь к Объект.Проведен
  3. 3
    При необходимости заблокируйте действия, требующие записанного документа (ввод на основании, печать с подписью)
  4. 4
    После записи обновите состояние формы и повторно проверьте признаки

Проверка через консоль кода и отладчик

Для разовой проверки конкретного документа удобна консоль кода (внешняя обработка) или окно «Вычислить выражение» в отладчике (Shift+F9). Достаточно вычислить выражение с запросом или обращением к свойствам ссылки.

В отладчике поставьте точку останова сразу после строки ДокОбъект.Записать() и вычислите ДокОбъект.ЭтоНовый() и ДокОбъект.Проведен. Если ЭтоНовый() по-прежнему возвращает истину — запись не выполнилась: либо произошло исключение, либо в обработчике ПередЗаписью был установлен Отказ = Истина.

Типичные ошибки
01
Вызов ЭтоНовый() у ссылки вместо объекта — метод отсутствует у ссылочного типа, код падает с ошибкой
02
Проверка Проведен до записи — у незаписанного документа свойство всегда ложно, что искажает логику
03
Игнорирование исключения при Записать() — документ остаётся незаписанным, а код продолжает работать как будто всё в порядке
04
Обращение к реквизитам битой ссылки без проверки — приводит к ошибке или неопределённым значениям

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

Если проверка показывает, что документ остался незаписанным, причина обычно одна из следующих. В обработчиках ПередЗаписью или ПриЗаписи (в модуле объекта, формы или подписке на событие) установлен параметр Отказ = Истина — запись отменяется платформой без явной ошибки в вашем коде.

Вторая причина — не заполнены обязательные реквизиты, и сработал контроль заполнения (свойство «Проверка заполнения» у реквизита или обработчик ОбработкаПроверкиЗаполнения). Третья — нарушение прав доступа: у пользователя нет права на добавление или изменение документа. Четвёртая — исключение при проведении: контроль остатков, закрытый период, дата запрета изменения данных.

Для диагностики оберните запись в попытку и выведите текст ошибки:

Попытка

ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);

Исключение

Сообщить("Документ не записан: " + ОписаниеОшибки());

КонецПопытки;

Если ДокОбъект.ЭтоНовый() Тогда

// Запись не выполнена — анализируем причину

КонецЕсли;

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

Сводная таблица способов проверки

Что проверяемСпособКогда применять
Записан ли объект в базуДокОбъект.ЭтоНовый()Работа с ДокументОбъект в коде
Записан ли документ из формыОбъект.Ссылка.Пустая()Клиентские обработчики формы
Существует ли документ по ссылкеЗапрос к таблице документаПроверка «битых» ссылок, серверный код
Проведён ли документСвойство Проведен (объект или ссылка)Любой контекст
Состояние визуальноЖурнал документов, пиктограмма, заголовок формыРабота пользователя без кода
Итог

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

«Записан» и «проведён» — разные состояния. Существование объекта в базе проверяют методом ЭтоНовый() или запросом по ссылке, проведение — свойством Проведен, а в интерфейсе — по журналу и заголовку формы. Если запись не выполняется, ищите отказ в обработчиках, контроле заполнения, правах и датах запрета.

Частые вопросы

Чем отличается Записать() от Провести() в 1С?

Записать() сохраняет документ в базе без формирования движений. Провести() — это тот же вызов Записать() с режимом проведения: документ записывается и формирует движения по регистрам. У проведённого документа свойство Проведен равно истине.

Почему ЭтоНовый() возвращает истину после Записать()?

Значит, запись фактически не выполнилась: либо возникло исключение, которое перехвачено выше по стеку, либо в обработчике ПередЗаписью или подписке на событие установлен Отказ = Истина. Проверьте запись в конструкции Попытка/Исключение и все подписки на события документа.

Как проверить, записан ли документ, не открывая его?

Найдите документ в журнале: если он есть в списке — записан. Пиктограмма покажет, проведён он или помечен на удаление. Программно — выполните запрос к таблице документа по ссылке или по номеру и дате.

Что такое «битая ссылка» и как её найти?

Это ссылка на объект, которого уже нет в базе (удалён прямым удалением). При обращении к её реквизитам возвращается неопределено или текст вида «Объект не найден». Найти такие ссылки можно запросом с левым соединением к таблице документа — записи, где ссылка документа равна NULL.

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

Да, если документ открыт в форме: свойство Объект.Проведен доступно на клиенте, так как данные объекта уже переданы в форму. Для произвольной ссылки вне формы обращение к реквизиту вызовет серверный вызов — в этом случае эффективнее один серверный метод с запросом.

Документ записан, но движений нет — это нормально?

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