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