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