Search code examples
progress-barbasicquickbasic

Advice on how to fix a Progress Bar code in QuickBASIC


I have a problem that I am hoping someone who is smarter then myself can help me with.

I have this bit of code that I am trying to get to work.

SUB ShowProgressBar (FileCount%, NCount%, BarWidth%, BarRow%, BarColum%)

percent = int((Ncount% / FileCount%) * 100)

Locate BarRow%, BarColumn%
Print String$(BarWidth%, Chr$(177))

Locate BarRow%, BarColumn%
Print String$((BarWidth% / 100 * percent), Chr$(178))

Locate BarRow%, (BarColumn% + 12)
Print percent + "%"

What I am trying to do is to show in screen 0 a text progress bar.

So first I would print to the screen ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ (for the background) and then the idea is to fill the progress bar with ▓ until the processing is completed.

What I can not get to work is the actual math of the progress bar.

What I am using this on is a function that reads in a CSV file and creates an ISAM database from it (so it can have anything from 0 to 10,000,000 records or more).

If someone could help me with this it would be most appreciated as I have spent the whole weekend on this and still can not get it to work correctly. I get overflow errors or the progress bar goes over 8-10 lines on screen.

Thank you for any help you can offer.


Solution

  • You only have 80 columns to work with on screen 0. If BarWidth% > 80, you will see problems.

    Adjust things however you want, but this should mostly do what you want:

    Sub ShowProgressBar (FileCount%, NCount%, BarWidth%, BarRow%, BarColumn%)
    
    ' Completed = NCount / FileCount
    '   Percent = Int(100      * Completed)
    '    Filled = Int(BarWidth * Completed)
    '
    ' Filled/BarWidth represents 100% when FileCount/FileCount files have completed.
    ' Since Completed represents NCount/FileCount, we can mathematically calculate
    '
    '    Filled/BarWidth = NCount/FileCount
    '             Filled = BarWidth * NCount / FileCount
    '
    ' Then you just apply Fix(), Int(), CInt(), CLng(), etc. to get rid of fractions
    ' (or use a\b to perform integer division instead of regular division with a/b).
    '
    percent% = (NCount% * 100) \ FileCount%
    filled% = (NCount% * BarWidth%) \ FileCount%
    
    Locate BarRow%, BarColumn%
    Print String$(filled%, Chr$(178));
    Print String$(BarWidth% - filled%, Chr$(177));
    
    ' Assuming `BarWidth%=20`:
    '
    '     ▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒   9%
    '     ▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒  50%
    '     ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 100%
    '
    ' (Of course, this would be printed on BarRow% only, not multiple lines.
    ' This was just to illustrate what the line below does.)
    '
    Print Using " ###%"; percent%
    
    End Sub
    

    Also, a general tip: try to multiply things before dividing to avoid rounding errors. This is not always possible, but it is a good idea to take advantage of the opportunity when you can.

    Since you mentioned overflow errors, you may want to switch from 16-bit integers with the % suffix to 32-bit long integers with the & suffix:

    • FileCount%FileCount&
    • NCount%NCount&