Как сделать недоступной ячейку в табличной части 1С: пошаговое руководство

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

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

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

Решение для обычных форм (v8.2 и более ранние версии)

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

Проанализируем ситуацию: если вы напишете ЭлементыФормы.Товары.Колонки.Товар.Доступность = Ложь, то вся колонка целиком станет недоступной для всех строк сразу. Чтобы изменить состояние только одной ячейки, нам нужно работать с объектом ОформлениеСтроки.

Разберем по шагам правильный алгоритм в процедуре ПриВыводеСтроки:

  1. Получаем данные текущей строки через параметр ДанныеСтроки.
  2. Проверяем наше условие (например, значение в колонке Отдел).
  3. Обращаемся к коллекции Ячейки объекта ОформлениеСтроки и устанавливаем свойство ТолькоПросмотр или Доступность.

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


Процедура ТоварыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
    // Проверяем, что данные строки доступны
    Если ДанныеСтроки = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Условие: если отдел - "Первый", блокируем ячейку "Товар"
    // Внимание: поиск по наименованию в этом событии - плохая практика (см. ниже)
    Если ДанныеСтроки.Отдел.Наименование = "Первый" Тогда
        ОформлениеСтроки.Ячейки.Товар.ТолькоПросмотр = Истина;
        // Можно также использовать: ОформлениеСтроки.Ячейки.Товар.Доступность = Ложь;
    Иначе
        ОформлениеСтроки.Ячейки.Товар.ТолькоПросмотр = Ложь;
    КонецЕсли;

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

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

Решение для управляемых форм (v8.3)

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

Способ 1: Настройка в конфигураторе (через интерфейс)

Это самый простой и быстрый способ, не требующий написания кода. Рассмотрим ситуацию из сообщения №12: если "Причина отказа" не заполнена, то "Дата отказа" должна быть недоступна.

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

Система сама будет отслеживать изменения в данных и блокировать/разблокировать ячейку автоматически.

Способ 2: Программное создание условного оформления

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


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

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

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

Дополнительные проверки: Событие "ПриНачалеРедактирования"

Для обеспечения максимальной надежности, особенно когда речь идет о бизнес-логике, рекомендуется дублировать запрет в событии самой таблицы ПриНачалеРедактирования (на клиенте). Это гарантирует, что пользователь не сможет начать ввод данных, если условия не соблюдены.

Проанализируем пример кода:


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

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

Выяснив причину сложности задачи, можно подвести итоги:

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

← На главную