Эта статья для программистов 1С – в ней разберем новое ограничение платформы при разработке кода.
О чем пойдет речь?
При закрытии формы обработки или при закрытии всего приложения достаточно часто используется дополнительный диалог.
В основной массе диалог представляет собой вопрос для подтверждения операции закрытия, но бывают более сложные случаи. Например, при закрытии формы подбора товаров можно запросить у пользователя разрешение на перенос подобранных товаров в документ.
Начиная с версии 8.3.8 разработчики платформы изменили подход, которому должны следовать программисты при решении подобного рода задач.
Коротко о главном…
Сначала коротко обозначим суть изменений. Начиная с версии платформы 8.3.8 необходимо выделять 2 сценария закрытия формы:
- Первый вариант – когда пользователь закрывает форму самостоятельно
- Второй вариант – когда форма закрывается в результате закрытия всего приложения.
Как это повлияло на объем кода?
- Немного увеличился код при закрытии формы, так как необходимо отрабатывать 2 сценария
- Практически до минимума упростился код при закрытии приложения (речь идет о подтверждении выхода из системы).
Кроме этого, изменения платформы серьезно затронули логику программного кода. Теперь в процессе закрытия приложения практически невозможно организовать произвольный сценарий из-за введенных ограничений. В чем суть ограничений?
- В процессе закрытия приложения запрещено открытие любых форм и диалогов
- В процессе закрытия приложения запрещены любые серверные вызовы
- Нельзя программным способом отменить закрытие приложения без отображения вопроса пользователю.
Фактически теперь в процессе закрытия приложения можно указать только текст вопроса, который увидит пользователь.
Скорее всего, у вас уже возник вопрос: к чему же все эти изменения?
Приведем цитату разработчиков платформы из файла V8Update.htm, содержащего перечень изменений релизов платформы:
Теперь подробнее разъясним суть проблемы.
Раньше при выходе из системы, когда возникала задача открытия диалогов, приходилось писать программный код отдельно для веб-клиента и отдельно для других клиентов. Связано это с тем, что все современные веб-браузеры, если страница не хочет, чтобы ее закрывали, выводят свой диалог. Примеры этих диалогов вы сможете увидеть ниже, в той части статьи, где подробно рассматривается поведение веб-браузеров.
Что же сделали разработчики платформы? Теперь платформа ведет себя так же, как и веб-браузеры: если приложение не хочет, чтобы его закрывали, тогда выводится платформенный диалог. В результате нет необходимости писать код под разные клиенты, так как работает он одинаково, но платой за такую универсальность являются описанные выше ограничения.
При этом даже если мы не предполагаем использование веб-клиента в нашей базе, то это ничего не меняет. Ограничения все равно действуют. В некоторых случаях это может быть неудобным, но с этим придется мириться. В частности, теперь открытие дополнительных обработок при закрытии приложения может вызвать затруднение. Решение подобной задачи мы рассмотрим в конце статьи.
На этом завершаем краткий обзор изменений и переходим к подробному разбору.
Вопрос при закрытии формы
Изменения в коде будем рассматривать в сравнении с тем, как это делалось в предыдущих версиях платформы.
Ранее, когда в процессе закрытия формы возникала необходимость задать вопрос пользователю, использовался следующий программный код:
&НаКлиенте Перем ЗакрытиеРазрешено; &НаКлиенте Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка) Если ЗакрытиеРазрешено=Неопределено Тогда ПоказатьВопрос( Новый ОписаниеОповещения("ПередЗакрытиемЗавершение", ЭтотОбъект), "Текст вопроса", РежимДиалогаВопрос.ДаНет); Отказ = Истина; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ПередЗакрытиемЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт Если РезультатВопроса = КодВозвратаДиалога.Да Тогда ЗакрытиеРазрешено = Истина; Закрыть(); КонецЕсли; КонецПроцедуры
Если данный код попытаться выполнить на платформе 8.3.8 с отключенным режимом совместимости, тогда возникнет ошибка:
Теперь, начиная с версии платформы 8.3.8, необходимо выделять 2 сценария закрытия формы. Первый вариант – когда пользователь закрывает форму самостоятельно и второй вариант – когда форма закрывается в результате закрытия всего приложения.
Таким образом, код требует модернизации:
&НаКлиенте Перем ЗакрытиеРазрешено; &НаКлиенте Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка) Если ЗавершениеРаботы Тогда ТекстПредупреждения = "Текст"; Отказ = Истина; ИначеЕсли ЗакрытиеРазрешено=Неопределено Тогда ПоказатьВопрос( Новый ОписаниеОповещения("ПередЗакрытиемЗавершение", ЭтотОбъект), "Текст вопроса", РежимДиалогаВопрос.ДаНет); Отказ = Истина; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ПередЗакрытиемЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт Если РезультатВопроса = КодВозвратаДиалога.Да Тогда ЗакрытиеРазрешено = Истина; Закрыть(); КонецЕсли; КонецПроцедуры
Как вы можете заметить, у обработчика ПередЗакрытием появились 2 новых параметра:
- Параметр ЗавершениеРаботы является булевым и позволяет определить причину закрытия формы
- Параметр ТекстПредупреждения используется только в процессе закрытия всего приложения. В этот параметр можно поместить текст вопроса, который будет отображен пользователю.
Теперь подробнее об изменении в коде. Как вы видите, появилась новая ветка алгоритма, которая выполняется в процессе завершения работы системы.
Обращаем ваше внимание, что никаких диалогов в этом случае не открывается, так как они запрещены. В коде устанавливается только текст предупреждения и обязательно устанавливается флаг Отказ. Как уже отмечалось выше, нельзя программным способом отменить процесс закрытия приложения, поэтому флаг Отказ работает иначе, чем при обычном закрытии формы. Установка флага указывает необходимость отображения предупреждения для пользователя, которое хранится в параметре ТекстПредупреждения.
В толстом и тонком клиенте окно предупреждения будет следующим:
Стоит отметить, что если флаг Отказ сброшен, а ТекстПредупреждения заполнен, тогда система проигнорирует текст и сообщение отображено не будет. Если же флаг Отказ установлен, а параметр ТекстПредупреждения не заполнен, тогда будет отображено системное предупреждение:
Также следует отметить, что количество подобных диалогов может быть любым – по числу закрываемых форм. Кроме того, аналогичный диалог может формироваться в обработчике ПередЗавершениемРаботыСистемы модуля управляемого приложения (этот вариант будет рассмотрен ниже). В итоге, если пользователь хотя бы в одном диалоге нажмет кнопку Продолжить работу, процесс завершения работы будет отменен и на экране останется та форма, в которой была нажата кнопка.
В веб-клиенте диалог будет выглядеть иначе. В веб-браузерах Mozilla Firefox и Google Chrome будет отображен только текст, заданный разработчиками веб-браузера и не будет отображаться текст, установленный в обработчиках событий системы.
Пример диалога для Mozilla Firefox:
Пример диалога для Google Chrome:
В веб-браузере Internet Explorer диалог будет выглядеть иначе. Будет отображен единый диалог, содержащий все сообщения, установленные в обработчиках формы и модуле управляемого приложения:
Стоит отметить, что если в свойствах конфигурации включен режим совместимости с 8.3.7 и более ранними версиями, то данный механизм будет работать в старом варианте.
Таким образом, при отключении режима совместимости следует проанализировать и скорректировать программный код по закрытию форм, так как если код содержит обращения к серверу или код по открытию дополнительных форм, то это будет приводить к ошибкам в процессе завершения работы системы.
Также можно сформулировать небольшую рекомендацию. Если в коде обработчика формы ПередЗакрытием, исполняемом в процессе завершения работы системы, необходимо получать дополнительные данные с сервера, то их следует получить заранее и хранить в данных формы.
Вопрос при закрытии приложения
В данном случае мы не будем приводить программный код, который использовался в предыдущих версиях для отображения вопроса при выходе из системы, так как он достаточно громоздкий. Приведем лишь новый код модуля управляемого приложения, который упростился до минимума:
Процедура ПередЗавершениемРаботыСистемы(Отказ, ТекстПредупреждения) ТекстПредупреждения = "Завершить работу с программой?"; Отказ = Истина; КонецПроцедуры
Теперь для отображения вопроса при выходе из системы достаточно установить текст предупреждения и флаг Отказ равным Истина.
Опять же, в коде запрещены обращения к серверу и открытия дополнительных форм, а также поведение в веб-браузере будет аналогичным тому, что уже было описано выше.
Открытие формы обработки при закрытии приложения
В завершении статьи хотелось бы продемонстрировать прием, который позволяет открыть форму некоторой обработки в процессе завершения работы системы.
Наша задача заключается в том, чтобы отменить процесс закрытия приложения и открыть форму некоторой обработки. Проблема в том, что отменить процесс закрытия или открыть форму мы не можем, так как это запрещено.
Поэтому, для того чтобы отменить закрытие приложения, потребуется использовать предупреждение, а для того чтобы открыть форму, используем обработчик ожидания, который выполнится только в том случае, если пользователь откажется от завершения работы системы.
Пример кода:
Процедура ПередЗавершениемРаботыСистемы(Отказ, ТекстПредупреждения) #Если ВебКлиент Тогда ТекстПредупреждения = "Завершить работу с программой?"; #Иначе ТекстПредупреждения = "Для запуска обработки проведения документов нажмите ""Продолжить работу"""; ПодключитьОбработчикОжидания("ОткрытиеОбработки", 0.1, Истина); #КонецЕсли Отказ = Истина; КонецПроцедуры Процедура ОткрытиеОбработки() Экспорт ОткрытьФорму("Обработка.ПроведениеДокументов.Форма"); КонецПроцедуры
Используя инструкции препроцессора, мы разделили сценарии закрытия в веб-клиенте и в других видах клиентов. В случае веб-клиента мы не открываем обработку, так как практически во всех веб-браузерах текст нашего предупреждения не отображается. В других видах клиентов будет отображен наш диалог:
Если пользователь нажмет кнопку Продолжить работу, тогда сработает обработчик ожидания и будет открыта форма обработки.
Заключение
Платформа продолжает свое уверенное движение в сторону веб-браузеров, но на этот раз разработчики наложили ограничения на программный код, исполняемый в толстом и тонком клиентах. С одной стороны, это упростило и унифицировало код при закрытии форм, так как теперь нет необходимости писать несколько вариантов кода под каждый клиент, с другой стороны, это ограничило нас в возможностях.
Чтобы освоить разработку интерфейсов и форм в 1С:Предприятие 8.3
на профессиональном уровне, рекомендуем записаться на курс:
«Профессиональная разработка интерфейсов и форм в 1С 8.3»
Поддержка – 3 месяца. Объем курса – 49 учебных часов.
Об авторе
Автор статьи – Сергей Калинкин
Автор и тренер курса «Профессиональная разработка интерфейсов и форм в 1С:Предприятие 8.3»
Директор ЦСО «Центр профессионального программирования», г. Казань
E-mail – mail@1c-cpp.ru
ВКонтакте – https://vk.com/id26296995
PDF-версия статьи для участников группы ВКонтакте
Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.
Если Вы еще не вступили в нее – сделайте это сейчас, и в блоке ниже (на этой странице) появятся ссылки на скачивание материалов.
Вы можете скачать эту статью в формате PDF по следующей ссылке: Ссылка доступна для зарегистрированных пользователей)
Теперь приходиться выкручиваться и писать пользователю такие предупреждения:
“Для корректного выхода нажмите “Продолжить работу”!”
А затем еще и разъяснять зачем это нужно.
Конечно это не основной функционал, а на случай когда связь с оборудованием будет потеряна.
Получается, что теперь даже такое простое действие как зафиксировать момент закрытия приложения (конец рабочего дня) нельзя?
1С такое 1С.. ради 3% (по ощущениям) пользователей веб-варианта 1С, такую свинью подкладывать.
Да, для решения этой задачи придется придумать что-то другое. Напрямую в момент закрытия приложения это сделать не получится.
Спасибо за хорошую статью!
Подозреваю, что статья интересная.
Но не имею желания регистрироваться в указанной соцсети, это противоречит моему внутреннему миру.
Какая будет альтернатива для ознакомления с материалом в pdf?
Подождать немного, когда будет подключен Facebook.
Хорошая статья и курс отличный. Курс сэкономил мне огромное количество времени, а время деньги).
Сергей, на счет Толстого клиента Вы не правы. Там поведение даже при отключенном режиме совместимости осталось прежним. Я проверил на 8.3.9.2170. О чем в принципе и синтакс-помошник говорит
Синтаксис:
ПередЗавершениемРаботыСистемы(<Отказ>)
как видите нет второго параметра.
Добрый день!
Я так понимаю, вы имеете ввиду обычный интерфейс и там действительно ничего не изменилось, но данная статья касается только управляемого интерфейса, который также умеет работать в толстом клиенте.
Чую чую … полным переходом на браузеры пахнет…А по хорошему вот сейчас проблемы то у некоторых возникнут. потому как частенько видел что пользуют сторонние решения для различных интеграций и естественно нормально отключались они при выходе. А тут по факту вылет программы а не выход. (((
Если речь идёт о версиях 8.3.8, 8.3.9, тогда получается “1С:Предприятие 8.3.8 (и младше)” :)
Совершенно верно, но в данном контексте речь идет о 8.3.8.
Добрый вечер.
Такой вопрос: “сейчас у меня в CRM2.0.9 (1С Рарус) при закрытии приложения выполняется серверный вызов в котором освобождается лицензия.
Как это можно обойти, не пользуясь решением с выдачей пользователю диалога типа – “для нормального закрытия приложения откажитесь от его закрытия, нам тут еще лицензию надо освободить”?
Пока видится только создание своей кнопки выхода, но можно хотя бы убрать пресловутый “крестик” из главного окна приложения?
Добрый день!
Ограничение на серверные вызовы обойти не получится, поэтому вариант с дополнительным диалогом не такой уж и плохой, каким кажется на первый взгляд.
К сожалению, в платформе отсутствует возможность скрытия кнопки закрытия приложения.
Как вариант, можно сделать свою кнопку выхода, а если пользователь использует стандартную, тогда вывести дополнительный диалог.
Спасибо за ответ.
Я пробовал такой прием как создание обработчика ожидания (платформа 8.3.9.2170), рассчитывая, что пока пользователь подтвердит закрытие окна, обработчик успеет сделать свое дело, но почему-то выполнение кода туда то попадает, то нет, независимо от того как долго висит вопрос о выходе из программы.
P.S.
Вы случайно не знаете почему вместо того чтобы обеспечить различное поведение при выходе из программы в зависимости от того под чем выполняется клиент, у “нормальных” приложений просто отобрали такую возможность?
Мне, например, было бы на порядок проще под обычным клиентом продолжать молча освобождать лицензии, а при работе с web идти на неудобства, благо, что в таком варианте пользователям не привыкать к странностям.
Обработчик ожидания срабатывает только после закрытия диалога, при условии, что пользователь отказался от закрытия приложения.
Я тоже не согласен с решение разработчиков “унифицировать код” в пользу веб-клиента, так как многие работают без использования веб-клиентов. Думаю, причина в том, что разработчики платформы за веб-клиентами видят будущее 1С.
Может выкрутиться, сделав регламентное задание, которое переодически будет проверять активных пользователей и у них оставлять лицензии, а у остальных, если они занимают лицензии, освобождать?
Хотя не знаю какие там лицензии у Раруса – поэтому может и не в тему написал…
Хорошая заметка, четко и по делу. Надеюсь ограничения налагаемые браузерами будут преодолены(мне кажется что некорректно игнорировать полностью сообщения от программы/страницы со стороны браузера) и у программиста появится больше возможностей по управлению закрытием.
Согласен, но остается только надеяться. Пока только IE отображает сообщения.