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