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