Наверное, вы согласитесь, что длительные операции, которые запускаются интерактивно и блокируют интерфейс пользователя, это крайне неудобно. Особенно в Web-клиенте, где это может вызвать тайм-аут и появление непонятных окон у пользователя.

Для решения вопроса выполнения длительных операций используются фоновые задания и обработчики ожидания на клиенте, которые раз в определенный интервал времени проверяют, выполнено ли фоновое задание.

В Интернете есть множество примеров, как это сделать неудобно. Благодаря БСП 2.3 мы можем запустить выполнение длительной операции с выводом формы длительной операции («крутящееся колёсико») и сообщение прогресса выполнения буквально в несколько строк кода.

Рассмотрим тестовую задачу.

Имеется обработка, с формы которой по нажатию кнопки требуется запускать длительные вычисления, результат которых выводится в ту же форму обработки. Во время выполнения фонового задания нужно выводить неблокирующую форму длительной операции.

Для решения задачи:

  1. Создадим серверный общий модуль, который будет содержать процедуру фонового задания:

В коде общего модуля разместим процедуру фонового задания и процедуру, выполняющую длительную операцию — паузу:

При разработке прикладного решения большую роль играет функциональность. Но для достижения коммерческого успеха не менее важна дружелюбность интерфейса или эргономичность. И в этой статье мы осветим важный момент эргономики – информирование пользователя о ходе длительного процесса.

Данный материал будет полезен и начинающим программистам 1С, и тем, кто хочет сделать свои разработки удобнее для пользователей. Кроме того, рассмотрим некоторые новшества платформы 8.3.10.

Начнём с того, что условимся о некоторых ограничениях:

  • В статье рассматриваются концепции. Поэтому за рамками останутся решения, основанные на библиотеках / внешних компонентах
  • Примеры, приведённые в статье, не претендуют на «Единственно-верное-решение».

В статье последовательно будет рассмотрено: как было в обычных формах, что случилось с приходом управляемых форм и какие сюрпризы нам преподнесла платформа 8.3.10.

Итак, давайте приступим.

Думаю, никого не требуется убеждать, что информирование о ходе выполнения длительного процесса в программе очень важно. Каждый пользователь может привести примеры, когда смотришь в экран и думаешь – «перезагружать не надо ждать» (пишите в комментариях – где вы предпочитаете ставить запятую).

И платформа «1С:Предприятие 8» в этом не исключение – в ней для отображения хода процесса имеется специальный элемент обычных форм «Индикатор» (или вид поля управляемой формы «Поле индикатора»). Давайте рассмотрим нюансы его использования.

Обычные формы

Придумать что-то проще, чем вывод индикатора выполнения процесса в обычных формах – сложная задача. А всё это благодаря тому, что в режиме толстого клиента в «1С:Предприятие 8» по умолчанию отсутствуют границы между клиентской частью и серверной частью. То есть выполнение программного кода и интерфейсных методов происходит, как правило, в одном контексте. Поэтому у разработчика не возникает необходимости задумываться о доступности необходимых свойств, процедур и функций.

Схематично работу «1С:Предприятие» в толстом клиенте можно представить следующим образом:

В обычном режиме клиентский сеанс открывает постоянное соединение с базой данных, а выполнение программного кода на встроенном языке преимущественно происходит на стороне клиента.

В связи с этим в любой строчке кода, описывающего длительный процесс, можно оценить объем обработанных данных, получить процент его выполнения и поместить полученное значение в реквизит формы, связанный с выведенным на форму элементом «Индикатор». В этот момент пользователь увидит графическое изменение отображения полосы индикатора в интерфейсе – опять же, благодаря тому, что всё действие происходит на клиенте.

Самый простой «длительный процесс» с выводом процента выполнения в обычном режиме может выглядеть следующим образом:

Как говорится – «проще не придумаешь». Никакого «лишнего» кода, всё максимально прозрачно, понятно и самое главное – работает!

На этом моменте кто-то из читателей ностальгично вздохнёт, так как мы переходим к следующей части статьи – к управляемым формам.

Управляемые формы

С приходом платформы 8.2 и управляемых форм ситуация с индикатором в корне изменилась. Но дело совсем не в версии платформы и не в новых формах, а в появлении новых видов клиентов для «1С:Предприятие» – тонкого и web-клиента. Схематично работу в управляемом режиме можно представить в следующем виде:

Если провести сравнение с обычным режимом, то сразу бросаются следующие отличия:

  • Постоянного соединения клиентской части с базой данных нет – их взаимодействие происходит только через сервер 1С (в файловом режиме вместо сервера 1С выступает некоторая эмуляция, но это уже другая история)
  • Отсутствует постоянное соединение клиентской части с серверной
  • Встроенный язык разделён на клиентский и серверный.

Есть ещё один важный, но не отображённый на схеме нюанс – серверный вызов, посредством которого происходит взаимодействие клиентской части и серверной. Он может быть инициирован только клиентом. А это значит, что со стороны сервера отправить данные на сторону клиента можно только в том случае, если с соответствующего клиентского сеанса пришёл запрос.

Как всё это повлияло на использование индикатора для отображения информации о ходе выполнения длительного процесса? Давайте подробно в этом разберёмся.

Обычно длительный процесс заключается в сложной обработке данных. Будь то групповое проведение документов, проведение сложных расчётов или выборка данных и заполнение ими отчётной формы.

Получается, что в том или ином виде всегда требуется доступ к базе данных и/или выполнение методов, доступных только на стороне сервера. Для этого на него необходимо передать управление.

Во время выполнения серверного вызова клиентская часть 1С становится неактивной и блокируется для дальнейшей работы до тех пор, пока вызов не завершится и управление не вернётся на сторону клиента. Поэтому, даже если во время выполнения процедуры на сервере производить изменение значения реквизита, отвечающего за данные индикатора, то на клиент вернётся только финальная величина.

Получается, что если взять код из предыдущего примера и просто разбить его на клиентскую и серверную часть, то получим долгое подвисание приложения, после чего индикатор резко установится в значение «100%».

При таком использовании индикатора от него пользы никакой нет. Поэтому разработчики идут на различные хитрости – выполняют длительные процессы «порционно» с отображением на полосе индикатора значений относительно «порций»; используют динамическое уменьшение скорости движения индикатора в зависимости от времени выполнения процесса; или придумывают другие варианты. Но ни один из них не имеет ничего общего с отображением выполнения конкретного процесса в режиме реального времени.

Именно поэтому при обновлении типовых конфигураций рядом с индикатором мы наблюдаем фразу примерно следующего содержания: «эта операция может занять длительное время – от нескольких минут до нескольких часов». И отчасти поэтому при формировании отчётов крутятся «безликие» круги-индикаторы, которые в виде простой анимации указывают на то, что программа вовсе не зависла.

Не знаю, как на счет настроения, но понимания о планируемом времени окончания выполнения процесса этот котёнок точно не прибавляет.

Один из вариантов вывода индикатора для отображения хода выполнения длительного процесса заключается в следующем:

  1. Длительная операция запускается в виде фонового задания, в ходе выполнения которого промежуточные результаты помещаются во временное хранилище.
  2. На стороне клиента запускается обработчик ожидания, который с определённой периодичностью опрашивает временное хранилище и выводит данные из него в полосу индикатора.

Программный код будет состоять из двух частей: из кода интерфейсной части (в нашем случае – обработки) и кода общего модуля. Модуль формы обработки будет выглядеть примерно так:

А общий модуль будет содержать процедуру для запуска в фоновом режиме:

Для тех, кто захочет проверить работоспособность данного примера, дополнительно приведём скриншот формы обработки:

Несмотря на то, что индикатор будет «живым», сказать, что эффект достигнут и пример рабочий, на сто процентов нельзя. Потому что между реальным состоянием выполнения процесса и интерфейсом пользователя есть аж целых две «прослойки» – временное хранилище и обработчик ожидания. При таком подходе мало того, что отображение идёт не в режиме реального времени, так ещё и возрастает возможность возникновения различного вида сбоев из-за использования промежуточных звеньев.

Подводя итог получаем, что для «правильной» работы индикатора в управляемых формах (то есть, как в обычном режиме – с привязкой к выполнению процесса в реальном времени) не хватает возможности инициировать сервером отправку данных на сторону клиентской части. И тут наступает самое время поговорить про сюрприз, который фирма «1С» преподнесла разработчикам в новой платформе «8.3.10».

Платформа «8.3.10»

На самом деле в платформе «1С:Предприятие 8.3.10» касательно индикатора ровным счётом ничего не изменилось. Там есть много других интересных «фишек». Например, система взаимодействий, инкрементальная выгрузка конфигурации в XML, новые режимы основного окна. Но всё это не относится к теме данной статьи. Поэтому, можно было бы уже закончить писать… Если бы не наши «пытливые умы».

Давайте чуть-чуть пристальнее взглянем на систему взаимодействий. Для этого возьмём описание с одного из сайтов фирмы «1С»:

Теперь посмотрим на определение протокола WebSocket на сайте Википедии:

Обратите внимание на ключевые слова: двухсторонняя связь между клиентом и сервером в режиме реального времени! То, чего так не хватало для нормального функционирования индикатора в управляемых формах! Давайте для лучшего понимания взглянем на схему работы «1С:Предприятие» и системы взаимодействий:

Остаётся вопрос: можно ли использовать систему взаимодействий для вывода хода выполнения процесса в индикатора? Ответ – можно конечно, но… Давайте сначала рассмотрим возможность информирования пользователя о ходе выполнения длительного процесса при помощи только системы взаимодействия.

Для этого нам потребуется длительный процесс, выполняемый в фоне:

Который мы дополним программным кодом работы с системой взаимодействия, достаточным для информирования пользователя о ходе выполнения процедуры в виде оповещений. Для этого нам будет необходимо немного изменить процедуру обработки фонового задания в общем модуле:

Если изучить программный код, то будет понятно – в момент старта фонового задания создаётся «Обсуждение», в котором будет выводится информация о ходе процесса. А при выполнении длительного процесса в «Обсуждение» выводятся сообщения с указанием процента выполнения. Каков будет результат и где его искать – видно на следующем рисунке:

Таким образом, у пользователя будет возможность увидеть процент выполнения фонового задания в режиме реального времени. Если он знает, куда смотреть.

С точки зрения эргономики данный вариант проигрывает выводу информации в виде индикатора на самой форме обработки. Поэтому при желании к описанному механизму можно «прикрутить» и индикатор. Но! Пока это возможно сделать только при помощи подключенного обработчика ожидания, который инициирует серверный вызов для анализа полученных сообщений и вывода данных в индикатор.

Конечно, это очередное использование промежуточного звена, неоправданные серверные вызовы и как следствие – запоздание отображения от режима реального времени.

Связано это с тем, что некоторые методы работы с системой взаимодействия не доступны на клиенте. Но это будет меняться, и разработчики платформы «1С:Предприятие» уже анонсировали, что в версии 8.3.11 на основе системы взаимодействий появится возможность инициирования сервером передачи информации на сторону клиента!

Вместо заключения

В настоящее время эргономика инструмента играет большую роль в дальнейшей его судьбе – будет оно активно использоваться/применяться или его отложат/выкинут.

И если раньше достаточно было показать пользователю куда/какие вводить данные в программе и где/какой он от этого будет видеть результат, то сейчас важно – удобно ли эти данные вносить и как быстро можно получить обратную связь.

Скорость реакции программы на действия пользователя тоже выходит на первый план. Даже минимальное ожидание отклика начинает вызывать раздражение, а задержка в обратной связи, длящаяся даже всего несколько секунд, может стать поводом к аварийному завершению работы приложения.

Поэтому при разработке конфигураций необходимо обращать внимание на программный код, выполнение которого может занять продолжительное время. И предусматривать механизмы оповещения пользователя о том, что программа выполняет процесс, а не зависла.

Конечно, не всегда представляется возможным в начале длительной операции предвидеть объем обрабатываемых данных или время выполнения операции. В этих случаях использование индикатора не будет давать пользователю достоверной информации о ходе процесса и его использование становится нецелесообразным. Поэтому порой приходится выкручиваться различными способами, чтобы работа в программе вызывала меньше негативных эмоций – использовать анимированные кольца или милых котят.

Но если есть возможность получить привязку выполнения процесса к реальному времени, то это нужно делать и выводить пользователю эту полезную информацию. Согласитесь – ведь приятно иметь возможность прогнозировать “успею ли я сходить налить себе кофе, пока этот отчёт формируется”?

Если вас заинтересовала система взаимодействий, и вы хотели бы попробовать с ней поработать, но не знаете, что это такое и с чего начать – читайте следующую статью Система взаимодействий в платформе 8.3.10.

А пока – пишите в комментариях истории из своего опыта по работе с индикаторами!

Об авторе

Автор статьи – Павел Ванин

Рассмотрим задачу, когда в обработке нужно запустить фоновое задание и при этом показывать форму выполнения фонового задания до его завершения. Рассмотрим на примере конфигурации с добавленной БСП.

Важное замечание! Нужны общие модули подсистемы БСП ДлительныеОперацииКлиент и ДлительныеОперации, общая форма ДлительнаяОперация.

Напоминание! Для отладки фонового задания в конфигураторе нужно отметить признак подключения к фоновым заданиямОтладка – Подключение… – Автоматическое подключение – Фоновые задания (рис. 1):

Рис. 1. Настройка отладки фоновых заданий

Потребуются изменения в следующих объектах:

Добавить кнопку и команду запуска фонового задания

Добавить реквизит ИдентификаторФЗ (тип УникальныйИдентификатор)

Модуль формы обработки

Добавить переменную ФормаДлительнойОперации

Добавить описание команды запуска фонового задания

Добавить процедуры для показа формы выполнения фонового задания до его завершения

Подробнее на примере:

Допустим, в обработке Новый_ЗаполнитьДокументНоменклатураПартнераКПолучению хотим запускать фоновое задание по формированию документов Новый_НоменклатураПартнераКПолучению, при этом хотим видеть, что фоновое задание еще не завершилось (т.е. выполняется).

Часть 1. Доработка формы обработки.

На форму обработки Новый_ЗаполнитьДокументНоменклатураПартнераКПолучению добавляем команду запуска фонового задания Заполнить и выводим кнопку на форму.

На форму добавляем реквизит ИдентификаторФЗ с типом УникальныйИдентификатор.

Часть 2. Доработка модуля формы обработки.

Открываем модуль формы обработки. Определяем следующие процедуры:

2.1 Добавляем переменную формы ФормаДлительнойОперации

2.2 Описываем команду запуска фонового задания Заполнить

Если ЗаполнитьСервер() Тогда

2.3 Описываем оставшиеся процедуры

Предполагаем, что нужное фоновое задание описано в общем модуле Новый_ЗаполнениеДокументов в экспортной процедуре ФормированиеДокНоменклатураПартнераКПолучению, у которой один параметр Период (поэтому в массиве один элемент со значением параметра процедуры Период = ТекущаяДата()).

Присваиваем реквизиту формы ИдентификаторФЗ значение идентификатора фонового задания.

Если ЗапущеноФЗ Тогда

ПараметрыФЗ = Новый Массив;

ЗапущенноеФЗ = ФоновыеЗадания.Выполнить("Новый_ЗаполнениеДокументов.ФормированиеДокНоменклатураПартнераКПолучению", ПараметрыФЗ, , "Формирование документов Номенклатура партнера к получению");

Если ПроверкаВыполнениеЗадания(ИдентификаторФЗ) Тогда

Если ФормаДлительнойОперации <> Неопределено Тогда

Теперь можно открыть конфигурацию в режиме Предприятие и проверить внесенные изменения. Во время выполнения фонового задания будет отображаться форма, как на рис. 2: