Jump to content

question with progress bars


Ace08
 Share

Recommended Posts

hi guys just curious about how progressbar works, i know it's been ask a few times before but i just can't seem to figure it out :x

i have a finished script that i want to add this(progress bars), the script reads a specific text file, say 100 lines then overwrite itself, im stumped, how will the script know its reading and writing these 100 lines and end exactly after the script finishes?

here is a sample script i made but when this reads huge files the progress bar finishes first

Opt('MustDeclareVars', 1)

Local $file,$Data,$DataRecord,$NewContent,$FiletoOpen,$a

$file = FileOpenDialog ("Choose The File to be Converted.", @ScriptDir, "TransactionFile(*.txt)" , 2)
If @error Then
    Exit
Else
    ProgressOn("", "Adding Fields")
    $FiletoOpen = FileOpen($file, 0)

    If $file = -1 Then
        MsgBox(0, "Error", "Unable to open file.")
        Exit
    EndIf

    While 1
        $a = $a + 1
        $Data = FileReadLine($file,$a)
        If @error = -1 Then ExitLoop
        $DataRecord = StringSplit($Data,",",1)
        $NewContent = $NewContent & $DataRecord[1] & "," & $DataRecord[2] & "," & _
        $DataRecord[3] & "," & $DataRecord[4] & "," & $DataRecord[5] & "," & _
        $DataRecord[6] & "," & $DataRecord[7] & "," & $DataRecord[8] & "," & _
        $DataRecord[9] & "," & $DataRecord[10] & "," & $DataRecord[11]  & "," & _
        $DataRecord[12] & "," & $DataRecord[13] & "," & $DataRecord[14] & "," & _
        $DataRecord[15] &   "," & $DataRecord[16] & "," & $DataRecord[17] & "," & _
        $DataRecord[18] & "," & $DataRecord[19] & "," & $DataRecord[20] & "," & _
        $DataRecord[21] & "," & $DataRecord[6] & @CRLF
        ProgressSet($a)
    Wend
    FileClose($FiletoOpen)

    $FiletoOpen = FileOpen($file, 10)
    FileWrite($FiletoOpen, $NewContent)
    FileClose($FiletoOpen)
    ProgressOff()
EndIf

Work smarter not harder.My First Posted Script: DataBase

Link to comment
Share on other sites

ProgressSet needs a percentage... You are just giving it a line number, when there are exactly 100 lines it would work fine, but if there are more then the progress will complete before you've read the file.

To get a percentage you need the total amount of lines. That usually means reading the file, then counting the lines. Reading the file twice just so you can get a progress is rather stupid... So I have an alternative for you. Rather than doing it by lines (a dodgy way of doing the progress anyway) do it in bytes. You can get the total with FileGetSize and then read x bytes at a time and add it to the string (in a similar way to what you do already.

This code was written off the top of my head with no testing, so consider it pseudocode :x If it works first time then thats a bonus.

$iTotal = FileGetSize($sFile)
$hFile = FileOpen($sFile)
$iRead = 0
$x = 1024
$sRet = ""

ProgressOn("Reading file", $sFile, "", -1, -1, 18)
While $iRead < $iTotal
    $sRet &= FileRead($hFile, $x)
    $iRead += @extended
    ProgressSet($iRead / $iTotal * 100, "Read " & $iRead & " bytes of " & $iTotal)
WEnd
FileFlush($hFile)
ProgressOff()

The size of $x depends on what you want to do. The bigger the number, that faster the routine will be, but very large chunks and the progress won't be very descriptive. I assume it will be a large file if you need a progress bar for it.

Mat

Link to comment
Share on other sites

Ace08,

The following code has some comments that may help. I have suggested an alternative to reading line by line, if you need help with thatlet me know.

Opt('MustDeclareVars', 1)

Local $file,$Data,$DataRecord,$NewContent,$FiletoOpen,$a

$file = FileOpenDialog ("Choose The File to be Converted.", @ScriptDir, "TransactionFile(*.txt)" , 2)

; $file now contains a list of files that you have selected.  I would suggest staying away from $file as a variable name as
; it is used extensively in the help doc and may lead to confusion.

If @error Then
    Exit
Else
    ProgressOn("", "Adding Fields")
    $FiletoOpen = FileOpen($file, 0)

    ; $filetoOpen is now you file handle

    If $file = -1 Then                              ; <-- This test should be on $FiletoOpen
        MsgBox(0, "Error", "Unable to open file.")  ; <-- It works because $file is not eq -1
        Exit
    EndIf

    While 1
        $a = $a + 1
        $Data = FileReadLine($file,$a)

        ; here's the big problem.  Readline works because the var $file contains a filename.  Your intent is to use the file
        ; handle ($FIletoOpen).  When a filename is used with readline the file is opened and closed with every call.
        ; This should read $Data = FileReadLine($FiletoOpen,$a) if you want to stick with the line by line method.  More
        ; on this later.


        ; Let me suggest an alternate method to line by line reading.
        ; Read the file into an array then loop through the array where each element represents one record (a readline in this
        ; context)
        ; The 0 subscript of the array will give you a record count to be used in loop control and to calc percentage of
        ; completion for you progress bar

        If @error = -1 Then ExitLoop

            $DataRecord = StringSplit($Data,",",1)
            $NewContent = $NewContent & $DataRecord[1] & "," & $DataRecord[2] & "," & _
            $DataRecord[3] & "," & $DataRecord[4] & "," & $DataRecord[5] & "," & _
            $DataRecord[6] & "," & $DataRecord[7] & "," & $DataRecord[8] & "," & _
            $DataRecord[9] & "," & $DataRecord[10] & "," & $DataRecord[11]  & "," & _
            $DataRecord[12] & "," & $DataRecord[13] & "," & $DataRecord[14] & "," & _
            $DataRecord[15] &   "," & $DataRecord[16] & "," & $DataRecord[17] & "," & _
            $DataRecord[18] & "," & $DataRecord[19] & "," & $DataRecord[20] & "," & _
            $DataRecord[21] & "," & $DataRecord[6] & @CRLF
            ProgressSet($a)
    Wend
    FileClose($FiletoOpen)  ; <--- Here you have the CORRECT file handle, however, because you are reading it with file
                            ;      name this is moot

    ; The rest from this point on is correct

    $FiletoOpen = FileOpen($file, 10)
    FileWrite($FiletoOpen, $NewContent)
    FileClose($FiletoOpen)
    ProgressOff()
EndIf

Good Luck,

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

Ace08,

This is an **UNTESTED** example of what I was talking about!

Opt('MustDeclareVars', 1)

Local $file,$Data,$DataRecord,$NewContent,$FiletoOpen,$i

$file = FileOpenDialog ("Choose The File to be Converted.", @ScriptDir, "TransactionFile(*.txt)" , 2)

If @error Then exit

ProgressOn("", "Adding Fields")
$FiletoOpen = FileOpen($file, 0)

If $filetoopen = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

$Data = stringsplit(FileRead($filetoopen),@crlf,1)
FileClose($FiletoOpen)

for $i = 1 to $data[0]  ; <-- $data is an array created by stringsplit above

    $DataRecord = StringSplit($Data[$i],",",1)
    $NewContent = $NewContent & $DataRecord[1] & "," & $DataRecord[2] & "," & _
    $DataRecord[3] & "," & $DataRecord[4] & "," & $DataRecord[5] & "," & _
    $DataRecord[6] & "," & $DataRecord[7] & "," & $DataRecord[8] & "," & _
    $DataRecord[9] & "," & $DataRecord[10] & "," & $DataRecord[11]  & "," & _
    $DataRecord[12] & "," & $DataRecord[13] & "," & $DataRecord[14] & "," & _
    $DataRecord[15] &   "," & $DataRecord[16] & "," & $DataRecord[17] & "," & _
    $DataRecord[18] & "," & $DataRecord[19] & "," & $DataRecord[20] & "," & _
    $DataRecord[21] & "," & $DataRecord[6] & @CRLF
    ProgressSet(int($i/100))

next

$FiletoOpen = FileOpen($file, 10)
FileWrite($FiletoOpen, $NewContent)
FileClose($FiletoOpen)
ProgressOff()

Good Luck,

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

ProgressSet(int($i/100))

That's not a huge improvement on what he was doing, and is flat out wrong. I know you haven't tested it, so I'll give you some credit, but you need to do the basic maths.

ProgressSet(int($i/$data[0]*100))

This is such a common question people here where people think that because they are scripting, they don't need to do any maths. Search the forums for "percentage" and I know there are at least 5 or 6 threads that I've replied to with people asking the same thing.

Percentage = (Value / Total) * 100

Remember that and you'll be a good step towards getting this working.

Link to comment
Share on other sites

Mat,

Thank you for the clarification. I was not concerned with the % calc and should have been more specific about that. There are larger, overriding problems with this code.

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...