Code: Select all
***********************************************************************************************************
****** Графический прогресс-бар (на основе примера XSample_14() xdemo.exe)
***********************************************************************************************************
STATIC FUNCTION Time_Progress (Time_Progress, Wsego, oProgress, lOk )
    LOCAL nMaxCount := Wsego
    xtime = Time_Progress
    ** Отображение занимает очень много времени, поэтому
    ** Если Wsego > 100 показывать прогресс не для всех х, 
    ** а только для таких, которые нацело делятся на Wsego/100
    IF xtime = 0 .OR. xtime = Wsego .OR. Wsego < 100             // Всегда показывать прогресс в начале и конце процесса
    ELSE                                                         // и для малого числа событий: Wsego < 100
       Wsego100 = ROUND(Wsego/100,0)
       IF xtime <> Wsego100*INT(xtime/Wsego100)
          RETURN lOk
       ENDIF
    ENDIF
    *** Индикация времени исполнения
    ***** Процесс может идти больше суток, поэтому для определения
    ***** во всех случаях вычисляется время, прошедшее с начала года
*   T_Mess1 = L("Начало:")+" "+TIME()        // Начало
    ***** Прошло секунд с начала процесса
    PUBLIC T_Mess2 := "ch:mi:se"
    Sec_2   = (DOY(DATE())-1)*86400+SECONDS() - Sec_1
    ch2 = INT(Sec_2/3600)                    // Часы
    mm2 = INT(Sec_2/60)-ch2*60               // Минуты
    cc2 = Sec_2-ch2*3600-mm2*60              // Секунды
    T_Mess2 = L("Прошло:")+" "+ALLTRIM(STRTRAN(T_Mess2,"ch",STR(ch2,19)))
    T_Mess2 = STRTRAN(T_Mess2,"mi",STRTRAN(STR(mm2,2)," ","0"))
    T_Mess2 = STRTRAN(T_Mess2,"se",STRTRAN(STR(cc2,2)," ","0"))
    *@19,2 SAY T_Mess2+L(" всего: ")+ALLTRIM(STR(Sec_2,17))+L(" сек.")
    PUBLIC T_Mess3 := "ch:mi:se"             // Осталось
    Sec_3 = Sec_2*Wsego/xtime                // Прогн.длит.исп. в секундах
    ch3 = INT(Sec_3/3600)                    // Часы
    mm3 = INT(Sec_3/60)-ch3*60               // Минуты
    cc3 = Sec_3-ch3*3600-mm3*60              // Секунды
    T_Mess3 = ALLTRIM(STRTRAN(T_Mess3,"ch",STR(ch3,19)))
    T_Mess3 = STRTRAN(T_Mess3,"mi",STRTRAN(STR(mm3,2)," ","0"))
    T_Mess3 = STRTRAN(T_Mess3,"se",STRTRAN(STR(cc3,2)," ","0"))
    *@20,2 SAY T_Mess3+L(" всего: ")+ALLTRIM(STR(Sec_3,17))+L(" сек.")
    PUBLIC T_Mess4 := "ch:mi:se"             // Окончание
    Sec_4 = Sec_1 + Sec_3 - (DOY(DATE())-1)*86400
    ch4 = INT(Sec_4/3600)                    // Часы
    mm4 = INT(Sec_4/60)-ch4*60               // Минуты
    cc4 = Sec_4-ch4*3600-mm4*60              // Секунды
    T_Mess4 = L("Окончание:")+" "+ALLTRIM(STRTRAN(T_Mess4,"ch",STR(ch4,19)))
    T_Mess4 = STRTRAN(T_Mess4,"mi",STRTRAN(STR(mm4,2)," ","0"))
    T_Mess4 = STRTRAN(T_Mess4,"se",STRTRAN(STR(cc4,2)," ","0"))
    *@21,2 SAY T_Mess4+L(" всего:) "+ALLTRIM(STR(Sec_4,17L())+" сек.с нач.суток")
    PUBLIC T_Mess5 := "Средн.время обработки 1-го объекта: ch:mi:se"
    Sec_5 = Sec_2/xtime
    ch5 = INT(Sec_5/3600)                    // Часы
    mm5 = INT(Sec_5/60)-ch5*60               // Минуты
    cc5 = Sec_5-ch5*3600-mm5*60              // Секунды
    T_Mess5 = ALLTRIM(STRTRAN(T_Mess5,"ch",STR(ch5,19)))
    T_Mess5 = STRTRAN(T_Mess5,"mi",STRTRAN(STR(mm5,2)," ","0"))
    T_Mess5 = STRTRAN(T_Mess5,"se",STRTRAN(STR(cc5,2)," ","0"))
    *@22,2 SAY T_Mess5+L(" всего: ")+ALLTRIM(STR(Sec_5,17))+L(" сек.")
    PUBLIC T_Mess6 := "ch:mi:se"             // Осталось
    Sec_6 = Sec_3 - Sec_2
    ch6 = INT(Sec_6/3600)                    // Часы
    mm6 = INT(Sec_6/60)-ch6*60               // Минуты
    cc6 = Sec_6-ch6*3600-mm6*60              // Секунды
    T_Mess6 = L("Осталось:")+" "+ALLTRIM(STRTRAN(T_Mess6,"ch",STR(ch6,19)))
    T_Mess6 = STRTRAN(T_Mess6,"mi",STRTRAN(STR(mm6,2)," ","0"))
    T_Mess6 = STRTRAN(T_Mess6,"se",STRTRAN(STR(cc6,2)," ","0"))
    *@23,2 SAY T_Mess6+L(" всего: ")+ALLTRIM(STR(Sec_6,17))+L(" сек.")
    Mess98 = T_Mess1+SPACE(142-LEN(T_Mess1)-LEN(T_Mess4))+T_Mess4  // Начало, окончание (прогноз) 145
    oSay98:SetCaption(Mess98);oSay98:SetCaption(oSay98:caption)
    Mess99 = T_Mess2+SPACE(144-LEN(T_Mess2)-LEN(T_Mess6))+T_Mess6  // Прошло, осталось (прогноз)  146
    oSay99:SetCaption(Mess99);oSay99:SetCaption(oSay99:caption)
    DC_GetProgress( oProgress, Time_Progress, Wsego )              // Отображение графического Progress-bar
*   Sec_1   // Начало
*   Sec_4   // Окончание
*   Sec_2   // Прошло секунд с начала процесса
*   Sec_6   // Осталось секунд до окончания
*   mWsego=1000;mTimeProgress=ROUND(Sec_2/(Sec_2+Sec_6)*mWsego,0)
*   DC_GetProgress( oProgress, mTimeProgress, mWsego )             // Отображение графического Progress-bar
*   DC_GetProgress( oProgress, ROUND(Sec_2,0), ROUND(Sec_2+Sec_6,0) )                // Отображение графического Progress-bar
*   MsgBox(STR(ROUND(Sec_2,0))+STR(ROUND(Sec_2+Sec_6,0)))
*   MsgBox(STR(mTimeProgress))
*   MILLISEC(1000)
    DC_AppEvent( @lOk, 0, .01 )
RETURN lOk
Do the forecast execution time all of the time specified. But I don't see anything wrong with that. And then always exactly the same as the fact.
Now I realized that the progress bar I do not always updated for some other reason than I thought. The fact is that the time is always updated correctly, and the progress bar is not always drawn.
The Time_Progress() function is used inside the loop just like DC_GetProgress(). Only initialize it should be just lines: 
When the time is used, there is no question about the two events, because the initialization event of the function is always earlier than its use for display