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

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

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

Способ 1. Использование механизма «Условное оформление»

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

Во-первых, нам необходимо подготовить данные. В объекте, описывающем дерево значений (реквизит формы), рекомендуется создать дополнительную невидимую колонку, например, УровеньСтроки с типом Число. Это избавит платформу от необходимости постоянно вызывать программный метод Уровень() во время отрисовки интерфейса.

Проанализируем процесс программного заполнения дерева:


// При заполнении дерева на сервере
НоваяСтрока = ДеревоДанных.ПолучитьЭлементы().Добавить();
НоваяСтрока.Заказ = "Заказ №1";
НоваяСтрока.УровеньСтроки = 0; // Первый уровень

ПодчиненнаяСтрока = НоваяСтрока.ПолучитьЭлементы().Добавить();
ПодчиненнаяСтрока.Товар = "Кирпич";
ПодчиненнаяСтрока.Цена = 100;
ПодчиненнаяСтрока.УровеньСтроки = 1; // Второй уровень

Во-вторых, настроим само Условное оформление формы. Перейдем на закладку «Условное оформление» в редакторе формы и добавим новый элемент:

  1. Оформление: Установим свойство Только просмотр в значение Истина. Также можно добавить свойство ЦветТекста (например, серый), чтобы визуально выделить заблокированные поля.
  2. Условие: Выберем наше поле Объект.ДеревоДанных.УровеньСтроки Равно 0.
  3. Оформляемые поля: Укажем конкретные колонки, которые нужно заблокировать (например, Товар и Цена).

Важный нюанс: Помните, что метод Уровень() в 1С возвращает индекс с нуля. То есть 0 — это самый верхний уровень (корень), 1 — следующий и так далее. Ошибка в этом расчете часто приводит к тому, что блокировка срабатывает не на тех строках.

Способ 2. Обработка события «Перед началом изменения»

Если нам нужно гарантированно запретить пользователю даже «проваливаться» в ячейку (активировать режим ввода текста), рассмотрим использование событий таблицы. Событие ПередНачаломИзменения срабатывает в тот момент, когда пользователь пытается начать редактирование строки или ячейки.

Разберем пример реализации в модуле формы:


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

Этот способ хорош тем, что параметр Отказ = Истина полностью пресекает попытку изменения. Однако он блокирует всю строку целиком. Если же вам нужно разрешить менять колонку «Заказ», но запретить «Товар» в той же строке, используйте проверку Элемент.ТекущийЭлемент.Имя.

Способ 3. Динамическое управление доступностью в «При начале редактирования»

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

Выясним, как это работает программно:


&НаКлиенте
Процедура ДеревоДанныхПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
    
    ТекущиеДанные = Элемент.ТекущиеДанные;
    
    Если ТекущиеДанные.УровеньСтроки = 0 Тогда
        // Блокируем конкретные колонки для этого уровня
        Элементы.ДеревоДанныхТовар.ТолькоПросмотр = Истина;
        Элементы.ДеревоДанныхЦена.ТолькоПросмотр = Истина;
    Иначе
        // Разблокируем их для остальных уровней
        Элементы.ДеревоДанныхТовар.ТолькоПросмотр = Ложь;
        Элементы.ДеревоДанныхЦена.ТолькоПросмотр = Ложь;
    КонецЕсли;
    
КонецПроцедуры

Внимание: При использовании этого метода важно не забывать возвращать доступность колонок обратно, иначе после перехода со строки 1-го уровня на строку 2-го уровня поля могут остаться заблокированными.

Способ 4. Перехват фокуса в «При активизации ячейки»

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

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


&НаКлиенте
Процедура ДеревоДанныхПриАктивизацииЯчейки(Элемент)
    
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Если мы на первом уровне и стоим в колонке Цена
    Если ТекущиеДанные.УровеньСтроки = 0 И Элемент.ТекущаяКолонка.Имя = "ДеревоДанныхЦена" Тогда
        // Переносим фокус на колонку Заказ
        Элемент.ТекущаяКолонка = Элементы.ДеревоДанныхЗаказ;
    КонецЕсли;
    
КонецПроцедуры

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

Рекомендации по надежности данных

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

Для этого в модуле объекта (если дерево связано с данными документа или справочника) или непосредственно перед записью данных из дерева в базу, добавьте очистку недопустимых значений. Например, если Уровень = 0, то значения в полях Товар и Цена должны принудительно устанавливаться в пустые значения или 0. Это гарантирует целостность вашей информационной системы вне зависимости от настроек формы.

Итоги

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

← На главную