Click here to Skip to main content
15,885,870 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I got the following function (see below for project code) that goes through an xml file and extracts data and writes the data to a file. What I want to accomplish is to have a progress bar as the file gets written. I know I start with a file of size 0 and I know I end up with a file of a certain size:
VB
Dim info2 As New FileInfo("C:\Temp\test.txt")
Dim length2 As Long = info2.Length / 1024 'KB
ProgressBar1.Maximum = length2



However, I am having problems implementing the fallowing code into my project, I appreciate your help:
VB
Dim intValue As Integer
        ProgressBar1.Maximum = lenth2

        Do While Not intValue = lenth2
            ProgressBar1.Value = intValue
            intValue = intValue + 1
        Loop


Project code:
VB
strFilename = browsetofile()

If IsNothing(strFilename) Then

    MsgBox("No XML file was selected", vbCritical, "No XML file was selected")

    Exit Sub
End If


Dim xd As XDocument = XDocument.Load(strFilename)

Dim FILE_NAME As String = "C:\Temp\test.txt"

Dim objWriter As New System.IO.StreamWriter(FILE_NAME)


Dim strPipe As String = Chr(124)

Dim strSpace As String = Chr(10)


Dim strFinalString As String = ""
prgreebar()

Dim Records = (From datafields In xd.Descendants("record")
Select datafields)

'Me.Cursor = Cursors.WaitCursor



For Each ser As XElement In Records

    Try

        Dim Num090 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "090")
                  Select datafield.Elements.ElementAt(0))

        Dim DTIC856 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "856")
                    Select datafield).Skip(1).First()

        Dim Edocs856 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "856")
                   Select datafield)


        Dim Title245_A = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "245")
                   Select datafield.Elements.ElementAt(0))

        Dim Title245_B = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "245") And datafield.Elements.Count >= 2
               Select datafield.Elements.ElementAt(1))



        Dim Author100 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "100")
                   Select datafield.Elements.ElementAt(0))


        Dim ADAnum037 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "037")
                   Select datafield.Elements.ElementAt(0))


        Dim CoAuthor500 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "500")
                   Select datafield).Skip(2).First()

        Dim Quater500 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "500")
                    Select datafield).Skip(1).First()

        Dim BOSUNnum001 = (From controlfield In ser.Descendants("controlfield") Where (controlfield.Attribute("tag").Value = "001")
                    Select controlfield)

        Dim Type999 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "999")
                Select datafield.Elements.ElementAt(2)) '.Skip(0).First()

        strFinalString = Num090.Value & "  " & strPipe & " " & DTIC856.Value & "  " & strPipe & "  " & Edocs856.Value & "  " & strPipe & "  " & Title245_A.Value _
          & "  " & Title245_B.Value & "  " & strPipe & "  " & Author100.Value & "  " & strPipe & "  " & ADAnum037.Value & "  " & strPipe & "  " & CoAuthor500.Value & _
            "  " & strPipe & "  " & Quater500.Value & "  " & strPipe & "  " & BOSUNnum001.Value & "  " & strPipe & "  " & Type999.Value



        objWriter.WriteLine(strFinalString)



    Catch ex As Exception

    Finally

    End Try

Next


objWriter.Close()


MsgBox("Done writing to the file")
Posted
Updated 22-Apr-11 10:58am
v3

1 solution

Probably the easiest way, given the code you have already written is to declare an Integer Property (call it something like BytesWritten) In the Setter for this property have:

VB
_BytesWritten += Value '_BytesWritten is the member associated with the Property
ProgressBar1.Value = _BytesWritten

Then replace this line:
VB
objWriter.WriteLine(strFinalString)

with:
VB
objWriter.WriteLine(strFinalString)
BytesWritten += strFinalString.Length


and get rid of your do-loop entirely
 
Share this answer
 
Comments
stopete82 25-Apr-11 12:44pm    
Thanks for the great suggestion; however it works great with a small size xml file (tried 21kb and 331 byes worked); however, if I try a large xml file (102mb) I don’t see the progress bar progress. Is there a way I can refresh the progress bar when using a large xml file? Appreciate your help.
Code:
strFilename = browsetofile()

If IsNothing(strFilename) Then

MsgBox("No XML file was selected", vbCritical, "No XML file was selected")

Exit Sub
End If


Dim xd As XDocument = XDocument.Load(strFilename)

Dim FILE_NAME As String = "C:\Temp\test.txt"

Dim objWriter As New System.IO.StreamWriter(FILE_NAME)


Dim strPipe As String = Chr(124)

Dim strSpace As String = Chr(10)


Dim strFinalString As String = ""

'prgreebar()


Dim value As Integer = 0
Dim BytesWritten As Integer = ProgressBar1.Maximum
BytesWritten += Value
ProgressBar1.Value = BytesWritten



Dim Records = (From datafields In xd.Descendants("record")
Select datafields)

'Me.Cursor = Cursors.WaitCursor



For Each ser As XElement In Records

Try

Dim Num090 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "090")
Select datafield.Elements.ElementAt(0))

Dim DTIC856 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "856")
Select datafield).Skip(1).First()

Dim Edocs856 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "856")
Select datafield)


Dim Title245_A = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "245")
Select datafield.Elements.ElementAt(0))

Dim Title245_B = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "245") And datafield.Elements.Count >= 2
Select datafield.Elements.ElementAt(1))



Dim Author100 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "100")
Select datafield.Elements.ElementAt(0))


Dim ADAnum037 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "037")
Select datafield.Elements.ElementAt(0))


Dim CoAuthor500 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "500")
Select datafield).Skip(2).First()

Dim Quater500 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "500")
Select datafield).Skip(1).First()

Dim BOSUNnum001 = (From controlfield In ser.Descendants("controlfield") Where (controlfield.Attribute("tag").Value = "001")
Select controlfield)

Dim Type999 = (From datafield In ser.Descendants("datafield") Where (datafield.Attribute("tag").Value = "999")
Select datafield.Elements.ElementAt(2)) '.Skip(0).First()

strFinalString = Num090.Value & " " & strPipe & " " & DTIC856.Value & " " & strPipe & " " & Edocs856.Value & " " & strPipe & " " & Title245_A.Value _
& " " & Title245_B.Value & " " & strPipe & " " & Author100.Value & " " & strPipe & " " & ADAnum037.Value & " " & strPipe & " " & CoAuthor500.Value & _
" " & strPipe & " " & Quater500.Value & " " & strPipe & " " & BOSUNnum001.Value & " " & strPipe & " " & Type999.Value


objWriter.WriteLine(strFinalString)
BytesWritten += strFinalString.Length



Catch ex As Exception

Henry Minute 25-Apr-11 13:19pm    
If you are going to be dealing with large files then you should really do the processing in a different Thread and the easiest way is to use a BackgroundWorker.

Here (http://www.java2s.com/Code/VB/GUI/BackgroundWorkerDemo.htm) is an example. You put the code to process the xml file in the DoWork method.

See if you can work it out for yourself but if you get stuck then ask again.
stopete82 25-Apr-11 15:38pm    
After father testing what’s going on with the original code is that the Progress bar goes from empty progress bar to full progress bar. In another words there are no progress bar increments. One thing I know that my progressbar1.max will my final strFinalSring.Length.
What I am having problems is setting up the fallowing variables:
ProgressBar1.Min = 0
Progressbar.Max = ? (final value until file finished written)
ProgressBar1.value = ?
With the code I provided using a small file, it writes three records and the values I get are as fallow:
BytesWritten += strFinalString.Length first record I get 485
BytesWritten += strFinalString.Length second record I get 912
BytesWritten += strFinalString.Length last record which it will be my max value is 1837
Again thanks for all your help
Henry Minute 25-Apr-11 15:57pm    
One thing I have just noticed, nothing to do with your problem, but I'll mention it now otherwise I will forget about it.
In your code you have:
strFinalString = Num090.Value & " " & strPipe & " " & DTIC856.Value & " " & strPipe & " " & ....... etc.
Concatenating strings like this is very inefficient and comparatively slow. Take a look at the StringBuilder Class and this (http://msdn.microsoft.com/en-us/library/aa260972%28v=vs.60%29.aspx) article.

Right, as far as the members of your ProgressBar are concerned Min is, as you say, obvious. For Max, as you say, you do not know the value until the write completes. BUT before you start writing you do know the number of records:
Dim Records = (From datafields In xd.Descendants("record")
Select datafields)
Use Records.Count to set Max and then have the ProgressBar step for each record written, rather than for the number of bytes. This will mean changing:
BytesWritten += strFinalString.Length
to:
BytesWritten += 1

Hope this helps.
stopete82 25-Apr-11 16:04pm    
Thanks for the tips, I will look into it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900