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