Как сделать доступным только один элемент формы, заблокировав остальные в 1С 8.2

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

В процессе разработки в среде 1С 8.2 часто возникает задача ограничить возможность редактирования документа или справочника, оставив при этом доступными лишь несколько конкретных полей или кнопок. Казалось бы, самое простое решение — установить свойство ЭтаФорма.ТолькоПросмотр = Истина. Однако на практике этот метод оказывается слишком радикальным: если форма переведена в режим «Только просмотр», программно разрешить редактирование отдельного элемента внутри неё не удастся, так как свойство формы имеет высший приоритет.

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

Проблема простого перебора коллекции элементов

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

Проанализируем базовый, но не совсем корректный подход:


Для Каждого ЭлФ Из ЭлементыФормы Цикл
    Если ЭлФ.Имя <> "НужныйЭлемент" Тогда
        ЭлФ.ТолькоПросмотр = Истина; // Ошибка, если элемент — декорация или группа
    КонецЕсли;
КонецЦикла;

Решение 1: Фильтрация элементов по типам данных

Чтобы избежать ошибок при обходе, нам необходимо проверять тип каждого элемента. Это самый надежный и правильный путь с точки зрения стандартов разработки 1С. Рассмотрим пример кода, который проверяет, является ли элемент полем ввода или таблицей, прежде чем изменять его состояние.

Для реализации этого метода воспользуемся функцией ТипЗнч(). Посмотрим на практическую реализацию:


РазрешитьИзменение = Ложь;
Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
    // Пропускаем тот элемент, который должен остаться доступным
    Если ЭлементФормы = ЭлементыФормы.ИмяНужногоРеквизита Тогда
        Продолжить;
    КонецЕсли;

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

Решение 2: Использование конструкции Попытка — Исключение

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

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


Для Каждого Элем Из ЭлементыФормы Цикл
    Если Элем = ЭлементыФормы.НужныйЭлемент Тогда 
        Продолжить; 
    КонецЕсли;

    Попытка
        Элем.ТолькоПросмотр = Истина;
    Исключение
        Попытка
            Элем.Доступность = Ложь;
        Исключение
            // Элемент не поддерживает ни одно из свойств
        КонецПопытки;
    КонецПопытки;
КонецЦикла;

Решение 3: Управление командными панелями и кнопками

Особое внимание стоит уделить кнопкам на командных панелях. Часто блокировка самой панели не дает нужного результата или блокирует лишнее (например, кнопку закрытия формы). Выясним, как детально настроить доступность кнопок, используя обход коллекции Кнопки.

Рассмотрим пример глубокой настройки командной панели:


// Блокируем кнопки основной командной панели, кроме "Закрыть"
Для Каждого Кнопка Из ЭлементыФормы.ОсновныеДействияФормы.Кнопки Цикл
    Если Кнопка.Имя <> "ОсновныеДействияФормыЗакрыть" Тогда
        Кнопка.Доступность = Ложь;
    КонецЕсли;
КонецЦикла;

// Работа с вложенными подменю
Для Каждого Кнопка Из ЭлементыФормы.ДействияФормы.Кнопки Цикл
    Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
        Для Каждого ВложеннаяКнопка Из Кнопка.Кнопки Цикл
            ВложеннаяКнопка.Доступность = Ложь;
        КонецЦикла;
    КонецЕсли;
КонецЦикла;

Рекурсивный обход вложенных элементов

В сложных формах элементы часто находятся не в корне, а внутри панелей со страницами. Обычный цикл по ЭлементыФормы может не «увидеть» то, что спрятано глубоко в иерархии. Для решения этой задачи разберем принцип рекурсивного обхода.

Важный нюанс: при отключении доступности у всей панели (объект типа Панель), все элементы на ней также станут недоступными. Однако это может привести к тому, что пользователь не сможет даже переключать закладки (страницы) формы.

Рассмотрим, как правильно обходить вложенные элементы, не ломая навигацию по страницам:


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

Рекомендации по управлению доступностью в управляемых формах

Если вы работаете в интерфейсе «Управляемое приложение» (даже на платформе 8.2), подход несколько меняется. Здесь мы рекомендуем управлять не визуальными элементами, а командами и группами.

  1. Группировка элементов: Объедините все элементы, которые нужно блокировать одновременно, в одну ГруппуФормы. Тогда вам достаточно будет одной строки кода: Элементы.ГруппаБлокировки.Доступность = Ложь;.
  2. Управление через команды: Если кнопки связаны с командами формы, лучше отключать саму команду: Команды.ИмяКоманды.Доступность = Ложь;. Это автоматически отключит все кнопки во всех меню, привязанные к этой команде.
  3. Условное оформление: В управляемых формах 8.2 доступен мощный механизм УсловноеОформление. Вы можете программно добавить правило, которое сделает все поля формы (за исключением списка исключений) только для чтения при выполнении определенного условия.

Использование свойства «Изменяет данные»

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

Резюме

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

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

← На главную