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