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