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

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

При разработке управляемых форм часто возникает задача уведомить пользователя об ошибке в конкретной ячейке табличной части. Для ссылочных объектов конфигурации (документов, справочников) обычно заполняется свойство КлючДанных, куда передается ссылка на объект. Однако у встроенных и внешних обработок ссылки в базе данных нет. При попытке вывести оповещение разработчики сталкиваются с тем, что сообщение об ошибке позиционируется не на конкретную строку, а привязывается ко всей табличной части в целом.

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

Почему сообщение привязывается ко всей таблице, а не к строке

Проанализируем ключевые особенности механизма СообщениеПользователю в управляемом интерфейсе:

  1. Невозможность позиционирования на строку целиком. Платформа «1С:Предприятие» не умеет фокусировать фокус ввода просто на строку вида ТабличнаяЧасть[0]. Чтобы система смогла активировать поле на форме, в пути обязательно должно присутствовать имя колонки или реквизита строки: ТабличнаяЧасть[Индекс].ИмяКолонки. Если указать только имя коллекции и индекс строки, фокус всегда будет сбрасываться на табличное поле целиком.
  2. Отсутствие ссылки у обработки. Свойство КлючДанных предназначено строго для идентификации объектов информационной базы (ссылок или ключей записей регистров). Для обработок заполнять КлючДанных не требуется: связь с формой выполняется через свойства ПутьКДанным и Поле.
  3. Нумерация индексов с нуля. В системном свойстве НомерСтроки табличной части нумерация начинается с единицы, тогда как в свойстве Поле объекта СообщениеПользователю используется индекс коллекции, начинающийся с нуля (0-based). Передача некорректного индекса приводит к тому, что платформа не находит строку и смещает фокус на всю таблицу.
  4. Неявное форматирование чисел. При формировании пути через сложение строк (например, "ТабЧасть[" + Индекс + "]") для строк с индексом 1000 и выше стандартная локализация 1С автоматически добавляет неразрывный пробел (разделитель групп разрядов: 1 000). Такой синтаксис ломает путь к данным, и платформенная привязка перестает работать.

Способ 1. Вывод сообщения из модуля управляемой формы

Рассмотрим базовый сценарий проверки данных непосредственно в модуле формы обработки (на клиенте или на сервере без создания объекта). В этом случае у формы уже есть контекст реквизита Объект.

Посмотрим на пример кода, в котором выполняется обход строк и выдача сообщения с точной привязкой к ячейке:


&НаКлиенте
Процедура ПроверитьТабличнуюЧастьНаКлиенте()

    Для Каждого СтрокаТЧ Из Объект.ТабличнаяЧасть Цикл
        
        Если Не ЗначениеЗаполнено(СтрокаТЧ.Реквизит1) Тогда
            
            // Вычисляем индекс строки (начиная с 0)
            ИндексСтроки = Объект.ТабличнаяЧасть.Индекс(СтрокаТЧ);
            
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = "Не заполнено обязательное поле!";
            
            // Задаем реквизит формы, к которому привязана табличная часть
            Сообщение.ПутьКДанным = "Объект";
            
            // Обязательно убираем группировку разрядов через параметр ЧГ=0
            Сообщение.Поле = "ТабличнаяЧасть[" + Формат(ИндексСтроки, "ЧГ=0") + "].Реквизит1";
            
            Сообщение.Сообщить();
            
        КонецЕсли;
        
    КонецЦикла;

КонецПроцедуры

Разберем важную альтернативу: свойство ПутьКДанным можно не заполнять отдельно, если указать полный путь к реквизиту прямо в свойстве Поле:


Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Поле заполнено некорректно";
Сообщение.Поле = "Объект.ТабличнаяЧасть[" + Формат(ИндексСтроки, "ЧГ=0") + "].Реквизит1";
Сообщение.Сообщить();

Обратите внимание: если таблица создана на форме не как табличная часть реквизита Объект, а как отдельный реквизит формы с типом ТаблицаЗначений (например, ТаблицаФормы), указывать ПутьКДанным = "Объект" нельзя. В этом случае свойство ПутьКДанным оставляем пустым, а в Поле пишем имя реквизита формы: "ТаблицаФормы[" + Формат(ИндексСтроки, "ЧГ=0") + "].ИмяКолонки".

Способ 2. Вывод сообщения из модуля объекта обработки

Если алгоритм валидации данных вынесен в модуль объекта (ОбработкаОбъект), стандартный вызов Сообщение.УстановитьДанные(ЭтотОбъект) не сможет самостоятельно связать сообщение с конкретным элементом формы, так как у объекта нет ссылки. Для решения этой задачи перед вызовом серверных методов объекта необходимо зарегистрировать соответствие между формой и объектом обработки.

Разберем реализацию по шагам.

  1. В модуле формы получаем объект обработки, устанавливаем соответствие и вызываем расчет:

&НаСервере
Процедура ВыполнитьПроверкуНаСервере()

    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    
    // Передаем контекст формы в объект
    ПараметрыСоответствия = Новый Структура;
    ПараметрыСоответствия.Вставить("ИдентификаторФормы", УникальныйИдентификатор);
    ПараметрыСоответствия.Вставить("ИмяРеквизита", "Объект");
    
    УстановитьСоответствиеОбъектаИФормы(ОбработкаОбъект, ПараметрыСоответствия);
    
    // Запускаем проверку
    ОбработкаОбъект.ПроверитьДанные();

КонецПроцедуры
  1. В модуле объекта используем метод УстановитьДанные совместно с точным путем к полю:

Процедура ПроверитьДанные() Экспорт

    Для Каждого СтрокаТЧ Из ТабличнаяЧасть Цикл
        
        Если СтрокаТЧ.Количество <= 0 Тогда
            
            Индекс = ТабличнаяЧасть.Индекс(СтрокаТЧ);
            
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = "Количество должно быть больше нуля!";
            Сообщение.Поле = "ТабличнаяЧасть[" + Формат(Индекс, "ЧГ=0") + "].Количество";
            
            // Связываем сообщение с текущим экземпляром объекта
            Сообщение.УстановитьДанные(ЭтотОбъект);
            
            Сообщение.Сообщить();
            
        КонецЕсли;
        
    КонецЦикла;

КонецПроцедуры

Способ 3. Использование функций «Библиотеки стандартных подсистем» (БСП)

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


ИндексСтроки = Объект.ТабличнаяЧасть.Индекс(СтрокаТЧ);
ПутьКПолю = "ТабличнаяЧасть[" + Формат(ИндексСтроки, "ЧГ=0") + "].Реквизит1";

ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
    "Укажите значение реквизита",
    ,
    ПутьКПолю,
    "Объект"
);

Программная активизация строки в дополнение к сообщению

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


&НаКлиенте
Процедура ПерейтиКСтроке(ИндексСтроки, ИмяКолонки)

    ИдентификаторСтроки = Объект.ТабличнаяЧасть[ИндексСтроки].ПолучитьИдентификатор();
    
    // Активируем строку таблицы
    Элементы.ТабличнаяЧасть.ТекущаяСтрока = ИдентификаторСтроки;
    
    // Переводим фокус на конкретную колонку
    Элементы.ТабличнаяЧасть.ТекущийЭлемент = Элементы["ТабличнаяЧасть" + ИмяКолонки];

КонецПроцедуры

Таким образом, для корректной работы СообщениеПользователю в обработках достаточно помнить три правила: не пытаться заполнять КлючДанных, обязательно указывать имя конкретной колонки в индексе и подавлять группировку разрядов числа с помощью формата ЧГ=0.

← На главную