Как запретить редактирование документа 1С, сохранив доступ к командной панели

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

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

Метод 1. Использование логических групп формы

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

Разберем по шагам реализацию этого метода:

  1. Создадим на форме группу, назовем ее ГруппаДанныеФормы.
  2. Установим свойство Отображение в значение Нет, чтобы группа не выделялась визуально.
  3. Переместим в нее все элементы, которые нужно блокировать.
  4. В программном коде, например, в процедуре ПриСозданииНаСервере, будем управлять доступностью этой группы:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Проверяем условие, например, наличие документа-основания
    Если ЗначениеЗаполнено(Объект.ДокументОснование) Тогда
        Элементы.ГруппаДанныеФормы.ТолькоПросмотр = Истина;
    КонецЕсли;
КонецПроцедуры

Этот метод хорош тем, что командная панель остается полностью интерактивной, в то время как все поля ввода внутри группы становятся доступными только для чтения.

Метод 2. Рекурсивный программный обход элементов

Ситуация усложняется, когда на форме находится 30 и более элементов, а менять структуру формы (вкладывать всё в группы) трудозатратно или невозможно из-за особенностей типового решения. В этом случае мы можем применить программный перебор всех элементов формы. Выясним, как это сделать эффективно.

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


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

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

Метод 3. Использование расширений (для конфигураций на поддержке)

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

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


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

Метод 4. Блокировка на уровне свойств объекта

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

Важно: Этот способ часто ведет к тому, что стандартные кнопки «Провести» или «Записать» исчезают или становятся неактивными, что может соответствовать нашей задаче (запрет правки данных), но при этом кнопки печати останутся рабочими.

Определение связи с документом-основанием

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

Подведем итоги

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

← На главную