При работе с управляемыми формами в системе 1С:Предприятие, многие разработчики сталкиваются с необходимостью динамического управления свойствами элементов. Одним из таких сложных сценариев является управление свойствами отдельных ячеек в элементе формы ТаблицаФормы, например, их доступностью, кнопкой выбора или списком выбора.
Рассмотрим ситуацию: нам требуется изменить свойство конкретной ячейки, находящейся в определенной строке и колонке таблицы, без прямого "клика" по ней или активации. Иными словами, мы хотим получить объект ячейки программно, по ее "координатам", и изменить его свойства.
К сожалению, прямого программного интерфейса для доступа к произвольной ячейке таблицы формы (как к отдельному объекту со своими свойствами) по ее координатам (строка, колонка) для изменения ее свойств вне текущей активизированной строки или ячейки в управляемых формах 1С не существует. Это фундаментальное ограничение платформы, обусловленное архитектурой управляемых форм, ориентированной на производительность и динамическую отрисовку только видимых элементов.
Однако, это не означает, что мы не можем достичь желаемого результата. Платформа 1С предоставляет ряд мощных механизмов, которые позволяют реализовать большинство сценариев управления поведением и внешним видом ячеек, хоть и не через прямой доступ к "объекту ячейки". Рассмотрим эти подходы подробнее.
Для большинства задач, связанных с изменением внешнего вида, доступности, видимости, режима редактирования ячеек, УсловноеОформление является наиболее эффективным и рекомендуемым инструментом. Пользователь в ветке форума упоминал, что оно не решает все его проблемы (например, `КнопкаВыбора`), но для `Доступность` и `ТолькоПросмотр` это идеальное решение.
Принцип работы: Мы определяем наборы условий и параметры оформления. Когда данные в таблице соответствуют условию, платформа автоматически применяет указанные параметры оформления к соответствующим ячейкам.
Что можно настроить:
Доступность (можно сделать ячейку недоступной для редактирования).Видимость (скрыть ячейку).ТолькоПросмотр (сделать ячейку доступной, но нередактируемой, что отличается от недоступности).ЦветФона, ЦветТекста, Шрифт.Подсказка.Картинка.Преимущества:
Пример:
Допустим, нам нужно сделать поле "Количество" недоступным, если "ТипОперации" равен "Возврат". Мы настраиваем УсловноеОформление для колонки "Количество", добавляя условие Поле.ТипОперации = Перечисления.ТипыОпераций.Возврат и устанавливая для этого условия параметр Доступность = Ложь.
Важно понимать, что УсловноеОформление работает на уровне данных, то есть оно реагирует на изменения в связанном реквизите таблицы и применяется при отрисовке.
Программная настройка Условного оформления:
Хотя часто УсловноеОформление настраивается в конфигураторе, его можно динамически изменять и программно. Рассмотрим пример программной настройки:
// Пример программной настройки условного оформления
// Получаем элемент условного оформления
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
// Настраиваем условие
УсловиеОформления = ЭлементОформления.Условие.Элементы.Добавить(Тип("ЭлементУсловногоОформленияКомпоновкиДанных"));
УсловиеОформления.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.ТаблицаТоваров.ТипОперации");
УсловиеОформления.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
УсловиеОформления.ПравоеЗначение = Перечисления.ТипыОпераций.Возврат;
// Настраиваем оформляемые поля
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("Объект.ТаблицаТоваров.Количество");
ПолеОформления.Использование = Истина;
// Настраиваем параметры оформления
ЭлементОформления.Оформление.Установить("Доступность", Ложь);
ПриНачалеВыбора и ОбработкаВыбораСценарий: Когда УсловноеОформление не может решить задачу, как, например, динамическое изменение КнопкаВыбора или СписокВыбора для конкретной ячейки. Пользователь форума как раз приводил пример с КнопкаВыбора = Ложь для ячейки.
Принцип: Эти события срабатывают в момент, когда пользователь пытается взаимодействовать с полем выбора в ячейке. В их обработчиках мы получаем доступ к параметрам выбора и можем их динамически изменять.
Событие ПриНачалеВыбора:
Происходит, когда пользователь нажимает кнопку выбора, F4 или начинает вводить текст в поле, что инициирует процесс выбора значения.
В этом событии мы можем программно определить, будет ли доступна кнопка выбора, какой будет список выбора, нужно ли использовать режим выбора из списка и т.д.
Параметры, доступные для управления: КнопкаВыбора, СписокВыбора, РежимВыбораИзСписка, СтандартнаяОбработка, ДанныеВыбора (если хотим передать параметры в форму выбора) и другие.
// Пример в обработчике события ПриНачалеВыбора для поля таблицы
&НаКлиенте
Процедура ТаблицаТоваровКоличествоПриНачалеВыбора(Элемент, СтандартнаяОбработка)
// Определяем текущую строку данных
ТекущаяСтрока = Элементы.ТаблицаТоваров.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
// Если тип операции "Услуга", то не показываем кнопку выбора (например, если поле - это ссылка)
Если ТекущаяСтрока.ТипОперации = Перечисления.ТипыОпераций.Услуга Тогда
СтандартнаяОбработка = Ложь; // Отменяем стандартную обработку (открытие формы выбора)
// Можем также установить КнопкаВыбора = Ложь в свойствах элемента формы в конфигураторе
// и программно устанавливать СтандартнаяОбработка = Истина в других случаях,
// чтобы имитировать динамическое управление кнопкой.
// Для поля числового типа с кнопкой выбора (например, выбора из справочника)
// это будет работать немного иначе. Для кнопки выбора самого поля ввода
// обычно используется УсловноеОформление.
// Но для списка выбора это работает напрямую:
СписокЗначений = Новый СписокЗначений();
СписокЗначений.Добавить(1, "Один");
СписокЗначений.Добавить(2, "Два");
Элемент.СписокВыбора = СписокЗначений; // Передаем свой список выбора
Элемент.РежимВыбораИзСписка = Истина;
Иначе
// В других случаях стандартная обработка разрешена
СтандартнаяОбработка = Истина;
КонецЕсли;
КонецПроцедуры
Событие ОбработкаВыбора:
Происходит после того, как пользователь выбрал значение. Позволяет перехватить выбранное значение (ВыбранноеЗначение) и выполнить дополнительные действия. Позволяет модифицировать или подтвердить выбранное значение.
ПриАктивизацииЯчейки / ПриАктивизацииПоляСценарий: Как упоминалось в обсуждении, эти события предоставляют доступ к ТекущемуЭлементу, который является именно той ячейкой, в которую пользователь "ткнул" или которая получила фокус.
Принцип: В обработчике этих событий вы получаете объект элемента формы, соответствующий активизированной ячейке. Вы можете программно изменить его свойства.
Ограничение: Это изменение касается только текущей активной ячейки и требует взаимодействия пользователя (активации). Это не решает проблему "без активации", но является способом индивидуальной настройки ячейки, если активация приемлема.
// Пример в обработчике события ПриАктивизацииЯчейки для ТаблицыФормы
&НаКлиенте
Процедура ТаблицаФормыПриАктивизацииЯчейки(Элемент, Колонка, Строка)
// Получаем активное поле (ячейку)
ТекущееПоле = Элемент.ТекущийЭлемент;
// Пример: делаем кнопку выбора недоступной, если это поле "Цена" и значение в соседнем поле "Валюта" - "Рубли"
Если Колонка.Имя = "Цена" Тогда
Если Строка.Валюта = Справочники.Валюты.НайтиПоКоду("643") Тогда // Условный код для рублей
ТекущееПоле.КнопкаВыбора = Ложь;
Иначе
ТекущееПоле.КнопкаВыбора = Истина;
КонецЕсли;
КонецЕсли;
// Важно: Эти изменения будут видны только для этой конкретной ячейки, пока она активна.
// При уходе фокуса могут потребоваться дополнительные действия для сохранения поведения.
// Для постоянного поведения на основе данных используйте УсловноеОформление или НачалоВыбора.
КонецПроцедуры
Важный нюанс: Изменения, сделанные через ТекущийЭлемент в ПриАктивизацииЯчейки, могут быть не персистентными. То есть, при уходе фокуса с ячейки, ее свойства могут вернуться к значениям, заданным в конфигураторе или через УсловноеОформление, если не предусмотрен механизм их повторной установки.
Сценарий: Если вы изменяете данные, к которым привязана таблица, и эти изменения должны повлиять на УсловноеОформление или другие динамические свойства, вам может потребоваться обновить отображение формы.
Методы:
Элементы.ИмяТаблицыФормы.Обновить(); – Метод элемента формы для обновления его содержимого.ОбновитьОтображениеДанных(); – Метод формы, который вызывает обновление всех элементов формы, связанных с реквизитами формы.Принцип: Эти методы заставляют платформу перерисовать соответствующие части формы, что, в свою очередь, приводит к повторному применению УсловногоОформления и пересчету динамических свойств на основе актуальных данных.
// Пример: После изменения значения в реквизите, связанном с таблицей
// Например, изменили флаг "РазрешитьРедактирование" для текущей строки
Объект.ТаблицаТоваров[НомерСтроки].РазрешитьРедактирование = Ложь;
// Теперь нужно обновить отображение, чтобы УсловноеОформление сработало
Элементы.ТаблицаТоваров.Обновить();
// Или
// ОбновитьОтображениеДанных();
Мы выяснили, что прямой, "низкоуровневый" доступ к объекту произвольной ячейки таблицы формы без ее активации, с целью управления ее свойствами, в 1С:Предприятии (управляемые формы) отсутствует.
Однако, вместо попыток "обойти" архитектуру платформы, рекомендуется использовать предоставленные ею механизмы:
УсловноеОформление для управления большинством визуальных свойств и доступностью/редактируемостью ячеек на основе данных. Это наиболее производительный и поддерживаемый способ.ПриНачалеВыбора и ОбработкаВыбора.ПриАктивизацииЯчейки, но помните об их временном характере.Понимание этих архитектурных особенностей и правильное применение встроенных механизмов позволит нам создавать функциональные и производительные интерфейсы в 1С:Предприятии.