Как отключить доступность колонок в конкретной строке табличной части в 1С?

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

При разработке интерфейсов в 1С часто возникает задача: сделать так, чтобы при определенных условиях (например, при установке флажка "Принято в работу") некоторые ячейки в этой же строке становились недоступными для редактирования. Начинающие разработчики часто пытаются решить эту задачу "в лоб", изменяя свойство доступности всей колонки формы: Элементы.ИмяКолонки.Доступность = Ложь. Однако это приводит к тому, что колонка блокируется сразу во всей таблице, во всех строках.

В этой статье мы подробно разберем, как правильно реализовать ограничение доступности ячеек для одной конкретной строки. Мы рассмотрим решения как для современных Управляемых форм (включая декларативный метод и программные обработчики), так и для классических Обычных форм.

Почему нельзя использовать событие "ПриАктивизацииСтроки"?

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

Мы настоятельно не рекомендуем использовать этот метод по следующим причинам:

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

Теперь рассмотрим правильные и производительные способы реализации этой задачи.

---

Вариант 1. Управляемые формы: Использование условного оформления (Рекомендуемый способ)

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

Способ А. Интерактивная настройка в Конфигураторе

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

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

Способ Б. Программная настройка условного оформления

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Добавляем новый элемент условного оформления
    ЭлементОформления = УсловноеОформление.Элементы.Добавить();
    
    // 1. Задаем оформление: устанавливаем свойство "ТолькоПросмотр" в значение Истина
    ЗначениеОформления = ЭлементОформления.Оформление.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ТолькоПросмотр"));
    ЗначениеОформления.Значение = Истина;
    ЗначениеОформления.Использование = Истина;
    
    // 2. Определяем условие: блокировка срабатывает, когда "ПринятоВРаботу" равно Истина
    ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.ПринятоВРаботу"); // Укажите имя вашей ТЧ и реквизита
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = Истина;
    ЭлементОтбора.Использование = Истина;
    
    // 3. Выбираем оформляемые поля (колонки, которые станут недоступными)
    ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
    ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТоварыЦена"); // Имя элемента колонки на форме
    ОформляемоеПоле.Использование = Истина;
    
    ОформляемоеПолеВторое = ЭлементОформления.Поля.Элементы.Добавить();
    ОформляемоеПолеВторое.Поле = Новый ПолеКомпоновкиДанных("ТоварыКоличество");
    ОформляемоеПолеВторое.Использование = Истина;

КонецПроцедуры

---

Вариант 2. Управляемые формы: Программный обход через обработчики событий

Бывают ситуации, когда условного оформления недостаточно. Например, если при блокировке ячеек нужно выполнять сложные расчеты, запрашивать данные из базы или проверять права пользователя.

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

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

Шаг 1. Обработка начала редактирования строки

Создадим для таблицы обработчик события ПриНачалеРедактирования. Он будет срабатывать, когда пользователь дважды кликает по строке или нажимает кнопку "Изменить":


&НаКлиенте
Процедура ТоварыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
    
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        // Управляем доступностью колонок в зависимости от значения флага в текущей строке
        Элементы.ТоварыЦена.ТолькоПросмотр = ТекущиеДанные.ПринятоВРаботу;
        Элементы.ТоварыКоличество.ТолькоПросмотр = ТекущиеДанные.ПринятоВРаботу;
    КонецЕсли;
    
КонецПроцедуры

Шаг 2. Обработка изменения флажка в строке

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


&НаКлиенте
Процедура ТоварыПринятоВРаботуПриИзменении(Элемент)
    
    // Получаем данные строки, в которой пользователь изменил флаг
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        // Мгновенно переключаем режим "Только просмотр" для колонок
        Элементы.ТоварыЦена.ТолькоПросмотр = ТекущиеДанные.ПринятоВРаботу;
        Элементы.ТоварыКоличество.ТолькоПросмотр = ТекущиеДанные.ПринятоВРаботу;
    КонецЕсли;
    
КонецПроцедуры

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

---

Вариант 3. Обычные формы: Использование события "ПриВыводеСтроки"

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

Для решения нашей задачи мы задействуем событие табличного поля ПриВыводеСтроки. Проанализируем пример кода:


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

Обратите внимание: чтобы изменения отражались на экране мгновенно при интерактивном нажатии на флажок "Принято в работу", нам нужно принудительно обновлять строки таблицы в событии ПриИзменении флажка. Добавим следующий код:


Процедура ТабличноеПолеТоварыПринятоВРаботуПриИзменении(Элемент)
    
    // Метод ОбновитьСтроки заставит платформу перерисовать таблицу и вызвать "ПриВыводеСтроки"
    ЭлементыФормы.ТабличноеПолеТовары.ОбновитьСтроки();
    
КонецПроцедуры

---

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

Мы подробно разобрали различные способы управления доступностью ячеек в строках табличных частей 1С. Подведем итог, какой метод выбрать для вашей задачи:

← На главную