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

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

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

Анализ типичной ошибки: Элементы vs Данные

Разберем ситуацию, с которой столкнулся автор темы. Попытка управлять доступностью через Элементы.Реквизит1 в обработчике ПриИзменении — это первая критическая точка. Важно понимать различие между элементом формы (визуальным представлением) и данными (тем, что хранится в объекте или таблице).

Когда мы пишем ПустаяСтрока(Элементы.Реквизит1), платформа пытается анализировать объект элемента управления, а не само значение, которое ввел пользователь. Это приводит к тому, что код либо работает нестабильно, либо вызывает ошибку «Проверка мутабельных значений на заполненность не поддерживается». Эта ошибка возникает, так как функция ЗначениеЗаполнено() не может обработать сложный программный объект элемента формы на стороне клиента.

Правильный подход: всегда обращаться к данным текущей строки через свойство ТекущиеДанные табличной части.

Способ 1. Условное оформление — рекомендуемый метод

Прежде чем приступать к написанию кода, проанализируем возможности платформы. Для управляемых форм «золотым стандартом» является Условное оформление. Это механизм, который работает на уровне платформы и не требует написания сложных обработчиков событий для каждой строки.

Рассмотрим по шагам, как настроить блокировку Реквизита2, если Реквизит1 заполнен, через интерфейс конфигуратора:

  1. Откроем форму документа и перейдем на закладку «Условное оформление».
  2. Добавим новое правило.
  3. В поле «Оформление» выберем свойство Только просмотр и установим значение Истина.
  4. В поле «Условие» укажем: Объект.ИмяВашейТЧ.Реквизит1 Заполнено.
  5. В поле «Оформляемые поля» выберем ИмяВашейТЧРеквизит2.

Этот метод предпочтительнее, так как он автоматически обрабатывает добавление новых строк, копирование и удаление данных без дополнительных вызовов серверного контекста.

Способ 2. Программное управление через события

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

Выясним причину, почему недостаточно только процедуры ПриИзменении. Если пользователь заполнил Реквизит1 в первой строке (колонка заблокировалась), а затем перешел во вторую пустую строку — колонка во второй строке может остаться заблокированной, если мы управляем элементом формы напрямую. Поэтому нам нужно обновлять состояние при активизации строки.

Создадим общую процедуру для управления состоянием и вызовем ее из нужных событий. Рассмотрим пример кода:


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

&НаКлиенте
Процедура ВашаТабличнаяЧастьРеквизит1ПриИзменении(Элемент)
    УстановитьДоступностьСтрокиТЧ();
КонецПроцедуры

&НаКлиенте
Процедура ВашаТабличнаяЧастьПриАктивизацииСтроки(Элемент)
    УстановитьДоступностьСтрокиТЧ();
КонецПроцедуры

Проанализируем этот код. Мы используем свойство ТолькоПросмотр. В отличие от Доступность, оно позволяет пользователю выделить текст в ячейке или скопировать его, при этом запрещая редактирование. Это делает интерфейс более дружелюбным.

Важные нюансы и оптимизация

При использовании программного метода (Способ 2) необходимо помнить о производительности. Процедура ПриАктивизацииСтроки срабатывает каждый раз, когда пользователь перемещает курсор по таблице. Рассмотрим основные правила оптимизации:

Использование скрытых реквизитов (флагов)

Бывают ситуации, когда условие доступности требует сложного расчета (например, проверки остатков на складе или прав доступа). В этом случае выполнять расчет на клиенте невозможно или долго. Разберем алгоритм решения такой задачи:

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

Посмотрим на пример серверного заполнения флага:


&НаСервере
Процедура РассчитатьФлагиДоступностиНаСервере()
    Для Каждого СтрокаТЧ Из Объект.ВашаТабличнаяЧасть Цикл
        // Здесь может быть сложная логика, запросы к БД и т.д.
        СтрокаТЧ.БлокировкаРедактирования = (СтрокаТЧ.Количество > 100); 
    КонецЦикла;
КонецПроцедуры

Таким образом, мы переносим тяжелые вычисления на сервер, а интерфейс оставляем легким и отзывчивым за счет использования механизма условного оформления, привязанного к значению этого флага.

Подводя итог, можно сказать: если ваша задача решается через Условное оформление — всегда выбирайте его. Если же логика требует динамического изменения в процессе ввода данных пользователем, используйте комбинацию событий ПриИзменении и ПриАктивизацииСтроки, работая строго с ТекущиеДанные на стороне клиента.

← На главную