При разработке интерфейсов на управляемых формах в «1С:Предприятие» перед нами часто встает задача валидации данных в табличных частях. Стандартный механизм, предоставляемый платформой — это использование объекта СообщениеПользователю. С его помощью мы можем привязать текст ошибки к конкретному объекту, табличной части, строке и даже ячейке (колонке). Пользователь видит удобный красный маркер непосредственно в проблемной ячейке, что значительно упрощает исправление ошибок.
Однако у этого механизма есть существенный побочный эффект: при вызове метода Сообщить() платформа автоматически открывает системную панель (окно) сообщений в нижней части экрана. Если строк с ошибками много, это окно перекрывает полезную рабочую область экрана, раздражает пользователей и заставляет их вручную закрывать панель. Попытки использовать метод ОчиститьСообщения() приводят к тому, что очищается как само окно, так и маркеры ошибок в ячейках таблицы.
В этой статье мы подробно разберем, почему платформа ведет себя именно так, и рассмотрим эффективные альтернативные способы подсветки ошибок в строках табличной части, которые позволяют полностью обойти это ограничение и сделать интерфейс программы максимально дружелюбным.
Проанализируем архитектуру работы объекта СообщениеПользователю. Данный объект глубоко интегрирован в платформу «1С:Предприятие». Его основное назначение — гарантировать, что пользователь увидит важную информацию (ошибку валидации, предупреждение или системное уведомление) при попытке записи или проведения документа.
Когда мы пишем следующий код:
Для каждого Строка из НашаТаблица Цикл
Если Строка.БруттоДефицит <> 0 Тогда
ТекНомерСтроки = Строка.НомерСтроки;
Сообщение = Новый СообщениеПользователю;
Сообщение.Поле = "РасходСырья[" + (ТекНомерСтроки - 1) + "].БруттоДефицит";
Сообщение.Текст = "Строка [" + Строка.НомерСтроки + "]. Не хватает " + Строка.БруттоДефицит;
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
КонецЕсли;
КонецЦикла;
Метод Сообщить() выполняет сразу два действия на уровне платформы:
Текст.К сожалению, в платформе 1С отсутствует свойство вроде Сообщение.ВыводитьТолькоВПоле = Истина или возможность программно свернуть панель сообщений после вывода. Нам приходится искать обходные пути.
Это самый элегантный, производительный и рекомендуемый стандарт разработки 1С способ визуализации ошибок в управляемом интерфейсе. Вместо генерации системных сообщений мы будем динамически раскрашивать ячейки с ошибками.
Разберем реализацию этого метода по шагам:
Шаг 1. Добавление служебного реквизита
В табличную часть вашего объекта (или в созданную таблицу формы) добавьте новую колонку (реквизит) с именем ЕстьДефицит (тип Булево) или ОшибкаЗаполнения (тип Строка), если вы хотите выводить разные типы предупреждений.
Шаг 2. Настройка условного оформления формы
Вы можете настроить условное оформление интерактивно в конфигураторе или программно при создании формы. Программный способ предпочтительнее, так как он защищен от случайного удаления при визуальном редактировании формы. Разместим код настройки в обработчике ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Добавляем элемент условного оформления
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
// 1. Что оформляем (красный фон для ячейки БруттоДефицит)
ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("РасходСырьяБруттоДефицит");
// 2. Как оформляем (задаем светло-красный цвет фона)
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоРозовый);
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ВыделятьОтрицательные", Истина);
// 3. При каком условии (если наш служебный флаг равен Истина)
ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.РасходСырья.ЕстьДефицит");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Истина;
КонецПроцедуры
Шаг 3. Код проверки данных в таблице
Теперь перепишем наш алгоритм проверки. Вместо создания объектов сообщений мы будем просто взводить флаг в строках таблицы:
&НаКлиенте или &НаСервереБезКонтекста
Процедура ПроверитьДефицитСырья()
Для каждого Строка из Объект.РасходСырья Цикл
// Проверяем условие дефицита
Если Строка.БруттоДефицит > 0 Тогда
Строка.ЕстьДефицит = Истина;
Иначе
Строка.ЕстьДефицит = Ложь;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Результат: Ячейки, где обнаружен дефицит, мгновенно окрасятся в мягкий красный цвет. При этом никакого всплывающего окна внизу формы не появится, а пользователь сразу поймет, где допущена ошибка.
Если пользователю недостаточно просто видеть раскрашенную ячейку и ему нужно прочитать текстовое описание проблемы (например: «Не хватает 5 кг сырья»), мы можем вывести текст ошибки прямо в строку таблицы.
Рассмотрим, как это сделать:
СтатусПроверки с типом Строка.ТолькоПросмотр = Истина).
&НаКлиенте
Процедура ПроверитьЗаполнениеТаблицы()
Для каждого Строка из Объект.РасходСырья Цикл
Если Строка.БруттоДефицит <> 0 Тогда
Строка.СтатусПроверки = "Не хватает " + Строка.БруттоДефицит + " " + Строка.Сырье;
Иначе
Строка.СтатусПроверки = "ОК";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Чтобы интерфейс выглядел современно, объедините этот подход с условным оформлением: строки со значением "ОК" можно окрасить в блекло-зеленый цвет текста, а строки с описанием нехватки — в красный.
Часто разработчики не хотят перегружать ширину таблицы дополнительными текстовыми колонками с ошибками. В таком случае мы можем выводить текст ошибки динамически в специальную надпись под табличной частью, реагируя на перемещение курсора пользователя.
Рассмотрим реализацию данного паттерна:
Шаг 1. Подготовка интерфейса формы
Добавьте на форму под вашей табличной частью элемент декорации типа Надпись (например, с именем ДекорацияИнформацияОбОшибке). Установите для нее красный цвет текста.
Шаг 2. Написание обработчика активизации строки
Создайте на клиенте обработчик события ПриАктивизацииСтроки для вашей таблицы:
&НаКлиенте
Процедура РасходСырьяПриАктивизацииСтроки(Элемент)
ТекущиеДанные = Элемент.ТекущиеДанные;
// Проверяем, что в таблице есть строки и строка выделена
Если ТекущиеДанные = Неопределено Тогда
Элементы.ДекорацияИнформацияОбОшибке.Заголовок = "";
Возврат;
КонецЕсли;
// Если у текущей строки есть дефицит, выводим подсказку
Если ТекущиеДанные.БруттоДефицит > 0 Тогда
Элементы.ДекорацияИнформацияОбОшибке.Заголовок = "Внимание! Строка № " + ТекущиеДанные.НомерСтроки
+ ": Не хватает " + ТекущиеДанные.БруттоДефицит + " ед. сырья (" + ТекущиеДанные.Сырье + ")";
Элементы.ДекорацияИнформацияОбОшибке.Видимость = Истина;
Иначе
// Скрываем надпись, если в строке все нормально
Элементы.ДекорацияИнформацияОбОшибке.Заголовок = "";
Элементы.ДекорацияИнформацияОбОшибке.Видимость = Ложь;
EndIf;
КонецПроцедуры
Результат: Этот подход экономит место на экране. Пользователь перемещается по строкам таблицы, и под ней оперативно обновляется детальная расшифровка ошибки по текущей строке. Никаких раздражающих всплывающих снизу панелей!
Если ваша задача — просто уведомить пользователя о том, что в процессе расчета или проверки возникли ошибки, но при этом жестко привязывать каждую строчку к ошибке не обязательно, воспользуйтесь современным механизмом неблокирующих всплывающих уведомлений («toast-сообщений»).
Вместо метода Сообщить() используйте глобальную процедуру ПоказатьОповещениеПользователя:
&НаКлиенте
Процедура ВыполнитьПроверкуИОповестить()
КоличествоОшибок = 0;
Для каждого Строка из Объект.РасходСырья Цикл
Если Строка.БруттоДефицит > 0 Тогда
КоличествоОшибок = КоличествоОшибок + 1;
КонецЕсли;
КонецЦикла;
Если КоличествоОшибок > 0 Тогда
ТекстОповещения = "Обнаружены ошибки в " + КоличествоОшибок + " строках табличной части!";
ПоказатьОповещениеПользователя(
"Проверка заполнения", // Заголовок окна
"ПолучитьНавигационнуюСсылкаФормы()", // Действие при клике (опционально)
ТекстОповещения, // Текст сообщения
БиблиотекаКартинок.Важно // Иконка
);
КонецЕсли;
КонецПроцедуры
Такое уведомление плавно появится в правом нижнем углу экрана монитора, не прерывая ввод данных, и автоматически исчезнет через несколько секунд. Оно отлично подходит для общей фоновой информации.
Для удобства выбора оптимального механизма спроектируем небольшую сравнительную таблицу характеристик описанных методов:
| Метод решения | Влияние на эргономику | Сложность реализации | Привязка к ячейке |
|---|---|---|---|
| Условное оформление | Отличное (фокусирует внимание цветом) | Низкая | Да (точная подсветка поля) |
| Колонка статуса ошибки | Хорошее (виден текст ошибки прямо в строке) | Низкая | Да (в рамках строки) |
| ПриАктивизацииСтроки + Декорация | Отличное (информация выводится контекстно) | Средняя | Да (привязано к текущей строке) |
| ПоказатьОповещениеПользователя | Высокое (мягкое всплывающее уведомление) | Минимальная | Нет (общее оповещение) |
Изучив данные методы, мы видим, что наиболее эффективным решением исходной задачи является связка Условного оформления (для моментальной визуальной идентификации проблемной ячейки) и динамического вывода подробного описания ошибки в Декорацию-надпись на форме при активизации строки. Это позволит вам полностью отказаться от устаревших всплывающих окон сообщений платформы и предоставить пользователям удобный, современный и отзывчивый интерфейс системы 1С.