
HomePage | Optical Illusions | War Stories | QBasic | Dads Navy Days | Bristol | Bristol, USA | Bristol, Canada | Terre Haute | Miscellany | Web Stuff | About Ray | Site Map | Site Search | Messages | Credits | Links | Web Rings
QBasic | Errors | 40lb Weight | Bits | Chance | Colours | Dates | Delays | File Dialog | Files | Input | Matching | Menus | Mouse | Numbers | SeqNo | SIRDS | Sorts | Text | Timer | DLoads
Visual Basic has a percent flood fill feature which is useful for displaying the percentage complete of a process. I thought it would be nice to do my own in QBasic. It's not so pretty but does the job.

This is a slightly more complicated program, here's the code for it
:
DIM Count AS INTEGER 'Used for loops, general numeric variable DIM Hrs AS INTEGER 'Hold hours DIM Mins AS INTEGER ' Holds minutes DIM PerCent AS INTEGER 'Calculates percentage done DIM Counter AS LONG 'Used for loops, general numeric variable DIM Elapsed AS LONG 'Used to calculate times DIM Num AS LONG 'General numeric variable DIM EndTimer AS LONG 'Holds the end time DIM EstTime AS LONG 'Used to claculate times DIM secs AS LONG 'Holds seconds DIM StrtTimer AS LONG 'Holds the start time DIM PerCntdone AS STRING 'Used to calculate % done and position on screen CLS PRINT "Busy.Bas Ray Thomas, September 1998" PRINT PRINT "This small program can work out and display a percent done bar" PRINT "a la Visual Basic (but not so pretty)." PRINT PRINT PRINT "Press any key to continue ..." DO LOOP UNTIL INKEY$ <> "" Num = 307 'A made up number, could be the number of records to process CLS PRINT "Working, please wait ..." PRINT PRINT PRINT CHR$(201); STRING$(50, CHR$(205)); CHR$(187) PRINT CHR$(186); SPACE$(50); CHR$(186) PRINT CHR$(200); STRING$(50, CHR$(205)); CHR$(188) StrtTime = TIMER PRINT PRINT "Routine started on :", " "; MID$(DATE$, 4, 2); "/"; LEFT$(DATE$, 2); "/"; PRINT RIGHT$(DATE$,2); " at "; TIME$ FOR Count = 1 TO Num Hrs = 0 Mins = 0 secs = 0 FOR Counter = 1 TO 100000 'This loop merely to act as a delay NEXT Counter 'but could be processing records etc EndTime = TIMER Elapsed = EndTime - StrtTime 'gives the elapsed time in seconds secs = Elapsed IF Elapsed >= 60 THEN Mins = FIX(Elapsed / 60) secs = Elapsed - (60 * Mins) END IF IF Mins >= 60 THEN Hrs = FIX(Mins / 60) Mins = Mins - (60 * Hrs) END IF LOCATE 9, 1 PRINT "Elapsed time :", Hrs; "Hours"; Mins;"Minutes"; FIX(secs); "Seconds " Hrs = 0 Mins = 0 secs = 0 EstTimes = (Elapsed / Count) * (Num - Count) secs = EstTimes IF EstTimes >= 60 THEN Mins = FIX(EstTimes / 60) secs = EstTimes - (60 * Mins) END IF IF Mins >= 60 THEN Hrs = FIX(Mins / 60) Mins = Mins - (60 * Hrs) END IF LOCATE 10, 1 PRINT "Estimated time to go :", Hrs; "Hours";Mins; "Minutes"; FIX(secs); "Seconds " PerCent = (Count / Num) * 100 PerCntdone$ = STR$(PerCent) + "% complete " LOCATE 5, 2 PRINT STRING$(Count / (Num / 50), CHR$(177)); LOCATE 4, 20 PRINT PerCntdone$; NEXT Count LOCATE 1, 1 PRINT "Finished " LOCATE 11, 1 PRINT "Routine finished on :", " "; MID$(DATE$,4, 2); "/"; LEFT$(DATE$, 2); "/"; PRINT RIGHT$(DATE$,2); " at "; TIME$ PRINT "Number of iterations :", Num END
During May 2000, I had a very interesting email saying that if used near midnight then the above code will not work correctly. On investigation, I realised why, the time elapsed is worked out by using the TIMER function which returns the number of seconds elapsed since midnight.
Suppose the program was started at 11pm and ran till 2am. The line StrtTime = TIMER would make StrtTime equal to 82800 (the number of seconds in 23 hours). The line EndTime = TIMER would make EndTime equal to 7200 (the number of seconds in 2 hours). When working out the number of seconds elapsed, Elapsed = EndTime - StrtTime, would make Elapsed equal to -75600, which isn't quite what we want.
A solution would be to replace Elapsed = EndTime - StrtTime with :-
IF EndTime < StrtTime THEN Elapsed
= 86400 - StrtTime + EndTime
ELSE Elapsed = EndTime - StrtTime
86400 is the number of seconds in 24 hours.
Of course this only works if the program is running for less than one day, for longer processes additional problems are introduced. The programmer must check to see how many days have passed since the process was started. The DATE$ command can be used and then a routine written to do the maths of taking one date away from another, but because you have to take into account the differing number of days in a month a simpler solution would be to check the TIMER periodically, if the reading is less than the reading before then another variable, which would count the days needs to be incremented.
Just before the process to be timed starts insert :-
LastTime = TIMER
During the process to be timed (remember that this must be done before 24 hours have elapsed) insert:-
ThisTime = TIMER
IF ThisTime < LastTime THEN
DayCount = DayCount + 1
LastTime = ThisTime
END IF
The total time elapsed can now be calculated as :-
EndTime = TIMER
Elapsed = (DayCount * 86400) + EndTime - StrtTime
The program snippets above may need editing, if the EndTime is very close to midnight then the DayCount counter may not be incremented properly. An extra line
IF EndTime < StrtTime THEN DayCount = DayCount + 1
may be needed to be added between the last two program lines.
During the email correspondence I wrote a program to investigate what happens to the system clock, TIMER and ON TIMER functions. The program changes the system time so it is best not to stop it from finishing itself, it will reset the system clock to the correct time when it finishes. As the clock passes midnight the system date will also change. The date is also reset near the end of the program.
Using the ON TIMER(x) GOSUB function and a simple counter loop. As in the program above there is a problem with the TIMER function as it changes from 86400 to 0 at midnight. The ON TIMER function however still works as it should. As in the above program the time elapsed calculation is corrected by the addition of 86400 to the calculation.
In November 2003, I received an email from Jonathan Simpson saying that in QBasic 7.1 the following code can be used
DIM a AS LONG, b AS LONG, days AS INTEGER
a = INT(NOW)
DO UNTIL something
b = INT(NOW)
IF b > a THEN days = days + 1: a = INT(NOW)
LOCATE 1, 1: PRINT days, NOW
LOOPUnfortunately QBasic v1.1 hasn't this facility.
'Midnight Ray Thomas May 2000
'A program to investigate what happens to the system clock and
'TIMER functions at midnight
CLS
StartTime$ = TIME$ 'Get the time the program was started
StartDate$ = DATE$ 'Get the present system date
TIME$ = "23:59:55" 'Set the system time to just before midnight
ProgStart = TIMER 'Get the number of seconds past midnight
Start = TIMER
ON TIMER(1) GOSUB TimeUp 'Set up the timer interupt
TIMER ON 'Start the timer interupt
FOR Count = 1 TO 1000000 'A do nothing loop
NEXT Count
TIMER OFF 'Stop the timer interupt
PRINT "Count ended"; Count
PRINT
PRINT "Press any key to reset the system clock ..."
DO
LOOP UNTIL INKEY$ <> ""
GOSUB ResetTime
END
TimeUp:
'*** Do whatever you want to do after the timer interupts
Finish = TIMER
PRINT
PRINT "The time is now: "; TIME$
'*** Stop the program to read what happens to the counters at midnight
IF TIME$ = "00:00:02" THEN
TIMER OFF
PRINT "press any key to continue ..."
DO
LOOP UNTIL INKEY$ <> ""
TIMER ON
END IF
PRINT "The Count is now at:"; Count
PRINT Finish - Start; "seconds elapsed"
'*** This is the part that checks for what happens at midnight
'*** it is here that the start time is greater than the finish time
IF Start > Finish THEN
PRINT "Amended time elapsed"; 86400 - Start + Finish
PRINT CINT(86400 - Start + Finish); "rounded amended second(s) elapsed"
ELSE PRINT CINT(Finish - Start); "rounded second(s) elapsed"
END IF
PRINT "The end time is"; Finish
PRINT "The start time is"; Start
Start = TIMER
RETURN
ResetTime:
'*** Work out the total time elapsed
'*** and reset the system date and time
PRINT
PRINT "The date when the program was started was "; StartDate$
PRINT
PRINT "The time when the program was started was "; StartTime$
PRINT
PRINT "The date has changed to "; DATE$
PRINT
PRINT "Resetting the date to "; StartDate$
PRINT
DATE$ = StartDate$
Finish = TIMER
PRINT "The program was running for"; CINT(86400 - ProgStart + Finish); "seconds"
Hours = VAL(LEFT$(StartTime$, 2))
Mins = VAL(MID$(StartTime$, 4, 2))
Secs = VAL(RIGHT$(StartTime$, 2))
Finish = TIMER
Secs = Secs + CINT(86400 - ProgStart + Finish)
IF Secs > 60 THEN
Mins = Mins + INT(Secs / 60)
Secs = Secs MOD 60
END IF
IF Mins > 60 THEN
Hours = Hours + INT(Mins / 60)
Mins = Mins MOD 60
END IF
NewTime$ = LTRIM$(STR$(Hours)) + ":" + LTRIM$(STR$(Mins)) + ":" + LTRIM$(STR$(Secs))
TIME$ = NewTime$
PRINT
PRINT "The time has been restored to "; TIME$
RETURN
QBasic | Errors | 40lb Weight | Bits | Chance | Colours | Dates | Delays | File Dialog | Files | Input | Matching | Menus | Mouse | Numbers | SeqNo | SIRDS | Sorts | Text | Timer | DLoads
HomePage | Optical Illusions | War Stories | QBasic | Dads Navy Days | Bristol | Bristol, USA | Bristol, Canada | Terre Haute | Miscellany | Web Stuff | About Ray | Site Map | Site Search | Messages | Credits | Links | Web Rings
This page last updated 23rd November 2003