none
How to increment and print a serialized bar code in vb.net from a PrintDialog

    Question

  • I wrote a bar code program sometime ago with vb.net that when the end user clicks the print button, the program will open the text file that contains the ZPL bar code, increment the serial number by 1, write the new serial number back to the text file, and then print out the predetermined amount of bar codes to a zebra printer.

    Now I am trying to rewrite the code so that it will print the number of bar codes the end user wants from the number they type into the PrintDialog. In my updated code, I tried putting in a DO......LOOP UNTIL . It will print out the number of bar codes the user puts into the PrintDialog box, but it doesn't serialize. By that I mean if the user enters 5 into the PrintDialog, the program will print serial # 01 five times instead of printing 02, 03, 04, 05, 06.

    Can anyone give me some pointers on how to have the program read, write, and print the desired x amount of times based on the number a user inputs into the PrintDialog?

    Here is my original code:

    Dim sL() As String = IO.File.ReadAllLines("C:\Labels\loop test.txt")
         Dim CurrentBar(2) As String
    
            For i = 0 To 2
                CurrentBar(i) = sL(sL.Length - 3 + i)
            Next
    
           If CurrentBar(1).Length >= 28 Then
    
                CurrentBar(1) = CurrentBar(1).Substring(0, 18) & Format(CInt(CurrentBar(1).Substring(18, 10) + 1), "0000000000") & CurrentBar(1).Substring(28)
    
            Else
    
                MessageBox.Show("String is not long enough!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    
            End If
    
            'Write the updated vaules back to the Text File
            IO.File.WriteAllText("C:\Labels\loop test.txt",
            CurrentBar(0) & vbNewLine &
            CurrentBar(1) & vbNewLine &
            CurrentBar(2))
    
        Dim psi As New ProcessStartInfo
                psi.UseShellExecute = True
                psi.Verb = "print"
                psi.WindowStyle = ProcessWindowStyle.Hidden                
                psi.FileName = "C:\Labels\loop test.txt"
                Process.Start(psi)
    

    And here is my updated code:

    Dim PrintDialog1 As New PrintDialog()
            Dim psi As New ProcessStartInfo
    
            Do
                'Put the text file into an array and increment the line containing the Serial # by 1
                Dim sL() As String = IO.File.ReadAllLines("\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt")
                Dim CurrentBar(2) As String
                For i = 0 To 2
                    CurrentBar(i) = sL(sL.Length - 3 + i)
                Next
    
                If CurrentBar(1).Length >= 28 Then
    
                    CurrentBar(1) = CurrentBar(1).Substring(0, 18) & Format(CInt(CurrentBar(1).Substring(18, 10) + 1), "0000000000") & CurrentBar(1).Substring(28)
    
                Else
    
                    MessageBox.Show("String is not long enough!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    
                End If
    
                'Write the updated vaules back to the Text File
                IO.File.WriteAllText("\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt",
                CurrentBar(0) & vbNewLine &
                CurrentBar(1) & vbNewLine &
                CurrentBar(2))
    
                'Print the labels
                'Get the number of copies to print  
                If (PrintDialog1.ShowDialog() = DialogResult.OK) Then
    
                    For i = 0 To PrintDialog1.PrinterSettings.Copies - 1
    
                        psi.UseShellExecute = True
                        psi.Verb = "print"
                        psi.WindowStyle = ProcessWindowStyle.Hidden
                        psi.Arguments = PrintDialog1.PrinterSettings.PrinterName.ToString()
                        psi.FileName = "\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt"
                        Process.Start(psi)
                    Next
                End If
            Loop Until PrintDialog1.PrinterSettings.Copies

    And my text file:

    ^XA
    ^LH20,85^BY3^AE^SN0000000001R,,Y^B3N,,60,,Y^FS
    ^XZ

    Friday, August 10, 2012 2:39 PM

Answers

  • Acamar,

    In took your advice and inserted a breakpoint in the code. I noticed that with the breakpoint, the program was incrementing the bar code correctly and as you suggested, was waiting until AFTER the Loop completed before it printed it out. I decided to try to some how slow down the process so the program would read, write, and print before it continued the loop. I managed to accomplish this  by inserting  System.Threading.Thread.Sleep() between Process.Start(psi) and the Loop. I don't know if there is a better way of doing it, but it does work! Here is my amended code:

    Dim psi As New ProcessStartInfo
            Dim PrintDialog1 As New PrintDialog
    
            'Get the number of copies to print 
            If (PrintDialog1.ShowDialog() = DialogResult.OK) Then
    
                For j = 0 To PrintDialog1.PrinterSettings.Copies - 1
                    Do
    
                        'Put the text file into an array and increment the line containing the Serial # by 1
                        Dim sL() As String = File.ReadAllLines("\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt")
                        Dim CurrentBar(2) As String
                        For i = 0 To 2
                            CurrentBar(i) = sL(sL.Length - 3 + i)
                        Next
    
                        If CurrentBar(1).Length >= 28 Then
                            CurrentBar(1) = CurrentBar(1).Substring(0, 18) & Format(CInt(CurrentBar(1).Substring(18, 10) + 1), "0000000000") & CurrentBar(1).Substring(28)
                        Else
                            MessageBox.Show("String is not long enough!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                        End If
    
                        'Write the updated vaules back to the Text File
                        File.WriteAllText("\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt",
                        CurrentBar(0) & vbNewLine &
                        CurrentBar(1) & vbNewLine &
                        CurrentBar(2))
    
                        psi.UseShellExecute = True
                        psi.Verb = "print"
                        psi.WindowStyle = ProcessWindowStyle.Hidden
                        psi.FileName = "\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt"
                        Process.Start(psi)
    
                        System.Threading.Thread.Sleep(500)
    
                    Loop Until PrintDialog1.PrinterSettings.Copies - 1
                Next
            End If

    Thanks again for all your help and tips!



    • Edited by bmj1474 Monday, August 13, 2012 8:42 PM
    • Marked as answer by bmj1474 Monday, August 13, 2012 8:42 PM
    Monday, August 13, 2012 8:40 PM

All replies

  • I'm not knowledgeable on printing but this may help you - http://www.mindstick.com/Articles/f8fd0f1d-d6a1-4581-bf24-f72deaeda85b/

    You've taught me everything I know but not everything you know.

    Saturday, August 11, 2012 8:05 PM
  • Your incrementing and writing is outside the loop.  You need to re-arrange your code segments like this:

    Dim PrintDialog1 As New PrintDialog()
           
    Dim psi As New ProcessStartInfo

            'Print the labels
           
    'Get the number of copies to print  
           
    If (PrintDialog1.ShowDialog() = DialogResult.OK) Then
                
    For j = 0 To PrintDialog1.PrinterSettings.Copies - 1
                    'Put the text file into an array and increment the line containing the Serial # by 1
                   
    Dim sL() As String = IO.File.ReadAllLines("\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt")
                   
    Dim CurrentBar(2) As String
                   
    For i = 0 To 2
                        CurrentBar
    (i) = sL(sL.Length - 3 + i)
                   
    Next

                   
    If CurrentBar(1).Length >= 28 Then
                        CurrentBar
    (1) = CurrentBar(1).Substring(0, 18) & Format(CInt(CurrentBar(1).Substring(18, 10) + 1), "0000000000") & CurrentBar(1).Substring(28)
                   
    Else
                        MessageBox
    .Show("String is not long enough!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                   
    End If

                   
    'Write the updated vaules back to the Text File
                    IO
    .File.WriteAllText("\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt",
                    CurrentBar
    (0) & vbNewLine &
                    CurrentBar
    (1) & vbNewLine &
                    CurrentBar
    (2))
                    psi.UseShellExecute = True
                    psi
    .Verb = "print"
                    psi
    .WindowStyle = ProcessWindowStyle.Hidden
                    psi
    .Arguments = PrintDialog1.PrinterSettings.PrinterName.ToString()
                    psi
    .FileName = "\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt"
                    Process
    .Start(psi)
                Next
            End If

    • Edited by Acamar Sunday, August 12, 2012 7:08 AM loop vble
    Saturday, August 11, 2012 9:37 PM
  • Acamar,

    Thanks for you reply. While it gets me closer to what I need to do, it presented another problem.

    I tried your code as follows:

     'Get the number of copies to print  
            If (PrintDialog1.ShowDialog() = DialogResult.OK) Then
                For j = 0 To PrintDialog1.PrinterSettings.Copies - 1
                    Do 
    
                        'Put the text file into an array and increment the line containing the Serial # by 1
                        Dim sL() As String = IO.File.ReadAllLines("C:\Labels\LoopTest.txt")
                        Dim CurrentBar(2) As String
                        For i = 0 To 2
                            CurrentBar(i) = sL(sL.Length - 3 + i)
                        Next
    
                        If CurrentBar(1).Length >= 28 Then
                            CurrentBar(1) = CurrentBar(1).Substring(0, 18) & Format(CInt(CurrentBar(1).Substring(18, 10) + 1), "0000000000") & CurrentBar(1).Substring(28)
                        Else
                            MessageBox.Show("String is not long enough!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                        End If
    
                        'Write the updated vaules back to the Text File
                        IO.File.WriteAllText("C:\Labels\LoopTest.txt",
                        CurrentBar(0) & vbNewLine &
                        CurrentBar(1) & vbNewLine &
                        CurrentBar(2))
    
                        psi.UseShellExecute = True
                        psi.Verb = "print"
                        psi.WindowStyle = ProcessWindowStyle.Hidden
                        psi.Arguments = PrintDialog1.PrinterSettings.PrinterName.ToString()
                        psi.FileName = "C:\Labels\LoopTest.txt"
                        Process.Start(psi)
                    Loop Until PrintDialog1.PrinterSettings.Copies
    
                Next
    
            End If

    While it does read and write the text but it only prints out the last barcode written back to the file. So if I enter 2 into the PrintDialog, the code will serialize properly, but it only prints out 003 twice (which is what was last thing written to the text file). How do I get it to print the text file after EACH time it is written to instead of after the last time it is written to?

    Sunday, August 12, 2012 12:30 PM
  • You are incrementing and writing the file before doing the printing, so I assume that the first number to be printed is one more than the current value in the file.

    If that procedure is not working properly then it indicates the printing process you are using is not compatible with the repetition that you require.  Perhaps the print procedure that you are starting are accessing the file after the updating is completed for all copies.

    You should insert a breakpoint immediately before the process start command so that you can examime the variables (CurrentBar) and the file contents at that point and confirm that the updating for each iteration is correct.  If it is, then your problem is with the print process.

    In that case you can investigate changing the Process operation so that the code does not continue on to the next incrementing until the print process has completed.


    • Edited by Acamar Sunday, August 12, 2012 9:48 PM sp
    • Proposed as answer by Mark Liu-lxfModerator Monday, August 13, 2012 6:12 AM
    • Marked as answer by bmj1474 Monday, August 13, 2012 8:31 PM
    • Unmarked as answer by bmj1474 Monday, August 13, 2012 8:31 PM
    Sunday, August 12, 2012 9:47 PM
  • Acamar,

    In took your advice and inserted a breakpoint in the code. I noticed that with the breakpoint, the program was incrementing the bar code correctly and as you suggested, was waiting until AFTER the Loop completed before it printed it out. I decided to try to some how slow down the process so the program would read, write, and print before it continued the loop. I managed to accomplish this  by inserting  System.Threading.Thread.Sleep() between Process.Start(psi) and the Loop. I don't know if there is a better way of doing it, but it does work! Here is my amended code:

    Dim psi As New ProcessStartInfo
            Dim PrintDialog1 As New PrintDialog
    
            'Get the number of copies to print 
            If (PrintDialog1.ShowDialog() = DialogResult.OK) Then
    
                For j = 0 To PrintDialog1.PrinterSettings.Copies - 1
                    Do
    
                        'Put the text file into an array and increment the line containing the Serial # by 1
                        Dim sL() As String = File.ReadAllLines("\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt")
                        Dim CurrentBar(2) As String
                        For i = 0 To 2
                            CurrentBar(i) = sL(sL.Length - 3 + i)
                        Next
    
                        If CurrentBar(1).Length >= 28 Then
                            CurrentBar(1) = CurrentBar(1).Substring(0, 18) & Format(CInt(CurrentBar(1).Substring(18, 10) + 1), "0000000000") & CurrentBar(1).Substring(28)
                        Else
                            MessageBox.Show("String is not long enough!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                        End If
    
                        'Write the updated vaules back to the Text File
                        File.WriteAllText("\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt",
                        CurrentBar(0) & vbNewLine &
                        CurrentBar(1) & vbNewLine &
                        CurrentBar(2))
    
                        psi.UseShellExecute = True
                        psi.Verb = "print"
                        psi.WindowStyle = ProcessWindowStyle.Hidden
                        psi.FileName = "\\10.5.2.250\TxtFiles$\4x6\LoopTest.txt"
                        Process.Start(psi)
    
                        System.Threading.Thread.Sleep(500)
    
                    Loop Until PrintDialog1.PrinterSettings.Copies - 1
                Next
            End If

    Thanks again for all your help and tips!



    • Edited by bmj1474 Monday, August 13, 2012 8:42 PM
    • Marked as answer by bmj1474 Monday, August 13, 2012 8:42 PM
    Monday, August 13, 2012 8:40 PM
  • "I don't know if there is a better way of doing it [...]"

    Maybe you can replace

         Process.Start(psi)     
         System.Threading.Thread.Sleep(500)

    by

         Dim p = Process.Start(psi)
         p.WaitForExit


    Armin

    Monday, August 13, 2012 8:47 PM
  • Using Thead Sleep will probably work, but it is a rough way to fix the problem, and it might be unreliable, for instance if there is some problem with the printing.    My suggestion was to investigate changing the way that you are using the Process class to control how that process executes, in order to ensure that your code does not continue until the print procedure has read the contents of the file. In particular, I would recommend looking at the options that are available when you create a Process instance, instead of relying on the shared instance.  When you create your own instance you have access to a large number of methods within that isntance that give you very fine control over the process that you are starting, including the ability to detect when the process is reported as finished.
    Monday, August 13, 2012 9:29 PM