Как программно проверить проведен документ или нет в 1С 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

1. Проверка признака проведения в модуле объекта

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

Рассмотрим, как правильно обращаться к этому свойству внутри модуля документа:


Если Проведен Тогда
    // Документ в текущем состоянии объекта помечен как проведенный
    Сообщить("Документ проведен");
Иначе
    Сообщить("Документ не проведен");
КонецЕсли;

Также допустимо явное обращение через системное свойство ЭтотОбъект:


Если ЭтотОбъект.Проведен Тогда
    // Выполняем действия для проведенного документа
КонецЕсли;

Важный нюанс: свойство Проведен в модуле объекта отражает состояние данных в оперативной памяти перед записью. Если документ проводится прямо сейчас, свойство Проведен уже будет равно Истина. Если нам требуется узнать, был ли документ проведен в базе данных до начала текущей транзакции записи, следует проверить свойство ссылки:


Если Не ЭтоНовый() И Ссылка.Проведен Тогда
    // Документ уже был проведен в базе данных до текущего изменения
КонецЕсли;

2. Проверка проведенности на управляемой форме

В модуле управляемой формы основным реквизитом документа обычно выступает Объект (тип ДанныеФормыСтруктура). На клиенте и на сервере формы свойство проведенности доступно напрямую через данный реквизит.

Посмотрим на пример проверки в контексте формы:


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

Обратите внимание: переменные ТекущийДокумент или ЭтотОбъект в управляемой форме не содержат реквизитов документа и обращение к ним для проверки статуса проведения вызовет ошибку компиляции.

3. Проверка проведения в командах (общие команды и команды объектов)

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

Разберем по шагам, как обработать команду с учетом клиент-серверного взаимодействия:

  1. Обработчик команды ОбработкаКоманды выполняется на клиенте (директива &НаКлиенте).
  2. На тонком клиенте прямое обращение через точку к реквизитам ссылки (например, ПараметрКоманды.Проведен) недопустимо или вызывает неявный вызов сервера. Поэтому проверку следует выносить в серверную процедуру или функцию.
  3. Если у команды включен множественный выбор, в ПараметрКоманды приходит Массив ссылок, который необходимо обработать циклом.

Посмотрим на типовую реализацию проверки в модуле команды:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    
    // Передаем ссылку на сервер для проверки
    ДокументПроведен = ПроверитьПроведениеНаСервере(ПараметрКоманды);
    
    Если ДокументПроведен Тогда
        ПоказатьОповещениеПользователю("Статус", , "Документ проведен");
    Иначе
        ПоказатьОповещениеПользователю("Статус", , "Документ не проведен");
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПроверитьПроведениеНаСервере(СсылкаНаДокумент)
    
    // На сервере свойство Проведен доступно у типа ДокументСсылка
    Возврат СсылкаНаДокумент.Проведен;
    
КонецФункции

4. Проверка проведенности по ссылке через запрос и функции БСП

Если в серверном коде у нас есть только переменная типа ДокументСсылка, мы можем прочитать признак проведения несколькими способами:

Способ А. Прямое обращение через точку (на сервере):


Если СсылкаНаДокумент.Проведен Тогда
    // Документ проведен в информационной базе
КонецЕсли;

Способ Б. Использование функции БСП (Библиотеки Стандартных Подсистем):

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


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

Способ В. Запрос к базе данных:

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Док.Проведен КАК Проведен
    |ИЗ
    |	Документ.РеализацияТоваровУслуг КАК Док
    |ГДЕ
    |	Док.Ссылка = &Ссылка";

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

Если Выборка.Следующий() И Выборка.Проведен Тогда
    // Документ проведен
КонецЕсли;

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

← На главную