О чем эта статья
Это финальная статья нашего цикла статей “Первые шаги в программировании на 1С”.
В статье будут рассмотрены основные причины отказа от модальности в платформе «1С:Предприятие» и основные методы преобразования участков кода на новую асинхронную модель.
Применимость
В статье рассматриваются асинхронная модель построения бизнес-логики, добавленная платформу «1С:Предприятие» редакции 8.3. Представленная информация актуальна для текущих релизов платформы.
Отказ от использования модальных окон в платформе 1С:Предприятие 8.3
При разработке конфигурации на платформе 1С:Предприятие 8 периодически возникает потребность приостановить работу программы до того момента, когда пользователь примет какое-либо решение или выполнит какие-либо действия.
Например, при нажатии на кнопку заполнения табличной части у пользователя следует спросить, нужно ли очистить табличную часть, чтобы не произошло потери ранее введенных данных.
Такое поведение может обеспечить, например, следующий код:
Процедура ЗаполнитьТовары(Команда)
Ответ = Вопрос(“Табличная часть будет очищена. Продолжить?”, РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
//алгоритм заполнения
КонецЕсли;
КонецПроцедуры
В результате работы этого фрагмента кода произойдет приостановка выполнения программного кода, на экране отображается вопрос, интерфейс приложения кроме диалога с вопросом становится недоступным, система ожидает принятия решения пользователем, выполнение кода продолжится только после ответа на вопрос.
Также к приостановке выполнения кода и блокировке интерфейса приводит открытие модальных окон при помощи вызова метода ОткрытьМодально().
При работе с конфигурацией в режиме веб-клиента через браузер в этом случае будет открыто новое окно – всплывающее окно, которое заблокирует не только текущую вкладку, но и весь интерфейс браузера, включая остальные открытые окна и вкладки.
Всплывающие окна в Интернете зачастую используются для злоумышленного распространения нежелательной рекламы, поэтому браузеры содержат функции блокировки всплывающих окон.
В таком случае для работы с конфигурациями 1С:Предприятие 8 через браузер необходимо запретить блокирование всплывающих окон.
Проблемы также возникают при работе на мобильных устройствах. Так, например, модальные окна не поддерживаются на iPad.
Для решения указанных проблем следует использовать блокирующие окна вместо модальных. Для пользователя визуально все выглядит так же: окно блокирует интерфейс веб-клиента.
Однако блокирующее окно как бы “рисуется” поверх главного окна, и блокируется только текущая вкладка браузера, в которой открыта конфигурация, позволяя переключаться на другие вкладки, поскольку модальные окна браузера при этом не используются.
Таким образом, всплывающие окна в браузере не открываются и обеспечивается работа через веб-клиент на мобильных устройствах.
У корневого элемента конфигурации существует свойство “Режим использования модальности”, которое определяет, можно ли в конфигурации открывать модальные окна.
Если выбран вариант “Использовать”, то модальные окна можно открывать. Если выбран вариант “Не использовать”, то модальные окна недопустимы. При попытке вызвать метод, открывающий модальное окно, система выводит сообщение об ошибке:
При таком значении свойства “Режим использования модальности” допустимы только блокирующие окна.
Если выбран вариант “Использовать с предупреждениями”, то при открытии модальных окон в окно сообщений выводится текст:
Такой вариант работы может использоваться как промежуточный при переработке конфигурации с целью отказа от использования модальных окон.
Основное отличие блокирующих окон от модальных заключается в том, что открытие блокирующего окна не производит приостановки выполнения кода.
Поэтому разработчикам придется переписать программный код, использующий модальные окна, с учетом этой особенности.
Код нужно разделить на две части:
- открытие блокирующего окна;
- обработка выбора пользователя.
Фрагмент кода, приведенный в начале статьи, нужно переписать следующим образом:
Процедура ЗаполнитьТовары(Команда)
Оповещение = Новый ОписаниеОповещения(“ЗаполнитьТоварыВопросЗавершение”, ЭтотОбъект);
ТекстВопроса = “Табличная часть будет очищена. Продолжить?”;
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьТоварыВопросЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
//алгоритм заполнения
КонецЕсли;
КонецПроцедуры
После выполнения процедуры ПоказатьВопрос() система не останавливается, ожидая ответ пользователя, исполнение кода продолжается.
Пользователь сможет сделать выбор только после завершения работы всей процедуры. При этом будет вызвана экспортная процедура ЗаполнитьТоварыВопросЗавершение(). Ее название мы передали в конструктор объекта ОписаниеОповещения.
Процедура, которая будет вызвана после осуществления выбора, может быть расположена в модуле формы, модуле команды, общем не глобальном модуле.
В рассмотренном примере вызываемая процедура расположена в модуле управляемой формы, поэтому мы передали в параметр ЭтотОбъект.
Рассмотрим вызов процедуры, расположенной в общем модуле. Для этого добавим новый общий модуль ОбработкаОповещений, установим для него флаг “Клиент (управляемое приложение)”, а признак “Глобальный” не устанавливаем. Расположим в этом модуле процедуру ЗаполнитьТоварыВопросЗавершение().
Тогда обработчик команды заполнения будет выглядеть так:
Процедура ЗаполнитьТовары(Команда)
Оповещение = Новый ОписаниеОповещения(“ЗаполнитьТоварыВопросЗавершение”,
ОбработкаОповещений);
ТекстВопроса = “Табличная часть будет очищена. Продолжить?”;
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
После вызова любого метода, открывающего блокирующее окно, процедура должна завершаться, а выполняемый далее код следует располагать в процедуре, которая будет вызвана после закрытия окна.
Для передачи контекста (вспомогательных данных, неких параметров, значений переменных) из процедуры, открывающей модальное окно, в процедуру, вызывающуюся при его закрытии, предусмотрен третий необязательный параметр конструктора объекта ОписаниеОповещения – ДополнительныеПараметры.
Этот объект (любого типа) будет передан в процедуру, описанную в ОписаниеОповещения, последним параметром.
На примере рассмотренного выше участка кода это можно сделать так:
Процедура ЗаполнитьТовары(Команда)
Параметр1 = 0;
Параметр2 = 0;
СписокПараметров = Новый Структура(“Параметр1, Параметр2″, Параметр1, Параметр2);
Оповещение = Новый ОписаниеОповещения(“ЗаполнитьТоварыВопросЗавершение”, ЭтотОбъект,
СписокПараметров);
ПоказатьВопрос(Оповещение, “Табличная часть будет очищена. Продолжить?”,
РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьТоварыВопросЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
//анализируем ДополнительныеПараметры.Параметр1
//анализируем ДополнительныеПараметры.Параметр2
КонецЕсли;
КонецПроцедуры
Если нужно передать только одно значение, то структуру можно не использовать, а присвоить это значение параметру ДополнительныеПараметры конструктора объекта ОписаниеОповещения.
Рассмотрим несколько примеров работы с блокирующими окнами.
Задача 1. Открытие другой формы
Из формы документа по нажатию на кнопку “Открыть параметры” нужно открыть форму, на которой расположены два флажка Параметр1 и Параметр2, которые должен установить пользователь. После закрытия формы вывести в строку сообщений значения параметров.
Создаем общую форму “ФормаПараметров”, на которой размещаем реквизиты Параметр1 и Параметр2, а также команду ЗакрытьФорму:
Обработчик команды выглядит следующим образом:
Процедура ЗакрытьФорму(Команда)
СписокПараметров = Новый Структура(“Параметр1, Параметр2”, Параметр1, Параметр2);
Закрыть(СписокПараметров); КонецПроцедуры
Для формы свойство РежимОткрытияОкна устанавливаем в “Блокировать весь интерфейс”:
На форме документа располагаем команду ОткрытьПараметры, обработчик которой описываем следующим образом:
Процедура ОткрытьПараметры(Команда)
Оповещение = Новый ОписаниеОповещения(“ОткрытьПараметрыЗавершение”, ЭтотОбъект);
ОткрытьФорму(“ОбщаяФорма.ФормаПараметров”, , , , , , Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ОткрытьПараметрыЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если ТипЗнч(Результат) = Тип(“Структура”) Тогда
Для каждого КлючЗначение Из Результат Цикл
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Ключ: “”” + КлючЗначение.Ключ + “””, значение = ”
+ КлючЗначение.Значение;
Сообщение.Сообщить();
КонецЦикла;
КонецЕсли;
КонецПроцедуры
В пользовательском режиме, запуская конфигурацию под веб-клиентом, получаем такие результаты работы:
Для увеличения нажмите на изображение.
Режим открытия окна можно также указывать в последнем параметре процедуры ОткрытьФорму.
Процедура ОткрытьПараметры(Команда)
Оповещение = Новый ОписаниеОповещения(“ОткрытьПараметрыЗавершение”, ЭтотОбъект);
ОткрытьФорму(“ОбщаяФорма.ФормаПараметров”, , , , , , Оповещение,
РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс);
КонецПроцедуры
Задача 2. Вопрос при закрытии формы
При закрытии окна обработки задавать пользователю вопрос, действительно ли он хочет закрыть окно.
Эту задачу можно решить при помощи следующего кода, расположенного в модуле формы обработки:
Перем НужноЗакрыватьФорму;
&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
Если НЕ НужноЗакрыватьФорму = Истина Тогда
Отказ = Истина;
Оповещение = Новый ОписаниеОповещения(“ПередЗакрытиемЗавершение”, ЭтотОбъект);
ПоказатьВопрос(Оповещение, “Вы действительно хотите закрыть окно?”,
РежимДиалогаВопрос.ДаНет);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытиемЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
НужноЗакрыватьФорму = Истина;
Закрыть();
Иначе
НужноЗакрыватьФорму = Неопределено;
КонецЕсли;
КонецПроцедуры
В процедуре ПередЗакрытием формы пользователю задается вопрос, флаг Отказ выставляется в Истина, закрытие формы отменяется.
После утвердительного ответа на вопрос переменная НужноЗакрыватьФорму устанавливается в Истина, форма закрывается повторно.
Задача 3. Ввод числового значения
При нажатии на кнопку на форме обработки открывать стандартный диалог ввода числа.
Для этого необходимо воспользоваться методом ПоказатьВводЧисла() вместо ВвестиЧисло(), который открывает блокирующее окно вместо модального.
Процедура ВводЧисла(Команда)
Оповещение = Новый ОписаниеОповещения(“ВводЧислаЗавершение”, ЭтотОбъект);
ПоказатьВводЧисла(Оповещение, 0, “Введите количество”, 15, 3);
КонецПроцедуры
&НаКлиенте
Процедура ВводЧислаЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если НЕ Результат = Неопределено Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = “Вы ввели количество ” + Результат;
Сообщение.Сообщить();
КонецЕсли;
КонецПроцедуры
После закрытия окна ввода числа будет вызвана процедура, в первый параметр которой будет передано введенное число или значение Неопределено, если пользователь отказался от ввода.
Задача 4. Выбор цвета
При нажатии на кнопку на форме обработки при помощи стандартного диалога выбора цвета пользователь указывает необходимый цвет. Этот цвет установить для фона нажимаемой кнопки.
Добавим на форму команду ВыборЦвета со следующим обработчиком:
Процедура ВыборЦвета(Команда)
ДиалогВыбораЦвета = Новый ДиалогВыбораЦвета;
Оповещение = Новый ОписаниеОповещения(“ВыборЦветаЗавершение”, ЭтотОбъект);
ДиалогВыбораЦвета.Показать(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ВыборЦветаЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если НЕ Результат = Неопределено Тогда
Элементы.ВыборЦвета.ЦветФона = Результат;
КонецЕсли;
КонецПроцедуры
Для объектов ДиалогВыбораЦвета (а также ДиалогРедактированияСтандартногоПериода, КонструкторФорматнойСтроки, ДиалогРасписанияРегламентногоЗадания, ДиалогВыбораШрифта) метод Показать() открывает блокирующее окно.
После закрытия окна будет вызвана процедура, в первый параметр которой будет передано выбранное значение (цвет, шрифт и т.д.) или значение Неопределено, если пользователь отказался от выбора.
Следует обратить внимание, что объект ДиалогВыбораФайла не имеет метода Показать() в отличие от диалогов выбора цвета или шрифта, поскольку реализация этих диалогов существенно разная.
Для использования диалога выбора файла на веб-клиенте необходимо предварительно подключить расширение работы с файлами.
Диалоги, реализуемые через расширение работы с файлами, не создают таких проблем в работе, как модальные окна браузеров, поэтому не было реализовано открытие блокирующих окон для объекта ДиалогВыбораФайла.
В заключение отметим, что начиная с релиза 8.3.10 в веб-клиенте прекращена поддержка модальных окон. В этом случае, если в конфигурации происходит вызов модального метода, то происходит генерация исключения. Также в в веб-клиенте прекращена поддержка режима интерфейса В отдельных окнах. Кроме того, и в тонком, и в веб-клиенте теперь нельзя открывать форму в отдельном окне (при работе в режиме интерфейса В Закладках). Такие кардинальные шаги позволили отказаться от режима интерфейса, который уже не поддерживается всеми современными браузерами.
Какой практический вывод можно сделать из этой информации? А вывод довольно простой – если по какой-то причине в вашей конфигурации до сих пор существуют модальные вызовы, то в этих местах в в веб-клиенте будет выдаваться окно с сообщением об ошибке. Хочется предостеречь от попыток “нагуглить” какое-то быстрое решение данной проблемы, т.к. основная масса советов сводится к такому рецепту: в конфигураторе на уровне конфигурации в свойстве «Режим использования модальности» поставить значение «Использовать». Естественно, в данный момент, это работать не будет только из-за того, что сами современные браузеры уже не поддерживают модальные вызовы.
И у вас есть всего два пути, каким образом решить описанную выше проблему:
- Обновить платформу до релиза 8.3.10+ (8.3.11), установить свойство конфигурации «Режим совместимости» в «Не использовать» и переписать фрагменты кода, использующие модальные методы на асинхронную модель построения бизнес-логики
- Рекомендовать вашим клиентам пользоваться устаревшими браузерами, где модальные вызовы еще поддерживались (Mozilla Firefox версии 37 и ниже, Chrоme ниже 37 версии и т.д.).
Кстати, начиная с релиза 8.3.11, больше не поддерживаются веб-браузеры Microsoft Internet Explorer версий 8 и 9.
С веб-браузерами в свете модальности мы разобрались, теперь настала пора прояснить ситуацию и с остальными клиентами.
Начиная с версии 8.3.5 свойство «Режим использования модальности» в тонком и толстом клиентах учитывается, только если указан параметр командной строки /EnableCheckModal. Этот параметр автоматически подставляется в командную строку только при запуске приложения из конфигуратора. Если же этот параметр не указан, то генерация исключений не происходит и соответствующие предупреждения не показываются. Т.е. на практике в случае использования толстого и тонкого клиента никакого кардинального изменения в работе при использовании режима модальности не наблюдается – модальные вызовы будут работать так же, как и работали ранее, при этом не выдавая никаких предупреждений, как в веб-клиенте.
Чтобы расставить все точки над “i”, заметим, что начиная с редакции 8.3.9 в толстом клиенте игнорируется свойство конфигурации «Режим использования синхронных вызовов расширений платформы и внешних компонент», при этом соответствующие синхронные методы работают без генерации исключений и вывода предупреждений. Указанное игнорируемое свойство было добавлено в редакции 8.3.5 с целью поддержки асинхронной работы с внешними компонентами, криптографией и расширениями для работы с файлами в веб-браузере Google Chrome. Понятно, что к толстому клиенту это никакого отношения не имеет, и поэтому “тихое” игнорирование данного свойства просто исключило лишние проверки использования синхронных методов при использовании конфигурации.
Кстати! Из-за того, что платформа уверенно движется в сторону веба, с версии 8.3.8 разработчики ввели определенные ограничения на программный код, который связан с логикой закрытия формы или приложения, исполняемый в толстом и тонком клиентах. Обязательно прочтите нашу статью, подробно освещающую этот нюанс. Кроме того, в курсе «Профессиональная разработка интерфейсов и форм в 1С:Предприятие 8.3», есть глава, посвященная отказу от модальности, и вы можете почерпнуть массу полезной и актуальной информации по этой теме.
Коллеги, существуют две вещи которые можно читать бесконечно: ленту вконтакте и список изменений в очередном релизе платформе, поэтому, давайте подводить окончательные итоги ;)
В процессе рассмотрения примеров, позволяющих перейти от элементов синхронной модели к асинхронной, вы, наверное, уже заметили, что в общем случае программного кода стало больше. Чем больше кода, тем больше повышается сложность его дальнейшего сопровождения и отладки.
Кроме того, количество кода еще более увеличится, если мы в процессе разработки будем использовать большее количество диалогов. Поэтому в процессе разработки прикладных решений, ориентированных на работу в веб-клиенте, нужно помнить о той парадигме работы, которая используется в данный момент в современных веб-приложениях. Поэтому если в вашей конфигурации много интерактивных диалогов с пользователем, выдаваемых предупреждений, то есть смысл пересмотреть данную функциональность в пользу каких-то других подходов в организации взаимодействия с пользователем.
Вместо заключения
Вот и подошел к концу наш цикл «Первые шаги в разработке на 1С». Если вы прочли его целиком, то скорее всего, уже заметили, какими семимильными шагами развивается платформа в последнее время. Материал данного цикла был написан относительно недавно, однако мы были вынуждены его серьезно актуализировать, т.к. даже за такой короткий срок появилась масса новых важных функциональных возможностей и изменений. Такие крупные изменения могут несколько озадачить программиста 1С, если он не рос и не развивался в профессиональном плане с платформой все это время.
На специализированных интернет-ресурсах часто можно прочесть просьбы от начинающих программистов и их более зрелых коллег посоветовать им материалы, которые помогли бы им разобраться в обширных и порой кажущихся бесконечными, возможностях платформы 1С. Мы, по традиции, рекомендуем обратить ваше внимание на наши курсы по программированию. Это сотни часов видео по самым актуальным темам от признанных гуру-разработки ;)
А как же «не переключайтесь»? Естественно! У нас еще тонны интересного и полезного материала по разработке, оптимизации и еще многому чему. Так что, изучайте, применяйте и да прибудет с вами сила ;)
PDF-версия статьи для участников группы ВКонтакте
Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.
Если Вы еще не вступили в группу – сделайте это сейчас и в блоке ниже (на этой странице) появятся ссылка на скачивание материалов.
Статья в PDF-формате
Вы можете скачать эту статью в формате PDF по следующей ссылке: Курсы-по-1С.рф – Отказ от использования модальных окон в платформе 1СПредприятие 8.3.pdf
Ссылка доступна для зарегистрированных пользователей)
Ссылка доступна для зарегистрированных пользователей)
Ссылка доступна для зарегистрированных пользователей)
Здравствуйте! Подскажите, пожалуйста, для чего идет закрытие структуры в первой задаче? никогда такого не видела..
Процедура ЗакрытьФорму(Команда)
СписокПараметров = Новый Структура(“Параметр1, Параметр2”, Параметр1, Параметр2);
Закрыть(СписокПараметров);
КонецПроцедуры
Добрый день!
В Синтакс-помощнике приведено такое описание метода Закрыть:
Закрыть(< ПараметрЗакрытия>)
Параметры:
< ПараметрЗакрытия> (необязательный)
Тип: Произвольный.
Параметр закрытия формы, открытой в модальном режиме. Это значение будет возвращено как результат метода, открывающего форму модально.
Таким образом, эта структура – это результат работы формы. Мы открыли форму, в ней выполнили какие-то действия, получили результат, который и передали при закрытии формы тому коду, который эту форму открыл. Значит, в зависимости от этого результата можно выполнять те или иные действия.
Спасибо большое за ответ!!!
“Поэтому если в вашей конфигурации много интерактивных диалогов с пользователем, выдаваемых предупреждений, то есть смысл пересмотреть данную функциональность в пользу каких-то других подходов в организации взаимодействия с пользователем.”
Какие подходы в сторону которых рекомендуете пересмотреть данную функциональность, имеете здесь ввиду?
Добрый день!
Например, вместо предупреждения выводить сообщение пользователю. Или вместо вопроса сделать на форме переключатели или галочки, которые будут определять логику обработки данных.
Добрый день!
Столкнулся с проблемой (в конфигурации в которой не разрешены синхронные методы работы) – нужно записать файл на локальный диск, в каталог, которого не существует. Не могу найти информацию о том, как это можно / нужно реализовать асинхронно? Т.е. нужно либо создать каталог – до начала выполнения “ПолучитьФайл(Адрес, УникальноеПутьИИмяСохраняемогоФайла, НЕ Интерактивно)”, либо как то “уговорить” метод глобального контекста “ПолучитьФайл()” при записи в несуществующий каталог одновременно и каталог создать… Либо необходимо использовать что то другое… В общем не нашел решения… Не понимаю, как используя асинхронные методы “породить” на локальном диске каталог… Можете помочь советом?
Добрый день!
Можно воспользоваться методом глобального контекста НачатьПолучениеФайлов:
Процедура ПолучитьКартинку(Команда)
ОписаниеФайлов = Новый Массив;
ОписаниеФайлов.Добавить(Новый ОписаниеПередаваемогоФайла("C:\Downloads\Картинки\1.png", АдресКартинки));//такого файла и каталога на диске не существует!
Оповещение = Новый ОписаниеОповещения("ПолучитьКартинкуЗавершение", ЭтотОбъект);
НачатьПолучениеФайлов(Оповещение, ОписаниеФайлов, , Ложь);
КонецПроцедуры
&НаКлиенте
Процедура ПолучитьКартинкуЗавершение(ПолученныеФайлы, ДополнительныеПараметры) Экспорт
Если ПолученныеФайлы = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ПолученныеФайлы) = Тип("Массив") Тогда
Для каждого ПолученныйФайл Из ПолученныеФайлы Цикл
Сообщить(ПолученныйФайл.Имя);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
В переменной АдресКартинки находится адрес во временном хранилище, где размещается файл. Для помещения во временное хранилище можно использовать методы ПоместитьВоВременноеХранилище, НачатьПомещениеФайла.
Спасибо! Этот метод действительно создает и файл и каталог, даже если его физически не существовало на локальном диске!
Пожалуйста! Хорошего обучения!
Только вот не понятно как должно работать с функциями. Пример, УТ 3.1 для Украины. Расшифровка СКД, ОписаниеОбработкиРасшифровки = КомпоновкаДанныхКлиент.ОбработатьРасшифровку(ЭтаФорма, "АнализДоступностиТоваров", Расшифровка, СтандартнаяОбработка);
То есть вызывается функция в общем мудуле, в этой функции есть
ОбработкаРасшифровки.ВыбратьДействие(Расшифровка, ВыполненноеДействие, ПараметрВыполненногоДействия);
Выбрать действие – открывается модально список действий. Вместо него надо использовать
Оп = Новый ОписаниеОповещения("РезультатОбработкаРасшифровки_Продолжение", КомпоновкаДанныхКлиент, Новый Структура("Расшифровка, ИмяРеквизитаФормы, Форма",Расшифровка, ИмяРеквизитаФормы,Форма));
ОбработкаРасшифровки.ПоказатьВыборДействия(Оп, Расшифровка);
Но как вы понимаете это не приведет к чему то хорошему, потому что процедура РезультатОбработкаРасшифровки_Продолжение выполнится только после окончания выполнения основной функции. То есть в расшифровку так ничего и не вернется. Сработает только для открытия значения, а если мы хотим расшифровку – кина не будет. Функция уже закончила свой вызов
Добрый день!
Смотрю типовую конфигурацию УТ 11. В ней для обработки расшифровки используются процедуры.
В свежих релизах метод ОбработатьРасшифровку из общего модуля КомпоновкаДанныхКлиент – это процедура.
Образец кода для обработки расшифровки:
&НаКлиенте
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(Отчет));
ОписаниеОповещения = Новый ОписаниеОповещения("ПоказатьВыборДействияЗавершение", ЭтаФорма);
ДоступныеДействия = Новый Массив;
ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение);
ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.Отфильтровать);
ДополнительныеПунктыМеню = Новый СписокЗначений;
ДополнительныеПунктыМеню.Добавить("Пункт1");
ДополнительныеПунктыМеню.Добавить("Пункт2");
Подменю = Новый СписокЗначений;
Подменю.Добавить("Пункт3");
ДополнительныеПунктыМеню.Добавить(Подменю, "Подменю");
ОбработкаРасшифровки.ПоказатьВыборДействия(ОписаниеОповещения, Расшифровка, ДоступныеДействия, ДополнительныеПунктыМеню);
КонецПроцедуры
&НаКлиенте
Процедура ПоказатьВыборДействияЗавершение(ВыполненноеДействие, ПараметрВыполненногоДействия, ДополнительныеПараметры) Экспорт
Если ВыполненноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение Тогда
ПоказатьЗначение(Неопределено, ПараметрВыполненногоДействия);
КонецЕсли;
КонецПроцедуры
Добрый день. Подскажите, есть ли возможность запретить “всплывающие окно”, при создании нового контрагента, когда программа предлагает автоматически заполнить ее ?
Добрый день!
По описанию непонятно, о чем именно идет речь. Предполагаю, что имеется в виду конкретная типовая конфигурация. Тогда надо анализировать конкретный программный код, который выводит это окно.
Вопрос не совсем по теме, но очень близко
БП 3.0
Внешняя обработка для заполнения строк документа, требуется перед заполнением получить у пользователя дополнительные параметры
Если обработку делать в режиме “ЗаполнениеФормы”, то при запуске обработки выполняется процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды) в МОДУЛЕ ОБРАБОТКИ
Вопрос как из модуля обработки открыть форму для ввода параметров с ОписаниеОповещения ?
Добрый день!
Команды вида ЗаполнениеФормы – серверные, вызвать клиентскую процедуру с сервера нельзя, поэтому при использовании такого вида внешней обработки нельзя открыть форму для взаимодействия с пользователем.
здравствуйте!
у меня в обработке происходит загрузка данных (заявок с номенклатурой) из внешней БД Firebird и в случае, если в БД 1С находятся несколько номенклатур с таким же артикулом, что и у загружаемой номенклатуры, то я открываю форму методом ОткрытьМодально (), где пользователь выбирает из списка этих номенклатур с одинаковым артикулом необходимую номенклатуру для дальнейшей загрузки данных. другими словами выполнение цикла останавливается, пока пользователь не выберет нужную номенклатуру.
из предложенных вариантов ухода от модальности, мне вроде бы следует использовать метод ПоказатьФорму (), но как быть с циклом? ведь выполнение кода не остановится и продолжится без результата выбора пользователя.
как быть?
Добрый день!
Да, выполнение кода не остановится.
Рекомендую пересмотреть принцип работы обработки. Можно сделать по аналогии с загрузкой из клиент-банка в типовых конфигурациях. Сначала формируется таблица на форме, куда загружаются предварительные данные и выполняются проверки (например, на количество номенклатур с одинаковым артикулом). Строки или поля с ошибочными значениями подсвечиваются или выделяются пиктограммами. Загрузить такие данные в базу можно только после того, как пользователь исправит все ошибки, т.е. укажет нужную номенклатуру.
Добрый день, подскажите, пожалуйста, как открыть из внешней обработки форму выбора из справочника с отбором и получить из нее результат выбора.
Добрый день!
Вот так можно открыть форму со списком договоров выбранного на форме обработки контрагента:
Процедура ОткрытьФормуВыбора(Команда)
ПараметрыФормы = Новый Структура("Отбор", Новый Структура("Владелец", Контрагент));
Оповещение = Новый ОписаниеОповещения("ОткрытьФормуВыбораДоговораЗавершение", ЭтотОбъект);
ОткрытьФорму("Справочник._ДемоДоговорыКонтрагентов.ФормаВыбора", ПараметрыФормы, , , , , Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ОткрытьФормуВыбораДоговораЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
//в переменной Результат находится выбранный договор
//...
КонецПроцедуры
Объект ДиалогВыбораФайла ИМЕЕТ метод Показать() !!!!!!
Диалог= Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Показать(Новый ОписаниеОповещения(“ПроцОбработкаФайла”, ЭтотОбъект, Новый Структура(“Диалог”, Диалог)))
Всё работает!
Да, вы правы. Начиная с платформы 8.3.5.1383 для диалога выбора файла (каталога) это уже реализовано.
чем это
НЕ Результат = Неопределено
лучше этого?
Результат Неопределено
Добрый день!
Наверное, вы имели в виду
Тогда результат будет тот же. Только раскладку клавиатуры переключать не придется:)
Полагаю, что в случае “Результат Неопределено” на одну операцию меньше, чем “НЕ Результат = Неопределено”, т.е. только сравнение, а не отрицание + сравнение
Добрый день!
Тут однозначно не могу ответить. Не встречал информации, как именно интерпретатор работает с такими выражениями.
Пытаюсь заменить Вопрос() на ПоказатьВопрос() в процедуре ПередЗаписью() в форме документа для ОБЫЧНЫХ форм. Это похоже на задачу 2 из статьи. В экспортной процедуре, которая запускается через оповещение после нажатия кнопки пользователем (для ответа на вопрос), запускаю ЗаписатьВФорме() – чтобы заново отработались все процедуры записи.
В принципе, все работает, но есть проблема: пользователю дважды выводится сообщение о том, что документ не может быть проведен неоперативно – до вопроса и после него. Подскажите, как с этим можно побороться?
Добрый день!
Такое сообщение выводится, поскольку для документа в конфигураторе разрешено оперативное проведение (закладка Движения). Если его запретить, вопрос не возникает.
Это будет “не спортивное поведение”, его мы приберегли в качестве плана “Б”. Возможно ли другое решение, без запрета оперативного проведения?
Попробуйте воспользоваться свойством формы документа ИспользоватьРежимПроведения.
К сожалению, этот вариант тоже не подходит. Существует ряд проверок, которые выполняются при проведении документа в оперативном режиме. Если проводить неоперативно, то система пропустит львиную долю процедур. Кроме того, большинству пользователей запрещено неоперативное проведение.
Неужели нет решения для оперативного проведения?
Это сообщение генерируется платформой, а не в прикладном коде. Поэтому повлиять на него проблематично. Можно задать или на уровне всего объекта метаданных, или в свойстве формы. Могу предложить еще только попробовать работать со свойством формы документа ИспользоватьРежимПроведения программно. Реализовать требуемую логику в зависимости, например, от прав пользователей и т.д.
И вопрос – почему возникла необходимость использовать ОписаниеОповещения в обычных формах?
У нас используется сильно переписанная УТ 10.3. Мы навесили на нее модуль на управляемых формах, позволяющий клиентам подключаться к базе через web. Однако, людей сильно напрягает необходимость разрешать всплывающие окна в браузере, поэтому руководством поставлена задача – отказаться от модального режима. В процессе решения этой задачи наткнулись на Вопрос(), который отрабатывает в процедуре ПередЗаписью() в модуле формы документа.
Очень понравилось решение, которое описано в вашей статье в задаче 2 (там и используется ОписаниеОповещения), но… есть тонкости :)
В типовой УТ 11 в процедуре ПередЗаписью() в форме документа используется код, похожий на разобранный в статье. Посмотрите, может, он наведет на какие-нибудь еще идеи.
Можно ли передать данные из открытой формы в процедуру-обработчик оповещения (в Задаче 1 это ОткрытьПараметрыЗавершение) кроме как с использованием метода Закрыть(СписокПараметров), не создавая свою кнопку?
Добрый день!
В подчиненной форме можно определить следующий обработчик события:
Процедура ПриЗакрытии()
СтруктураРезультат = Новый Структура("
|БанковскийСчетОрганизации,
|Руководитель, ЗаРуководителяПоПриказу,
|ГлавныйБухгалтер, ЗаГлавногоБухгалтераПоПриказу,
|ДоверенностьЧерезКого, ЗаЗаказчикаНаОсновании");
ЗаполнитьЗначенияСвойств(СтруктураРезультат, ЭтаФорма);
ОповеститьОВыборе(СтруктураРезультат);
КонецПроцедуры
Тогда в основной форме нужно реализовать процедуру ОбработкаВыбора.
Пример можно посмотреть в конфигурации “Бухгалтерия предприятия 3.0”, документ РеализацияТоваровУслуг, форма ФормаДокументаУслуги, процедура ДекорацияРеквизитыОрганизацииКонтрагентаНажатие().
И всё-таки, это жуткий изврат. Из простого линейного кода – сделать несколько процедур с описанием оповещения о закрытии.
Как быть, например, с модальными окнами, открываемыми через метод “Выполнить()” системы?
Добрый день!
Да, происходит усложнение программного кода.
Для работы через метод Выполнить() всё аналогично – необходимо наличие в текущем контексте второй процедуры, выполняющейся при закрытии.
Подскажите, пожалуйста, какая задача требует открытия модальных окон через метод Выполнить()?
Спасибо, интересная статья.
Перечитал 3 раза, вроде разобрался.
Но разработчики 1С преподносят сюрпризы:
********************************************************************
Демонстрационная конфигурация “Управляемое приложение 8.3 1.0.18.4”
// Ошибка
{Справочник.ХранимыеФайлы.Форма.ФормаЭлемента.Форма(26)}: Ошибка при вызове метода контекста (НачатьПомещениеФайла)
НачатьПомещениеФайла(Оповещение, , “”, Истина);
по причине:
Использование синхронных методов на клиенте запрещено!
******************************************************************
Где тут синхронный вызов???
&НаКлиенте
Процедура ВыбратьФайлСДискаИЗаписать()
НовыйОбъект = Объект.Ссылка.Пустая();
Оповещение = Новый ОписаниеОповещения(“ВыбратьФайлСДискаИЗаписатьЗавершение”, ЭтотОбъект, НовыйОбъект);
НачатьПомещениеФайла(Оповещение, , “”, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ВыбратьФайлСДискаИЗаписатьЗавершение(Результат, АдресВременногоХранилища, ВыбранноеИмя, НовыйОбъект) Экспорт
Если Результат Тогда
Объект.ИмяФайла = ВыбранноеИмя;
Если Не ЗначениеЗаполнено(Объект.Наименование) Тогда
// Ошибка в следующей строке
ОписаниеФайла = Новый Файл(ВыбранноеИмя);
// КонецОшибки
Объект.Наименование = ОписаниеФайла.Имя;
КонецЕсли;
ПоместитьФайлОбъекта(АдресВременногоХранилища);
Если НовыйОбъект Тогда
ОтобразитьИзменениеДанных(Объект.Ссылка, ВидИзмененияДанных.Добавление);
Иначе
ОтобразитьИзменениеДанных(Объект.Ссылка, ВидИзмененияДанных.Изменение);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
******************************************************************
Добрый день!
Это новое свойство конфигурации Режим использования синхронных вызовов расширений и внешних компонент. При установке его в значение Использовать платформа не будет выдавать такую ошибку.
Что касается метода глобального контекста НачатьПомещениеФайла(), то в синтакс-помощнике указано, что он в тонком и толстом клиентах, в отличие от веб-клиента, блокирует исполнение кода языка. Посмотрите новый метод НачатьПомещениеФайлов().
Как раз искала решение для своего мобильного приложения : ввод параметров в отдельном окне и переносе их в родительское. Очень пригодилась статья! Спасибо!
Пожалуйста! Отлично, что материал оказался полезным на практике.
После смены платформы 8.3.4.408 на 8.3.4.482 (вплоть до 8.3.5.1088) данный метод отправляет систему в дамп в том случае, если ожидать завершения работы с базой по таймауту. Может кто-нибудь проверить?
&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
ОписаниеОповещения = Новый ОписаниеОповещения(“ОбработатьОтвет”, ЭтотОбъект);
ПоказатьВопрос(ОписаниеОповещения, “Завершить работу системы?”, РежимДиалогаВопрос.ДаНет, 60);
Отказ = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ОбработатьОтвет(РезультатВопроса, ДополнительныеПараметры) Экспорт
Если РезультатВопроса КодВозвратаДиалога.Нет Тогда
ЗавершитьРаботуСистемы(Ложь);
КонецЕсли;
КонецПроцедуры
Методом проб и ошибок я нашел обходной путь. Нужно изменить процедуру ОбработатьОтвет() следующим образом:
&НаКлиенте
Процедура ОбработатьОтвет(РезультатВопроса, ДополнительныеПараметры) Экспорт
Если РезультатВопроса КодВозвратаДиалога.Нет Тогда
//ЗавершитьРаботуСистемы(Ложь);
ПодключитьОбработчикОжидания(“ЗавершитьРаботуСистемыНаКлиенте”, 1, Истина);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗавершитьРаботуСистемыНаКлиенте()
ЗавершитьРаботуСистемы(Ложь);
КонецПроцедуры
Что-то все-таки разработчики 1С нахимичили в платформе…
Проверил на платформе 8.3.5.1068 – описанная Вами ошибка воспроизводится.
На сайте публикации ошибок есть такая запись:
Код ошибки: 20017151
Статус: Исправлена в выпущенной версии Зарегистрирована: 19.07.2013
Исправлена: “Технологическая платформа”, версия 8.3.4.365
Описание:
Функция ПоказатьВопрос не закрывается по таймеру.
Думаю, что это о другой ошибке речь.
Согласен с Вами, но возможно у этих ошибок внутри платформы есть что-то общее:)
Добрый день! отличная статья, но никто не встречал того, что после использования в любом методе на форме объекта(справочника, документа и т. д.) ОписаниеОповещения, при повторном редактированииобъект оказывается заблокирован?
Такое поведение не воспроизвелось по Вашему описанию. Взял пример №1 с открытием другой формы – ОписаниеОповещения используется, однако при многократном открытии формы, редактировании реквизитов не получилось заблокировать объект.
Опишите подробнее механизм возникновения этого эффекта на конкретном примере.
Спасибо, примеры понятны и доходчивы.
Добрый день!
Спасибо за статью!
Очень интересно!
За статью спасибо
А я сейчас работаю с УПП 1.2 и ЗУП 2.5 .. ни УФ, ни Веб, ни 8.3! Деградирую! :(
Актуальная статья. Когда сам начинал переводить на безмодальный режим пришлось все постигать методом проб и ошибок, а здесь все написано что для работы надо.
Если возможно, примеры кода раскрашивать как в конфигураторе 1С, так легче читается.
Да, раскраску кода сделаем в ближайшее время.
Статья понравилась. Есть практические примеры, которые можно использовать в работе. Спасибо.
Интересная статья. Есть над чем подумать.
Годная статья про технику. Приму к сведению.
Спасибо!
Доступно, понятно.
Много примеров – это отлично.
спасибо за примеры. надеюсь пригодятся.