Содержание:
1. Закрытие формы через обработчик ожидания
2. Решение проблемы при работе в системе 1С:ERP
В типовой конфигурации ERP проявилась следующая проблема: после нажатия на кнопку «Провести и закрыть» форма могла надолго подвисать. Численно это отражалось в ключевой операции «Провести и закрыть документ. <имя документа> форма. форма документа» (в примере указан документ вида «приобретение товаров и услуг», но такая ситуация случалась и с другими видами документов), задержки достигали нескольких десятков и даже сотен секунд.
Провести и закрыть. документ. приобретение товаров услуг. форма. форма документа
Отчет по ключевым операциям показал, что вопросы возникают при проведении документов именно из формы (и, например, групповое перепроведение документов такой проблемы не выявляет). Замер производительности в конфигураторе и анализ ТЖ это подтвердил.
1. Закрытие формы через обработчик ожидания
В типовом коде 1С есть место, которое может приводить к задержкам закрытия форм документов после их проведения.
Особенность кода заключается в том, что закрытие формы после ее записи реализовано не прямым методом Закрыть(), а через запуск «ОбработчикаОжиданий» в процедуре ВыполнитьДействияПослеЗаписи() общего модуля ОбщегоНазначенияУТКлиент.
Процедура ВыполнитьДействияПослеЗаписи(Форма, Объект, ПараметрыЗаписи) Экспорт
Если Не ПараметрыЗаписи.Свойство("НовыйОбъект") Тогда
Возврат;
КонецЕсли;
Если ПараметрыЗаписи.НовыйОбъект Тогда
ТекстЗаголовка = НСтр("ru = 'Создание:';
|en = 'Created:'");
Иначе
ТекстЗаголовка = НСтр("ru = 'Изменение:';
|en = 'Editing:'");
КонецЕсли;
ОповеститьПользователяОбИзмененииОбъекта(Объект.Ссылка, ТекстЗаголовка);
Если Форма.ПринудительноЗакрытьФорму Тогда
Форма.ПодключитьОбработчикОжидания("Подключаемый_ЗакрытьФорму", 0.1, Истина);
КонецЕсли;
КонецПроцедуры
А обработчик ожидания модуля формы документа уже закрывает форму обычным методом Закрыть().
&НаКлиенте
Процедура Подключаемый_ЗакрытьФорму()
Закрыть();
КонецПроцедуры
Разработчики платформы такой подход к закрытию форм объясняют учетом требованиями современных веб-браузеров и унификацией кода для всех клиентов (толстого, тонкого и веб).
С другой стороны, в синтакс-помощнике указано, что «вызов обработчика ожидания будет осуществляться только в «состоянии покоя», то есть в тот момент, когда программа не выполняет никаких действий.» То есть, если при проведении документа программа что-то еще делает, то закрытие формы документа может задерживаться.
2. Решение проблемы при работе в системе 1С:ERP
В качестве решения проблемы был выбран отказ от использования обработчиков ожидания в процедурах закрытия формы документа при работе не из веб-клиента (в тонком и толстом клиенте).
А таких вызовов в типовом коде оказалось два:
● Обработчик, который непосредственно закрывает форму - это «Подключаемый_ЗакрытьФорму()» - он запускается, как уже говорилось, процедурой ВыполнитьДействияПослеЗаписи() общего модуля ОбщегоНазначенияУТКлиент
● Но сам этот обработчик запускается из кода другого обработчика – «Подключаемый_Обработать записьОбъекта() – располагается в формах документа, содержит одну строку «ОбщегоНазначенияУТКлиент.ОбработатьЗаписьОбъектаВФорме()» и запускается из процедуры «ЗаписатьОбъектПриНеобходимости() общего модуля ОбщегоНазначенияУТКлиент
Процедуры ЗаписатьОбъектПриНеобходимости () и ВыполнитьДействияПослеЗаписи() были модифицированы через расширение.
&ИзменениеИКонтроль("ВыполнитьДействияПослеЗаписи")
Процедура UG_boostВыполнитьДействияПослеЗаписи(Форма, Объект, ПараметрыЗаписи)
Если Не ПараметрыЗаписи.Свойство("НовыйОбъект") Тогда
Возврат;
КонецЕсли;
Если ПараметрыЗаписи.НовыйОбъект Тогда
ТекстЗаголовка = НСтр("ru = 'Создание:';
|en = 'Created:'");
Иначе
ТекстЗаголовка = НСтр("ru = 'Изменение:';
|en = 'Editing:'");
КонецЕсли;
ОповеститьПользователяОбИзмененииОбъекта(Объект.Ссылка, ТекстЗаголовка);
Если Форма.ПринудительноЗакрытьФорму Тогда
#Вставка
//Кодерлайн, Борисенко, 26.08.2025
Если МожноВыполнитьБезОбработчикаОжиданий(Форма) Тогда
//Используем прямое закрытие формы,
//чтобы избежать возможное запаздывание срабатывания обработчика ожидания
//и дополнительное ожидание пользователя
Форма.Закрыть();
ОценкаПроизводительностиКлиент.ЗавершитьЗамерВремениНаКлиентеАвто();
Иначе
//типовой код
#КонецВставки
Форма.ПодключитьОбработчикОжидания("Подключаемый_ЗакрытьФорму", 0.1, Истина);
#Вставка
КонецЕсли;
#КонецВставки
КонецЕсли;
КонецПроцедуры
&ИзменениеИКонтроль("ЗаписатьОбъектПриНеобходимости")
Процедура UG_boostЗаписатьОбъектПриНеобходимости(Форма, ПараметрыЗаписи, Отказ, ПроверкиПройдены)
Если Отказ Тогда
Возврат;
КонецЕсли;
Форма.ПараметрыДляЗаписи = ПараметрыЗаписи;
НеобходимаОтложеннаяЗапись = ПараметрыЗаписи.Свойство("ДействиеПослеЗаписи");
Если НеобходимаОтложеннаяЗапись Или ПроверкиПройдены Тогда
Отказ = Истина;
#Вставка
//Кодерлайн, Борисенко, 26.08.2025
Если МожноВыполнитьБезОбработчикаОжиданий(Форма) Тогда
//Вызываем процедуры, не используя обработчик ожидания
//чтобы избежать возможное запаздывание срабатывания обработчика ожидания
//и дополнительное ожидание пользователя
ОбщегоНазначенияУТКлиент.ОбработатьЗаписьОбъектаВФорме(Форма, ПараметрыЗаписи);
Иначе
//типовой код
#КонецВставки
Форма.ПодключитьОбработчикОжидания("Подключаемый_ОбработатьЗаписьОбъекта", 0.1, Истина);
#Вставка
КонецЕсли;
#КонецВставки
Иначе
НачатьЗамерВремениЗаписиОбъекта(Форма, ПараметрыЗаписи);
КонецЕсли;
КонецПроцедуры
//Кодерлайн, Борисенко, 26.08.2025
Функция МожноВыполнитьБезОбработчикаОжиданий(Форма)
Можно = Ложь;
#Если Не ВебКлиент Тогда
//ТонкийКлиент, ТолстыйКлиентУправляемоеПриложение, ТолстыйКлиентОбычноеПриложение
Если СтрНайти(Форма.ИмяФормы, "Документ.") > 0
И ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Форма, "UG_ВыполнитьБезОбработчикаОжиданий")
И Форма["UG_ВыполнитьБезОбработчикаОжиданий"] = Истина
Тогда
//Только для форм документов
//После обновлений необходимо убеждаться, что:
// 1) типовые обработчики ожиданий документов "Подключаемый_ЗакрытьФорму()" содержат только одну команда Закрыть() и ничего больше
// 2) типовые обработчики ожиданий документов "Подключаемый_ОбработатьЗаписьОбъекта()" содержат только код "ОбщегоНазначенияУТКлиент.ОбработатьЗаписьОбъектаВФорме(ЭтаФорма, ПараметрыДляЗаписи);" и ничего больше
Можно = Истина;
КонецЕсли;
#КонецЕсли
Возврат Можно;
КонецФункции
После таких модификаций проблема временных задержек при закрытии форм документов исчезла.
Специалист компании ООО "Кодерлайн"
Игорь Борисенко
