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