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