В погоне за большой кнопкой

«Самый лучший гуй — одна большая кнопка
в центре экрана с надписью «Сделай мне хорошо!»
(с) Опытный дизайнер

«Самый лучший гуй — одна большая надпись
в центре экрана «Тебе уже хорошо!»
(с) Опытный программист

Цитата #437964
Неудобства: При работе с программой
приходится нажимать на различные кнопки
(с) bash.org.ru

 

В идеале каждая система должна стремиться к минимизации своего интерфейса.

В качестве плохого примера в системе SAP ERP можно вспомнить транзакцию проводки амортизации AFAB:

Стандартный экран проводки амортизации

Первый экран выглядит очень типично для SAP ERP, поэтому и проблемы у этого экрана старые идеологические:

1. Первый экран (экран выбора) не даёт никакой информации о текущем состоянии

2. Все проверки происходят после заполнения всех параметров и запуска процесса

3. Объем задачи большой, заранее не просчитывается, поэтому установлено простое ограничение на тестовый прогон – 1000 записей

4. Формирование фонового задания и отслеживание его статуса – не самая простая пользовательская операция: пять кликов на запуск, пять кликов на просмотр, причём через непростые малознакомые экраны.

5. Нет никакой отчётливой сигнализации об ошибках расчёта

 

Я просто удивляюсь, почему за последние десять лет никто так и не решился переписать междумордие этой важной задачи.

BTW: Вполне вероятно, что в “Пульте управления закрытием” это и сделано, вот только это тема совсем другого разговора.

Приступим?

 

Предпосылки

Сначала обратим внимание на предпосылки, которые должны оказать влияние на интерфейс.

* * *

В этой транзакции пользователь обычно выполняет две рутинных операции:

  • Один раз в месяц пользователь запускает расчет за последний месяц в режиме “по плану”.
  • Иногда пользователь запускает расчет за предыдущий месяц  в режиме “повторение”

* * *

Пользователь всегда прикреплён к одной определённой балансовой единице.

* * *

Амортизация выполняется по периодам строго последовательно и только вперёд. В системе контролируются статусы расчета по периодам.

* * *

Самый первый прогон всегда запускается вручную под пристальным наблюдением.

* * *

При прогоне амортизации не должны возникать ошибки. Если вдруг ошибки всё-таки возникают, то пользователь не может их решить самостоятельно.

* * *

Пользователю не нужно запускать тестовый прогон (режим моделирования без реальных проводок), всё сразу и взаправду.

* * *

Прогон амортизации выполняется не сразу, а занимает продолжительное время. Условный ориентир – пять минут.

* * *

В особо сложных случаях старая функциональность никуда не девается.

 

Интерфейс

При первом подходе с учетом требований выше нарисовался такой интерфейс:

Новый экран проводки амортизации

 

Что показываем:

  • Балансовую единицу не запрашиваем, просто показываем без вариантов.
  • Текущий месяц определяется автоматически, без вариантов.
  • Показываем дату последнего расчета.

 

Целых две кнопки:

  • В предыдущий раз было не очень хорошо, давай ещё раз!
  • Всё нормально, идём вперёд!

 

Можно ли сделать всего лишь одну кнопку? При большем количестве допущений – да. Например:

  • Если последний месяц расчета  = текущий, то можно выполнить только “Повтор”.
  • Если последний месяц расчета < текущий, то можно выполнить только “По плану”(Вперёд). Если при этом можно проверить, что (а) последний месяц расчета всё ещё открыт в бухгалтерском учёте, (б) с момента последнего расчета есть влияющие изменения, тогда можно предложить предварительный запуск в режиме “Повтор”.
  • При закрытии периода можно проверять наличие изменений, при которых желательно сделать прогон в режиме “Повтор”.

Это большие допущения, требующие более сложной реализации и обсуждения. Пока отложим.

 

Итак, если наш пользователь всё-таки нажимает одну их кнопок, то справа появляется журнал:

Новый экран проводки амортизации 2

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

Если пользователь уверен в результате, то он может закрыть окно, не дожидаясь окончания. Фоновое задание продолжит работу в любом случае.

Реализация

А теперь рассмотрим на реализацию типичных задач, спрятанную под этим капотом.

Кроме обыкновенного ABAP-кода нам понадобятся следующие запчасти и велосипеды:

  • Изменение надписей на кнопках в рантайме
  • Формирование фонового задания
  • Автообновление интерфейса
  • Вывод результатов в виде журнала

 

Добавим мегакнопки

Обычно кнопки имеют неизменяемую надпись, но мы можем изменять надпись в рантайме.

Сначала нам понадобится пара переменных, по одной на кнопку:

data: bt_refresh type char40.
data: bt_next type char40.

Затем надо нарисовать кнопки на экране:

Динамическая надпись на кнопке

Остаётся только написать код, который склеит хитрое наименование для кнопки в нужный момент:

concatenate 
  gc_icon_refresh
  ‘Перерасчитать'(G01)
  ls_t247-ltx
  taba-afblgj
  into bt_refresh
  separated by space.

Здесь кроме обыкновенных переменных можно увидеть константу с кодом иконки:

constants: gc_icon_refresh type icon-id value ‘@42@’. "ICON_REFRESH

С иконками интерфейс выглядит красивее.

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

Добавим фоновое задание

Если есть супертяжёлые вычисления, то мы можем выделить их в фоновое задание (JOB). В этом случае работа будет выполняться в отдельном потоке, не связанном с пользовательской сессией.

Один из самых простых способов сформировать задание: воспользоваться функциями JOB_OPEN и JOB_CLOSE. При этом подразумевается, что все вычисления вынесены в отдельную программу, которую можно вызвать используя конструкцию SUBMIT REPORT.

Шаг первый. Придумываем имя и  открываем задание:

Шаг второй. Формулируем содержимое задания:

Шаг третий. Закрываем задание:

После таких манипуляций без дополнительных параметров задание будет запущено немедленно.

Мы можем отследить дальнейшую судьбу этого задания по имени и идентификатору.

Добавим автообновление

Один из способов сделать автообновление экрана – реализация через таймер.

Сначала определяем таймер и его обработчик с событием:

После этого осталось в нужный момент инициировать сам процесс автообновления:

Добавим журнал

Журнал можно реализовать при помощи HTML-элемента.

Сначала надо инициализировать элемент управления:

А затем можно вставить внутрь нашего элемента любые HTML-фрагменты, например так:

И если все эти ингредиенты смешать в ABAP-редакторе, влить наполнителей и вкусовых добавок, то получится работоспособное решение.

Добавить комментарий

Ваш адрес email не будет опубликован.