Полоса прогресса с процентами и прогнозом оставшегося времени

18 6

По мере наполнения информацией база системы разрастается и со временем уже не достаточно просто знать, благодаря полосе прогресса, что запущенный сценарий не повис и не зациклился. Некоторые скрипты ISBL могут выполняться очень долго - дольше чем ночь. Как же узнать как долго будет выполняться сценарий?

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

Многим разработчикам известен класс объектов системы IProgress, который можно получить функцией CreateProgress(). Он позволяет увидеть полосу прогресса выполнения какого-либо процесса в рамках кода на ISBL. Я приведу пример кода, в котором помимо показа полосы прогресса есть так же информация о проценте завершения процесса, о пройденном времени и плановом времени окончания процесса.

Пример завершения всех заданий, находящихся в работе у пользователя "БУХГАЛТЕРИЯ":

Q = "
  select %s from sbtaskjob job
  left join MBAnalit perf on perf.Analit = job.Executor
  where job.State = 'w'
  and perf.Dop = 'БУХГАЛТЕРИЯ'
"
JobsCount = SQL(Format(Q; "count(*)"))
JobIDs = CSQL(Format(Q; "job.xrecid"))

Progress = CreateProgress(; JobsCount; true)
ProgressShowTime = true
t0 = formatdate('d.m.yy h:n:s.000'; now())
time = '???'
LastPlan = 0
Progress.Show

foreach JobID in JobIDs
  Job = Jobs.GetObjectByID(JobID)
  Job.Perform
  Progress.Next
  Percent = round(Progress.position/Progress.max*100;0)
  Title = 'Завершено: ' & Percent & '%'
  if ProgressShowTime
    t = formatdate('d.m.yy h:n:s.000'; now())
    SecondsLeft = SQL("SELECT DATEDIFF(s,'" & t0 & "','" & t & "')") 
    if (Progress.position>0) and (SecondsLeft>5) and (SecondsLeft-LastPlan>1) 
      // изменение прогноза не чаще, чем 1 раз в секунду и не раньше, чем через 5 секунд после старта
      LastPlan = SecondsLeft
      PlanSeconds = round((Progress.max - Progress.position) * SecondsLeft / Progress.position;0)
      Q="SELECT "&PlanSeconds&"/3600 as integer,"&PlanSeconds&"%3600/60 as integer,"&PlanSeconds&"%60" 
      time = formatdate('h:n:s';SQL(Q;;;':'))
    endif  
    Q="SELECT "&SecondsLeft&"/3600 as integer,"&SecondsLeft&"%3600/60 as integer,"&SecondsLeft&"%60"
    timeleft = formatdate('h:n:s';SQL(Q;;;':'))
    Progress.Text = 'Прошло времени: ' & timeleft
    Title = Title & ', осталось: ' & time 
  endif
  Progress.Title = Title    
endforeach

18
Авторизуйтесь, чтобы оценить материал.
1
Андрей Манаков

Скриншот был бы очень к месту ;)

Сергей Филипченко

Скриншот вставил )

Андрей Ерошенко

Привет, Сергей!

Отличный прогресс-индикатор. Замечательно, что почти все вычисления сделаны в SQL )

 

Алексей Пестов

Странно вылетает с такой ошибкой:

[Window Title]
Ошибка

[Main Instruction]
Значение 243:22:13 параметра 2 должно быть датой.

[Expanded Information]
Сценарий "11111": ошибка в строке 29.

[^] Меньше сведений  [ОК]

Алексей Пестов

Понял, если оставшееся время больше чем 24 часа, то выдаётся ошибка :)

Сергей Филипченко
Понял, если оставшееся время больше чем 24 часа, то выдаётся ошибка :)

Думаю, стоит доработать индикатор, чтобы показывал еще и дни...
Привет, Сергей! Отличный прогресс-индикатор. Замечательно, что почти все вычисления сделаны в SQL )
Привет, Андрей! Спасибо )

Авторизуйтесь, чтобы написать комментарий