Как привязать СообщениеПользователю к ячейке таблицы на управляемой форме 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При валидации данных на управляемых формах часто требуется подвязать сообщение об ошибке к конкретной ячейке таблицы, чтобы платформа подсветила проблемное поле красной рамкой и показала всплывающую подсказку. Однако при работе со сложными структурами, когда в качестве колонки одной таблицы выступает вложенная таблица значений, стандартный синтаксис привязки перестает работать. Разберем причины такого поведения платформы 1С:Предприятие 8.3 и рассмотрим правильные варианты реализации данной задачи.

Почему возникает ошибка при указании вложенного пути

Проанализируем типичную ошибку при формировании свойства Поле объекта СообщениеПользователю. Попытка передать составной многоуровневый путь вида:

Таблица1[0].Таблица2[1].СтроковаяКолонка

приводит к тому, что платформа не может сопоставить строковый путь с визуальным элементом интерфейса. В результате сообщение либо выводится в общую панель сообщений формы без привязки к конкретной ячейке, либо многократно дублируется.

Выясним две ключевые причины этой проблемы:

  1. Ограничение парсера платформы: механизм СообщениеПользователю поддерживает адресацию табличных реквизитов только с одним уровнем индексации формата "ИмяТаблицы[ИндексСтроки].ИмяКолонки". Вложенные конструкции парсер платформы не обрабатывает.
  2. Путаница между индексом и идентификатором строки: свойство элемента формы Элементы.Таблица.ТекущаяСтрока возвращает числовой идентификатор строки (внутренний ключ строки в данных формы), а не её индекс (порядковый номер с нуля). Если строки добавлялись или удалялись, идентификатор не совпадает с индексом строки в коллекции.

Правильное получение индекса строки таблицы

Для корректной адресации ячейки в плоской таблице необходимо передавать порядковый индекс строки в коллекции данных формы, а не значение из ТекущаяСтрока. Рассмотрим, как получить правильный индекс:


// Получаем индекс текущей строки из коллекции ДанныеФормыКоллекция
ИндексСтроки = Таблица2.Индекс(Элементы.Таблица2.ТекущиеДанные);

Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Поле заполнено некорректно!";
Сообщение.Поле = "Таблица2[" + ИндексСтроки + "].СтроковаяКолонка";
Сообщение.Сообщить();

Основное решение: переход к плоской структуре реквизитов формы

Если требуется полноценная визуальная привязка сообщения к ячейкам второй таблицы, наилучшим архитектурным решением является отказ от хранения таблицы внутри ячейки другой таблицы. Разберем по шагам, как перестроить форму по принципу «Мастер — Деталь»:

  1. Создадим на форме два независимых реквизита верхнего уровня: Таблица1 и Таблица2 (тип ТаблицаЗначений или ДанныеФормыКоллекция).
  2. Разместим оба элемента на форме в виде двух связанных таблиц.
  3. В обработчике события Таблица1ПриАктивизацииСтроки будем динамически считывать и заполнять реквизит Таблица2 данными, относящимися к текущей активной строке Таблица1.
  4. Перед переключением строки или при записи формы сохраняем отредактированные данные Таблица2 обратно в структуру данных родительской строки.

Посмотрим на пример проверки данных при такой архитектуре в событии ПередОкончаниемРедактирования подчиненной таблицы:


&НаКлиенте
Процедура Таблица2ПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
    
    Если ОтменаРедактирования Тогда
        Возврат;
    КонецЕсли;
    
    ТекущиеДанные = Элементы.Таблица2.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем заполнение строки
    Если ПустаяСтрока(ТекущиеДанные.СтроковаяКолонка) Тогда
        Отказ = Истина;
        
        ИндексСтроки = Таблица2.Индекс(ТекущиеДанные);
        
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Необходимо заполнить строковую колонку!";
        Сообщение.Поле = "Таблица2[" + ИндексСтроки + "].СтроковаяКолонка";
        Сообщение.УстановитьДанные(ЭтотОбъект);
        Сообщение.Сообщить();
    КонецЕсли;
    
КонецПроцедуры

Альтернативные способы оповещения пользователя

Если реструктуризация реквизитов формы невозможна или нецелесообразна, рассмотрим альтернативные обходные пути для оповещения пользователя о некорректном вводе:

  1. Привязка сообщения к элементу формы целиком: можно указать в свойстве Поле имя самого элемента формы подчиненной таблицы или колонки без индекса (например, Сообщение.Поле = "Таблица2"). Сообщение привяжется к шапке таблицы, не вызывая сбоев адресации.
  2. Блокировка смены фокуса: в обработчике ПередОкончаниемРедактирования устанавливаем параметр Отказ = Истина и принудительно возвращаем курсор в нужный элемент с помощью свойства ТекущийЭлемент = Элементы.Таблица2СтроковаяКолонка.
  3. Условное оформление: добавляем в подчиненную таблицу служебную колонку ЕстьОшибка (тип Булево) и настраиваем условное оформление формы, чтобы подсвечивать ошибочные ячейки красным фоном.
  4. Всплывающие уведомления: используем процедуру ПоказатьОповещениеПользователя() или ПоказатьПредупреждение() для информирования пользователя без жесткой привязки к координатам управляемых элементов.
← На главную