При разработке конфигураций и доработке типовых решений на платформе 1С:Предприятие 8.3 часто возникает задача проверить, проведен ли документ. Способ получения этого признака напрямую зависит от контекста выполнения программного кода: пишем ли мы логику в модуле объекта, в модуле управляемой формы, в обработчике команды или выполняем проверку произвольной ссылки на сервере. Разберем подробно каждый из этих случаев.
В модуле самого документа (например, в обработчиках событий ПередЗаписью, ОбработкаПроведения или в экспортных процедурах) доступен контекст самого объекта. Встроенный язык платформы предоставляет прямое свойство Проведен типа Булево.
Рассмотрим, как правильно обращаться к этому свойству внутри модуля документа:
Если Проведен Тогда
// Документ в текущем состоянии объекта помечен как проведенный
Сообщить("Документ проведен");
Иначе
Сообщить("Документ не проведен");
КонецЕсли;
Также допустимо явное обращение через системное свойство ЭтотОбъект:
Если ЭтотОбъект.Проведен Тогда
// Выполняем действия для проведенного документа
КонецЕсли;
Важный нюанс: свойство Проведен в модуле объекта отражает состояние данных в оперативной памяти перед записью. Если документ проводится прямо сейчас, свойство Проведен уже будет равно Истина. Если нам требуется узнать, был ли документ проведен в базе данных до начала текущей транзакции записи, следует проверить свойство ссылки:
Если Не ЭтоНовый() И Ссылка.Проведен Тогда
// Документ уже был проведен в базе данных до текущего изменения
КонецЕсли;
В модуле управляемой формы основным реквизитом документа обычно выступает Объект (тип ДанныеФормыСтруктура). На клиенте и на сервере формы свойство проведенности доступно напрямую через данный реквизит.
Посмотрим на пример проверки в контексте формы:
Если Объект.Проведен Тогда
Сообщить("Документ проведен");
Иначе
Сообщить("Документ не проведен");
КонецЕсли;
Обратите внимание: переменные ТекущийДокумент или ЭтотОбъект в управляемой форме не содержат реквизитов документа и обращение к ним для проверки статуса проведения вызовет ошибку компиляции.
В модулях команд (как общих, так и принадлежащих конкретному документу) контекст формы и реквизит Объект отсутствуют. При вызове обработчика ОбработкаКоманды ссылка на текущий документ передается в параметре ПараметрКоманды.
Разберем по шагам, как обработать команду с учетом клиент-серверного взаимодействия:
ОбработкаКоманды выполняется на клиенте (директива &НаКлиенте).ПараметрКоманды.Проведен) недопустимо или вызывает неявный вызов сервера. Поэтому проверку следует выносить в серверную процедуру или функцию.ПараметрКоманды приходит Массив ссылок, который необходимо обработать циклом.Посмотрим на типовую реализацию проверки в модуле команды:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// Передаем ссылку на сервер для проверки
ДокументПроведен = ПроверитьПроведениеНаСервере(ПараметрКоманды);
Если ДокументПроведен Тогда
ПоказатьОповещениеПользователю("Статус", , "Документ проведен");
Иначе
ПоказатьОповещениеПользователю("Статус", , "Документ не проведен");
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПроверитьПроведениеНаСервере(СсылкаНаДокумент)
// На сервере свойство Проведен доступно у типа ДокументСсылка
Возврат СсылкаНаДокумент.Проведен;
КонецФункции
Если в серверном коде у нас есть только переменная типа ДокументСсылка, мы можем прочитать признак проведения несколькими способами:
Способ А. Прямое обращение через точку (на сервере):
Если СсылкаНаДокумент.Проведен Тогда
// Документ проведен в информационной базе
КонецЕсли;
Способ Б. Использование функции БСП (Библиотеки Стандартных Подсистем):
В типовых конфигурациях для оптимизации обращений к базе данных рекомендуется использовать функции общего назначения, которые считывают только требуемое поле без избыточного кэширования всего объекта:
БылПроведен = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаДокумент, "Проведен");
Если БылПроведен Тогда
// Действия при проведенном документе
КонецЕсли;
Способ В. Запрос к базе данных:
При пакетной обработке большого массива документов наиболее производительным решением является использование запроса к таблице документа:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Док.Проведен КАК Проведен
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Док
|ГДЕ
| Док.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() И Выборка.Проведен Тогда
// Документ проведен
КонецЕсли;
Таким образом, выбор конструкции зависит от того, где именно выполняется проверка: внутри модуля объекта используется свойство Проведен или ЭтотОбъект.Проведен, на управляемой форме — Объект.Проведен, а в командах и серверных алгоритмах — чтение реквизита переданной ссылки.