Как программно настроить оформление и доступность строк табличной части в управляемых формах 1С

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

В процессе разработки на платформе 1С 8.3 часто возникает задача динамического управления доступностью ячеек в табличной части. Например, когда редактирование конкретной колонки "Значение" должно быть разрешено только в том случае, если в колонке "Показатель" выбран элемент с определенным признаком. Рассмотрим, как правильно реализовать такую логику, разберем типичные ошибки и проанализируем различные подходы к решению этой задачи.

Метод 1: Программное создание Условного Оформления

Использование механизма Условного Оформления (УО) — это наиболее "правильный" и нативный способ для управляемых форм. Он позволяет платформе самостоятельно отрисовывать элементы интерфейса в зависимости от данных, не перегружая клиент-серверное взаимодействие при каждом клике. Разберем пошагово, как программно добавить правила оформления для табличной части.

Проанализируем типичную ситуацию: у нас есть пять пар колонок (Показатель1 — Значение1, Показатель2 — Значение2 и т.д.). Мы хотим, чтобы поле "Значение" было доступно для редактирования только если у соответствующего "Показателя" в базе данных стоит флаг ЗаполняетсяВДокументе.

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


&НаСервере
Функция ПолучитьСписокПоказателейКРедактированию()
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Ссылка
        |ИЗ
        |   Справочник.ПоказателиРасчетаЗаработнойПлаты
        |ГДЕ
        |   ЗаполняетсяВДокументе = ИСТИНА";
    
    РезультатЗапроса = Запрос.Выполнить();
    Список = Новый СписокЗначений;
    Список.ЗагрузитьЗначения(РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка"));
    Возврат Список;
КонецФункции

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


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

Критически важные нюансы при работе с Условным Оформлением

Разберем основные причины, по которым "лыжи не едут", то есть оформление не применяется, даже если код написан без ошибок:

  1. Различие между Путем к данным и Именем элемента. В коллекции Отбор мы всегда используем путь к данным (например, Объект.ВидыРасчетов.Номенклатура). В коллекции Поля мы указываем имя колонки, как она названа в дереве элементов формы (например, ВидыРасчетовНоменклатура). Если их перепутать, правило просто проигнорируется.
  2. ТолькоПросмотр vs Доступность. Условное оформление позволяет управлять свойством ТолькоПросмотр. Это означает, что пользователь сможет кликнуть в ячейку, но не сможет изменить значение. Свойством Доступность (которое делает поле серым и "некликабельным") через УО управлять нельзя — это ограничение платформы.
  3. Приоритет правил. Если для одной ячейки срабатывают два правила, приоритет будет у того, которое находится ниже в списке УсловноеОформление.Элементы.
  4. Оптимизация условий. Выполнение запроса в цикле или при каждом обновлении формы — плохая практика. Лучше выгрузить данные один раз при открытии или использовать скрытые реквизиты.

Метод 2: Использование скрытых реквизитов для упрощения УО

Проанализируем ситуацию: обращение через точку в условии (Показатель1.ЗаполняетсяВДокументе) может замедлять работу интерфейса, так как платформе приходится подтягивать данные из базы для каждой строки. Выясним, как это оптимизировать.

Рассмотрим следующий алгоритм:

  1. Добавим в табличную часть формы (в данные, а не только в элементы) невидимую колонку Булево, например, НужноРедактировать1.
  2. При заполнении таблицы или при изменении показателя будем устанавливать значение в это поле.
  3. В Условном Оформлении настроим отбор просто по этому полю: Если Объект.ВидыРасчетов.НужноРедактировать1 = Ложь Тогда ТолькоПросмотр = Истина.

Это значительно упростит отбор в УО и сделает интерфейс более отзывчивым.

Метод 3: Использование событий формы (ПриАктивацииЯчейки)

Если Условное Оформление по какой-то причине не подходит (например, требуется именно программная блокировка Доступность = Ложь или сложная логика, которую невозможно описать в компоновке данных), можно использовать обработчики событий таблицы.

Рассмотрим событие ПриАктивацииЯчейки. Оно срабатывает каждый раз, когда пользователь перемещает фокус. В этом обработчике мы можем динамически менять свойства элементов формы.


&НаКлиенте
Процедура ВидыРасчетовПриАктивацииЯчейки(Элемент)
    ТекущиеДанные = Элементы.ВидыРасчетов.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Определяем имя текущей колонки
    ИмяТекущейКолонки = Элементы.ВидыРасчетов.ТекущийЭлемент.Имя;
    
    // Пример логики для одной из колонок
    Если ИмяТекущейКолонки = "ВидыРасчетовЗначениеПоказателя1" Тогда
        // Проверяем условие (флаг может быть в скрытой колонке или кэше)
        ДоступноРедактирование = ПроверитьДоступностьНаСервере(ТекущиеДанные.Показатель1);
        Элементы.ВидыРасчетовЗначениеПоказателя1.ТолькоПросмотр = НЕ ДоступноРедактирование;
    КонецЕсли;
КонецПроцедуры

Внимание: Будьте осторожны с серверными вызовами внутри ПриАктивацииЯчейки. Это событие вызывается очень часто, и любые "походы" на сервер приведут к серьезным задержкам интерфейса. Если используете этот метод, все данные для проверки условий должны быть уже доступны на клиенте в текущей строке.

Метод 4: Событие ПередНачаломИзменения

Посмотрим на ситуацию с точки зрения надежности. Условное оформление — это визуализация. Если же нам нужно гарантированно запретить вход в режим редактирования, лучше всего использовать событие таблицы ПередНачаломИзменения.


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

Этот метод считается наиболее жестким и надежным способом контроля ввода данных в табличных частях.

Резюме и рекомендации

Подводя итог, выберем оптимальную стратегию оформления строк табличной части:

  1. Для визуального выделения (цвет фона, цвет текста, шрифт) и базового запрета редактирования (ТолькоПросмотр) всегда используйте Условное Оформление.
  2. Для высокой производительности выносите условия оформления в скрытые колонки табличной части типа Булево, чтобы избежать обращений через точку в условиях отбора.
  3. Если нужно программно блокировать ввод с уведомлением пользователя, используйте обработчик ПередНачаломИзменения.
  4. Никогда не забывайте, что в ПолеКомпоновкиДанных для отбора нужно писать Объект.ИмяТаблицы.ИмяПоля, а для оформляемых полей — просто ИмяЭлементаКолонки.

Применяя эти подходы, мы создаем гибкий, понятный и быстрый интерфейс, который помогает пользователю корректно вводить данные и предотвращает ошибки на раннем этапе.

← На главную