[Новое в платформе] Как правильно закрывать формы и приложение в платформе 1С:Предприятие 8.3.8 (и старше)
Эта статья для программистов 1С – в ней разберем новое ограничение платформы при разработке кода.
При закрытии формы обработки или при закрытии всего приложения достаточно часто используется дополнительный диалог.
В основной массе диалог представляет собой вопрос для подтверждения операции закрытия, но бывают более сложные случаи. Например, при закрытии формы подбора товаров можно запросить у пользователя разрешение на перенос подобранных товаров в документ.
Начиная с версии 8.3.8 разработчики платформы изменили подход, которому должны следовать программисты при решении подобного рода задач.
Коротко о главном…
Сначала коротко обозначим суть изменений. Начиная с версии платформы 8.3.8 необходимо выделять 2 сценария закрытия формы:
Как это повлияло на объем кода?
Кроме этого, изменения платформы серьезно затронули логику программного кода. Теперь в процессе закрытия приложения практически невозможно организовать произвольный сценарий из-за введенных ограничений. В чем суть ограничений?
Фактически теперь в процессе закрытия приложения можно указать только текст вопроса, который увидит пользователь.
Скорее всего, у вас уже возник вопрос: к чему же все эти изменения?
Приведем цитату разработчиков платформы из файла V8Update.htm, содержащего перечень изменений релизов платформы:
Теперь подробнее разъясним суть проблемы.
Раньше при выходе из системы, когда возникала задача открытия диалогов, приходилось писать программный код отдельно для веб-клиента и отдельно для других клиентов. Связано это с тем, что все современные веб-браузеры, если страница не хочет, чтобы ее закрывали, выводят свой диалог. Примеры этих диалогов вы сможете увидеть ниже, в той части статьи, где подробно рассматривается поведение веб-браузеров.
Что же сделали разработчики платформы? Теперь платформа ведет себя так же, как и веб-браузеры: если приложение не хочет, чтобы его закрывали, тогда выводится платформенный диалог. В результате нет необходимости писать код под разные клиенты, так как работает он одинаково, но платой за такую универсальность являются описанные выше ограничения.
При этом даже если мы не предполагаем использование веб-клиента в нашей базе, то это ничего не меняет. Ограничения все равно действуют. В некоторых случаях это может быть неудобным, но с этим придется мириться. В частности, теперь открытие дополнительных обработок при закрытии приложения может вызвать затруднение. Решение подобной задачи мы рассмотрим в конце статьи.
На этом завершаем краткий обзор изменений и переходим к подробному разбору.
Вопрос при закрытии формы
Изменения в коде будем рассматривать в сравнении с тем, как это делалось в предыдущих версиях платформы.
Ранее, когда в процессе закрытия формы возникала необходимость задать вопрос пользователю, использовался следующий программный код:
Если данный код попытаться выполнить на платформе 8.3.8 с отключенным режимом совместимости, тогда возникнет ошибка:
Теперь, начиная с версии платформы 8.3.8, необходимо выделять 2 сценария закрытия формы. Первый вариант – когда пользователь закрывает форму самостоятельно и второй вариант – когда форма закрывается в результате закрытия всего приложения.
Таким образом, код требует модернизации:
Как вы можете заметить, у обработчика ПередЗакрытием появились 2 новых параметра:
Теперь подробнее об изменении в коде. Как вы видите, появилась новая ветка алгоритма, которая выполняется в процессе завершения работы системы.
Обращаем ваше внимание, что никаких диалогов в этом случае не открывается, так как они запрещены. В коде устанавливается только текст предупреждения и обязательно устанавливается флаг Отказ. Как уже отмечалось выше, нельзя программным способом отменить процесс закрытия приложения, поэтому флаг Отказ работает иначе, чем при обычном закрытии формы. Установка флага указывает необходимость отображения предупреждения для пользователя, которое хранится в параметре ТекстПредупреждения.
В толстом и тонком клиенте окно предупреждения будет следующим:
Стоит отметить, что если флаг Отказ сброшен, а ТекстПредупреждения заполнен, тогда система проигнорирует текст и сообщение отображено не будет. Если же флаг Отказ установлен, а параметр ТекстПредупреждения не заполнен, тогда будет отображено системное предупреждение:
Также следует отметить, что количество подобных диалогов может быть любым – по числу закрываемых форм. Кроме того, аналогичный диалог может формироваться в обработчике ПередЗавершениемРаботыСистемы модуля управляемого приложения (этот вариант будет рассмотрен ниже). В итоге, если пользователь хотя бы в одном диалоге нажмет кнопку Продолжить работу, процесс завершения работы будет отменен и на экране останется та форма, в которой была нажата кнопка.
В веб-клиенте диалог будет выглядеть иначе. В веб-браузерах Mozilla Firefox и Google Chrome будет отображен только текст, заданный разработчиками веб-браузера и не будет отображаться текст, установленный в обработчиках событий системы.
Пример диалога для Mozilla Firefox:
Пример диалога для Google Chrome:
В веб-браузере Internet Explorer диалог будет выглядеть иначе. Будет отображен единый диалог, содержащий все сообщения, установленные в обработчиках формы и модуле управляемого приложения:
Стоит отметить, что если в свойствах конфигурации включен режим совместимости с 8.3.7 и более ранними версиями, то данный механизм будет работать в старом варианте.
Таким образом, при отключении режима совместимости следует проанализировать и скорректировать программный код по закрытию форм, так как если код содержит обращения к серверу или код по открытию дополнительных форм, то это будет приводить к ошибкам в процессе завершения работы системы.
Также можно сформулировать небольшую рекомендацию. Если в коде обработчика формы ПередЗакрытием, исполняемом в процессе завершения работы системы, необходимо получать дополнительные данные с сервера, то их следует получить заранее и хранить в данных формы.
Вопрос при закрытии приложения
В данном случае мы не будем приводить программный код, который использовался в предыдущих версиях для отображения вопроса при выходе из системы, так как он достаточно громоздкий. Приведем лишь новый код модуля управляемого приложения, который упростился до минимума:
Теперь для отображения вопроса при выходе из системы достаточно установить текст предупреждения и флаг Отказ равным Истина.
Опять же, в коде запрещены обращения к серверу и открытия дополнительных форм, а также поведение в веб-браузере будет аналогичным тому, что уже было описано выше.
Открытие формы обработки при закрытии приложения
В завершении статьи хотелось бы продемонстрировать прием, который позволяет открыть форму некоторой обработки в процессе завершения работы системы.
Наша задача заключается в том, чтобы отменить процесс закрытия приложения и открыть форму некоторой обработки. Проблема в том, что отменить процесс закрытия или открыть форму мы не можем, так как это запрещено.
Поэтому, для того чтобы отменить закрытие приложения, потребуется использовать предупреждение, а для того чтобы открыть форму, используем обработчик ожидания, который выполнится только в том случае, если пользователь откажется от завершения работы системы.
Используя инструкции препроцессора, мы разделили сценарии закрытия в веб-клиенте и в других видах клиентов. В случае веб-клиента мы не открываем обработку, так как практически во всех веб-браузерах текст нашего предупреждения не отображается. В других видах клиентов будет отображен наш диалог:
Если пользователь нажмет кнопку Продолжить работу, тогда сработает обработчик ожидания и будет открыта форма обработки.
Заключение
Платформа продолжает свое уверенное движение в сторону веб-браузеров, но на этот раз разработчики наложили ограничения на программный код, исполняемый в толстом и тонком клиентах. С одной стороны, это упростило и унифицировало код при закрытии форм, так как теперь нет необходимости писать несколько вариантов кода под каждый клиент, с другой стороны, это ограничило нас в возможностях.
Чтобы освоить разработку интерфейсов и форм в 1С:Предприятие 8.3
на профессиональном уровне, рекомендуем записаться на курс:
Поддержка – 3 месяца. Объем курса – 49 учебных часов.
Об авторе
Автор статьи – Сергей Калинкин
Директор ЦСО «Центр профессионального программирования», г. Казань
PDF-версия статьи для участников группы ВКонтакте
Если Вы еще не вступили в нее – сделайте это сейчас, и в блоке ниже (на этой странице) появятся ссылки на скачивание материалов.
Управляемые формы. Как программно выполнить процедуры и обработ. событий формы?
Здравствуйте Уважаемые коллеги. Столкнулся с задачей выполнить процедуру управляемой формы, но что-то как-то не получается.
Коротко: в УТ11 создается программно элементы справочника вид цен. И все бы хорошо, только вот этот вид цен работать не будет до тех пор, пока элемент не откроешь в программе вручную, а затем нажмешь «Записать и закрыть».
Объекты создаются на сервере.
Проверял в отладчике, события формы элемента естественно не выполняются(при создании и записи).
Пробывал создовать объекты на сервере, затем по ссылке открывать формы на клиенте, все равно обработчики событий не срабатывают!
&НаКлиенте
Процедура ЗагрузитьНаКлиенте()
Для Каждого Строка Из МассивСсылок Цикл
ПараметрыОткрытия = Новый Структура(«Ключ», Строка);
ФормаОбъекта = ПолучитьФорму(«Справочник.ВидыЦен.Форма.ФормаЭлемента», ПараметрыОткрытия);
ФормаОбъекта.Открыть();
//ОЗ = ДанныеФормыВЗначение(Объект, Тип(«Справочник.ВидыЦен.Форма.ФормаЭлемента»));
ЭтаФорма.ОбновитьОтображениеДанных();
ФормаОбъекта.Закрыть();
На сервере создаются так:
&НаСервере
Процедура СоздатьВидЦен(КоллекцияАтрибутов, БазовыйВидЦен = Неопределено)
НовыйВидЦен.Заполнить(Неопределено);
НовыйВидЦен.Наименование = КоллекцияАтрибутов.ПолучитьИменованныйЭлемент(«Наименование»).Значение;
// недопустимо пустое наименование
Если Не ЗначениеЗаполнено(НовыйВидЦен.Наименование) Тогда
НовыйВидЦен.Наименование = Новый УникальныйИдентификатор();
КонецЕсли;
// не допустимы не уникальные идентификаторо относительно всех видов цен
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(«Идентификатор», НовыйВидЦен.Идентификатор);
Запрос.Текст = «ВЫБРАТЬ
| ВидыЦен.Ссылка
|ИЗ
| Справочник.ВидыЦен КАК ВидыЦен
|ГДЕ
| ВидыЦен.Идентификатор = &Идентификатор»;
РезультатВыполнения = Запрос.Выполнить();
Если Не РезультатВыполнения.Пустой() Тогда
НовоеНаименование = НовыйВидЦен.Наименование + «_» + Новый УникальныйИдентификатор();
Если КоллекцияАтрибутов.ПолучитьИменованныйЭлемент(«ЦенаВключаетНДС»).Значение = «1» Тогда
НовыйВидЦен.ЦенаВключаетНДС = Истина;
КонецЕсли;
НовыйВидЦен.ИспользоватьПриПродаже = Истина;
НовыйВидЦен.ИспользоватьПриПередачеМеждуОрганизациями = Истина;
// проверим, если валюту не нашли отменяем создание вида цены
Если Не ЗначениеЗаполнено(НовыйВидЦен.ВалютаЦены) Тогда
Сообщить («Не удалось создать вид цен: » + НовыйВидЦен.Наименование + «. Причина: не найдена валюта цены с кодом: [» + КоллекцияАтрибутов.ПолучитьИменованныйЭлемент(«Валюта»).Значение + «]»);
Возврат;
КонецЕсли;
// Определимся, вдруг расчитывается на основании базовой цены
Если ЗначениеЗаполнено(БазовыйВидЦен) Тогда
НовыйВидЦен.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.РассчитыватьПоДругимВидамЦен;
ПроцентнаяСтавка = КоллекцияАтрибутов.ПолучитьИменованныйЭлемент(«Процент»).Значение;
Если Число(ПроцентнаяСтавка) >= 0 Тогда
НовыйВидЦен.АлгоритмРасчетаЦены = «[» + БазовыйВидЦен.Идентификатор + «] * ((100 + » + Строка(ПроцентнаяСтавка) + «) / 100)»;
Иначе
НовыйВидЦен.АлгоритмРасчетаЦены = «[» + БазовыйВидЦен.Идентификатор + «] * ((100 » + Строка(ПроцентнаяСтавка) + «) / 100)»;
КонецЕсли;
Иначе
НовыйВидЦен.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.Вручную;
КонецЕсли;
Вообще это все пишется для обработки переноса данных из писаной-переписанной семерки в УТ11. Так сказать, одноразовая обработка, лишь бы перебросить данные ))))
Вопрос: как программно эмулировать открытие формы и нажатие кнопки «Записать и закрыть» в управляемом приложении, так что бы выполнились все стандартные обработчики соответствующих событий формы? Желательно, что бы пользователь не наблюдал открытия и закрытия формы, но необязательно.
Переопределение кнопки «Провести и закрыть»
Уверен, что для многих эта задача не представляет никакой сложности. Очень даже возможно, что эта задача решается и другими способами.
Имеется: Документ с реквизитами НомерВх и ДатаВх, а также основная форма документа
Зачада: Перед записью необходимо задать вопрос пользователю и по результату ответа продолжить запись, либо не продолжать.
В свойствах формы редактируем список команд: снимаем галки с команд «Провести и закрыть», «Записать», «Провести».
Для командной панели убираем признак «Автозаполнение». Добавляем на форму свои команды, а также добавляем группу с типовыми командами. Далее описываем код для созданных команд:
Далее описываем код команд и проверку на дубли
Для каждой команды определяем ПараметрыЗаписи, а также добавляем признак «Закрыть», чтобы после того, как будет задан вопрос, можно было определить надо ли закрывать форму или оставить форму открытой.
Собственно, процедура самой проверки
Далее процедура обработки оповещения, в которой происходит запись и закрытие документа (если он должен закрыться)
Остается ещё один момент: документ может быть записан при закрытии на крестик, тогда будут отрабатывать только типовые механизмы записи документа. Для себя решил это следующим образом (возможно, не очень правильно):
Добавлен реквизит формыВ процедуре ПередЗаписью следующий код
В процедуре ПриСозданииНаСервере устанавливаем флаг в положение ИСТИНА
Вот и всё, типовые команды заменены на наши и можно задавать вопросы пользователю до записи документа. Надеюсь статья будет кому-то полезна. Самого на написание статьи подтолкнула ситуация, когда при нажатии на кнопку «Провести и закрыть» выводится вопрос, подтверждаю запись, но документ не закрывается, закрыть документ можно только по крестику.
Открыть форму выбора и сохранить выбранное значение для дальнейшего использования.
Пишу так:
ФормаВыбора = ПланыСчетов.Хозрасчетный.ПолучитьФормуВыбора();
ВыбранноеЗначение = ФормаВыбора.ОткрытьМодально();
Ошибка: Интерактивные операции недоступны
Пишу так:
ФормаОснования = ПолучитьФорму(«ПланСчетов.Хозрасчетный.ФормаВыбора»);
ВыбранноеЗначение = ФормаОснования.Открыть();
Ошибка:
Обращение к процедуре объекта как к функции (Открыть)
ВыбранноеЗначение = ФормаОснования.Открыть();
Как открыть форму выбора и сохранить выбранное значение для дальнейшего использования?
(0) Ты хоть скажи, с какой ты планеты (зачеркнуто) ОФ/УФ.
По контексту ОФ, но вдруг..
вот несколько примеров
Это сработает, если в форме выбора для списка на форме у тебя установлен признак «РежимВыбора».
Тогда когда в форме будет даблклик, в форму владельца (обработку) тебе прилетит событие формы ОбработкаВыбора() с выбранным значением.
(33) А что мешало посмотреть, как это работает в типовой конфе, да в той же бухгалтерии? Зачем вы пытались использовать модальный режим? В управляемых формах его практически не используют, в конфигураторе вообще может быть запрет на модальный режим. Вы могли просто открыть форму выбора, в данной форме после закрытия использовать команду ОповеститьОВыборе(результат). В форме источнике использовать событие обработка выбора и там уже обрабатывать полученный результат. Без всяких там доп оповещений.
пример:
&НаКлиенте
Как обновить форму документа после изменения данных
хотела обновить реквизит измененный
УправляемаяФорма (ManagedForm)
ОбновитьОтображениеДанных (RefreshDataRepresentation)
Синтаксис:
Тип: ГруппаФормы; ТаблицаФормы; ПолеФормы; Массив.
Если параметр задан, то установка значений (и обновление) будет выполняться только для тех элементов, которые заданы в параметре. Если в качестве значения передан пустой массив, то ни для каких элементов формы установка значений выполнена не будет.
После вызова метода признак необходимости установки значений и обновления для элементов формы сбрасывается: если после вызова метода никакие данные формы не меняются, то ни для никаких элементов, кроме указанных, текст обновлен не будет.
Если параметр имеет значение типа Массив, то элементами массива могут быть только значения типа ГруппаФормы, ТаблицаФормы, ПолеФормы.
Если массив содержит значение другого типа, то будет выдано исключение о неверном типе параметра.
Вызов метода ОбновитьОтображениеДанных с параметром имеет смысл только внутри обработчика ВнешнееСобытие, обработчиков ожидания формы и обработчика ОбработкаОповещения.
В обработчиках других событий вызов этого метода с параметром аналогичен вызову без параметра (при необходимости данные будут установлены всем элементам управления).
Описание:
В принудительном порядке обновляет содержание элементов управления.
Полезен при изменении значений реквизитов формы вне формы, в тот момент, когда форма отображается на экране.
Тонкий клиент, веб-клиент, толстый клиент, мобильное приложение(клиент).
Примечание:
В веб-клиенте обновление элементов управления происходит не сразу, а после окончания выполнения кода на встроенном языке.