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

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

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

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

Выясним причину: почему форма остается доступной?

Проанализируем ситуацию: архитектурно клиентское приложение 1С работает в одном потоке. Казалось бы, пока выполняется код записи на сервере, интерфейс должен быть «заморожен». Однако в обычных формах существует ряд нюансов:

  1. Прокачка сообщений ОС: Во время длительных серверных вызовов или циклов операционная система Windows продолжает отправлять сообщения форме (перерисовка, нажатия клавиш). Если внутри кода вызываются определенные функции или внешние компоненты, очередь сообщений может обрабатываться, что делает форму визуально «живой».
  2. Программный вызов записи: Если запись инициирована не стандартной кнопкой панели инструментов, а программно через метод Записать() в обработчике нажатия кастомной кнопки, автоматическая блокировка интерфейса платформой может не сработать.
  3. Фоновые процессы: Если в конфигурации (например, в ЗУП) реализована фоновая запись или проведение, управление возвращается в форму немедленно, пока сервер продолжает работу.

Рассмотрим подробнее способы программного решения этой задачи.

Способ 1: Управление свойством Доступность

Наиболее надежным и «некостыльным» методом является программное отключение доступности всей формы перед началом записи. Важно понимать разницу между ТолькоПросмотр и Доступность. Установка свойства ТолькоПросмотр = Истина позволяет пользователю перемещаться по полям и копировать текст, тогда как Доступность = Ложь полностью отключает реакцию элементов управления на любые действия.

Посмотрим на пример реализации в коде формы:


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

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

Способ 2: Использование системных индикаторов состояния

Чтобы пользователь понимал, что система не «зависла», а выполняет полезную работу, рекомендуется использовать метод Состояние(). В обычных формах вызов этого метода с выводом прогресс-бара или текста помогает визуально обозначить занятость процесса.

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


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

Способ 3: Проблема активной ячейки в табличных частях

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

Используйте следующий прием:


// Сброс активного элемента формы
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ПанельОсновная; // или другой статический элемент

Способ 4: Борьба с повторным входом (Reentrancy)

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

Выясним, как защититься от этого программно через флаг-предохранитель:


Перем ОперацияВыполняется;

Процедура КоманднаяПанельЗаписать(Кнопка)
    
    Если ОперацияВыполняется = Истина Тогда
        Возврат; // Игнорируем повторное нажатие
    КонецЕсли;
    
    ОперацияВыполняется = Истина;
    
    Попытка
        ЭтотОбъект.Записать();
    Исключение
        ОперацияВыполняется = Ложь;
        ВызватьИсключение;
    КонецПопытки;
    
    ОперацияВыполняется = Ложь;
    
КонецПроцедуры

Способ 5: Модальные окна как жесткая блокировка

Хотя современная методология 1С призывает отказываться от модальности, в старых конфигурациях на обычных формах вызов модального окна — это самый простой способ гарантированно остановить любой ввод пользователя. Если запись инициирует какой-то сложный процесс (например, обмен данными), открытие модальной формы индикации процесса полностью исключит доступ к основной форме.

Рассмотрим, как это выглядит:

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

Заключение

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

← На главную