Как заблокировать поле табличной части в управляемой форме, если документ не модифицирован

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

В разработке на платформе 1С 8.3 часто возникает задача управления доступностью полей «на лету». Одной из специфических задач является блокировка редактирования конкретной колонки табличной части до тех пор, пока пользователь не начнет целенаправленно изменять документ (т.е. пока форма не перейдет в состояние «Модифицированность»). Это позволяет снизить количество случайных ошибок и «когнитивную нагрузку» на оператора, предотвращая правки в важных полях без осознанного изменения документа.

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

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

Проанализируем самый «чистый» с точки зрения платформенных стандартов метод. Поскольку мы не можем привязать Условное оформление напрямую к флагу модифицированности, нам необходимо создать «проводник» — вспомогательный реквизит формы.

Пошаговый алгоритм реализации:

  1. Добавим на форму новый реквизит (не путать с реквизитом объекта!) с именем ДокументЗаписан (тип Булево).
  2. В обработчике события ПриЧтенииНаСервере установим значение этого реквизита:
    
    &НаСервере
    Процедура ПриЧтенииНаСервере(ТекущийОбъект)
        // Если ссылка не пустая, значит документ уже есть в базе
        ДокументЗаписан = Не Объект.Ссылка.Пустая();
    КонецПроцедуры
    
  3. В обработчике ПослеЗаписиНаСервере актуализируем состояние:
    
    &НаСервере
    Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
        ДокументЗаписан = Истина;
    КонецПроцедуры
    
  4. Настроим Условное оформление формы. В поле «Условие» укажем: ДокументЗаписан Равно Истина. В «Оформляемых полях» выберем нужную колонку табличной части. В параметрах оформления установим Только просмотр = Истина.

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

Метод 2. Программный запрет через событие «ПередНачаломИзменения»

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

У каждого элемента формы типа «Таблица» есть событие ПередНачаломИзменения. Мы можем использовать его для прерывания процесса редактирования. Посмотрим на пример кода:


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

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

Проанализируем ситуацию: данный метод работает мгновенно на стороне клиента и не требует серверных вызовов. Однако у него есть существенный минус — пользователь не видит заранее, что поле недоступно, пока не попытается в него зайти. Чтобы улучшить UX (пользовательский опыт), рекомендуется сочетать этот метод с визуальным оформлением из первого способа.

Метод 3. Динамическое управление свойством «ТолькоПросмотр» колонки

Если логика требует, чтобы поле становилось доступным сразу, как только пользователь изменил что-то в форме, мы можем управлять свойством элемента формы напрямую. Однако стоит помнить, что свойство Модифицированность формы устанавливается платформой автоматически, но события «ПриИзмененииМодифицированности» в 1С не существует.

Рассмотрим вариант реализации через обработчик ожидания (хотя этот метод стоит использовать с осторожностью из-за нагрузки на систему):

  1. В процедуре ПриОткрытии подключаем обработчик:
    
    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        ПодключитьОбработчикОжидания("ПроверитьМодифицированность", 1);
    КонецПроцедуры
    
  2. Создаем саму процедуру проверки:
    
    &НаКлиенте
    Процедура ПроверитьМодифицированность()
        // Управляем доступностью конкретной колонки
        Элементы.ИмяТаблицыИмяКолонки.ТолькоПросмотр = Не ЭтаФорма.Модифицированность;
    КонецПроцедуры
    

Важно: Постоянные вызовы каждые несколько секунд могут замедлять работу интерфейса в тяжелых формах. Более оптимальным считается вызов подобной проверки в событиях ПриИзменении основных реквизитов шапки документа. Как только пользователь поменял «Организацию» или «Склад» — колонка в таблице разблокируется.

Комбинированный подход: лучший результат

Проанализировав все способы, мы рекомендуем использовать комбинацию первого и второго методов. Это обеспечит и визуальную подсказку, и надежный программный запрет:

  1. Используйте Условное оформление для окрашивания колонки в серый цвет, если документ уже записан в базу (используя вспомогательный реквизит ДокументЗаписан).
  2. Добавьте проверку в ПередНачаломИзменения, чтобы физически отсечь возможность редактирования.
  3. В обработчиках ПриИзменении элементов шапки, которые инициируют начало работы с документом, установите ДокументЗаписан = Ложь. Это мгновенно обновит Условное оформление, и колонка станет визуально доступной (белой), сигнализируя оператору о возможности ввода данных.

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

← На главную