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

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

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

Использование обработчика ПослеЗаписи на клиенте

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

Проанализируем программный код, который решает эту задачу. В модуле формы документа следует прописать следующую логику:


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

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

Инициализация состояния при открытии формы

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

Разберем, почему это важно. Когда форма открывается, сервер считывает данные объекта. Установив доступность в ПриЧтенииНаСервере, мы передаем на клиент уже правильно настроенный интерфейс:


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

Управление через свойства команды

Профессиональный подход в разработке на управляемых формах подразумевает управление не самой кнопкой (элементом формы), а командой, к которой эта кнопка привязана. Если одна команда выведена в нескольких местах (например, в командной панели и в контекстном меню), изменение доступности команды автоматически обновит все связанные с ней кнопки.

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

Особенности многопользовательской работы и оповещения

Рассмотрим ситуацию, когда один пользователь открыл документ, а второй в это время его провел. В открытой форме первого пользователя кнопка останется недоступной, так как форма «не знает» об изменениях в базе. Для решения таких задач в 1С применяется механизм оповещений.

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

  1. В процедуре ПослеЗаписи добавим вызов метода Оповестить. Это пошлет сигнал всем открытым окнам системы.
  2. В форме документа создадим обработчик ОбработкаОповещения, который будет реагировать на это событие и обновлять состояние элементов.

Пример реализации оповещения:


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    Оповестить("ДокументПроведен", Объект.Ссылка, ЭтаФорма);
    // Обновляем текущую форму
    УстановитьДоступностьКнопок(); 
КонецПроцедуры

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

Критически важные ограничения

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

← На главную