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 UNTIL ......LOOP. 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
Dim sL() As String = IO.File.ReadAllLines("C:\Labels\loop test.txt")
Dim CurrentBar(2) As String
Do Until PrintDialog1.PrinterSettings.Copies - 1
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))
'Print the labels
'Get the number of copies to print
If (PrintDialog1.ShowDialog() = DialogResult.OK) Then
'print desired number of copies to target printer
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 = "C:\Labels\loop test.txt"
Process.Start(psi)
Next
End If
Loop
And here is my text file:
^XA
^LH20,85^BY3^AE^SN0000000001R,,Y^B3N,,60,,Y^FS
^XZ
I think your problem in your new code is that you are reading in the text file before you do the loop. At the end of the loop, you write out the new values, but never read them back in (or reuse them). Therefore, the input is always going to be what it was before the loop iterates. I think by putting
sl() = IO.File.ReadAllLines("C:\Labels\loop test.txt")
right after your Do Until statement should fix this.
Related
I coded a simple program that reads from a Textfile Line by Line and If the current readed Line has alphabetics (a-z A-Z) it will write that Line into an other txt file.
If the current readed line doesn't have alphabetics it wont write that line into a new text file.
I created this for the purpose that I have members registering at my website and some of them are using only numbers as Username. I will filter them out and only save the alphabetic Names. (Focus on this Project please I know i could just use php stuff)
That works great already but it takes a while to read line by line and write into the other text file (Write speed 150kb in 1 Minute - Its not my drive I have a fast ssd).
So I wonder if there is a faster way. I could "readalllines" first but on large files it just freezes my program so I don't know if that works too (I want to focus on large +1gb files)
This is my code so far:
If System.IO.File.Exists(FILE_NAME) = True Then
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Do While objReader.Peek() <> -1
Dim myFile As New FileInfo(output)
Dim sizeInBytes As Long = myFile.Length
If sizeInBytes > splitvalue Then
outcount += 1
output = outputold + outcount.ToString + ".txt"
File.Create(output).Dispose()
End If
count += 1
TextLine = objReader.ReadLine() & vbNewLine
Console.WriteLine(TextLine)
If CheckForAlphaCharacters(TextLine) Then
File.AppendAllText(output, TextLine)
Else
found += 1
Label2.Text = "Removed: " + found.ToString
TextBox1.Text = TextLine
End If
Label1.Text = "Checked: " + count.ToString
Loop
MessageBox.Show("Finish!")
End If
First of all, as hinted by #Sean Skelly updating UI controls - repeatedly - is an expensive operation.
But your bigger problem is File.AppendAllText:
If CheckForAlphaCharacters(TextLine) Then
File.AppendAllText(output, TextLine)
Else
found += 1
Label2.Text = "Removed: " + found.ToString
TextBox1.Text = TextLine
End If
AppendAllText(String, String)
Opens a file, appends the specified string to the file, and then
closes the file. If the file does not exist, this method creates a
file, writes the specified string to the file, then closes the file.
Source
You are repeatedly opening and closing a file, causing overhead. AppendAllText is a convenience method since it performs several operations in one single call but you can now see why it's not performing well in a big loop.
The fix is easy. Open the file once when you start your loop and close it at the end. Make sure that you always close the file properly even when an exception occurs. For that, you can either invoke the Close in a Finally block, or use a context manager, that is keep your file write operations within a Using block.
And you could remove the print to console as well. Display management has a cost too. Or you could print status updates every 10K lines or so.
When you've done all that, you should notice improved performance.
My Final Code - It works a lot faster now (500mbs in 1 minute)
Using sw As StreamWriter = File.CreateText(output)
For Each oneLine As String In File.ReadLines(FILE_NAME)
Try
If changeme = True Then
changeme = False
GoTo Again2
End If
If oneLine.Contains(":") Then
Dim TestString = oneLine.Substring(0, oneLine.IndexOf(":")).Trim()
Dim TestString2 = oneLine.Substring(oneLine.IndexOf(":")).Trim()
If CheckForAlphaCharacters(TestString) = False And CheckForAlphaCharacters(TestString2) = False Then
sw.WriteLine(oneLine)
Else
found += 1
End If
ElseIf oneLine.Contains(";") Or oneLine.Contains("|") Or oneLine.Contains(" ") Then
Dim oneLineReplac As String = oneLine.Replace(" ", ":")
Dim oneLineReplace As String = oneLineReplac.Replace("|", ":")
Dim oneLineReplaced As String = oneLineReplace.Replace(";", ":")
If oneLineReplaced.Contains(":") Then
Dim TestString3 = oneLineReplaced.Substring(0, oneLineReplaced.IndexOf(":")).Trim()
Dim TestString4 = oneLineReplaced.Substring(oneLineReplaced.IndexOf(":")).Trim()
If CheckForAlphaCharacters(TestString3) = False And CheckForAlphaCharacters(TestString4) = False Then
sw.WriteLine(oneLineReplaced)
Else
found += 1
End If
Else
errors += 1
textstring = oneLine
End If
Else
errors += 1
textstring = oneLine
End If
count += 1
Catch
errors += 1
textstring = oneLine
End Try
Next
End Using
I have a TextBox and it contains this text "File Was Created"
I would like to place the cursor one space over from the end of this text in the TextBox
I am trying to NOT say Simple Enough Task BUT I have wasted 2 hours with no solution
YES I know if I change the text to this "File Was Created " it will work NOT a solution
Here is the code mess I have tried
Dim L As Integer
L = tbMessage.Text.Length
L += 1
'tbMessage.Text = CStr(L)
'tbHaveTwo.Text = frmOne.vR
'Me.ActiveControl = tbMessage
'tbMessage.SelectionStart = tbMessage.Text.Length
tbMessage.SelectionStart = L
tbMessage.Select()<br/>
Here is Two updated ways to solve this issue Jimi way less code
tbMessage.Text = "File Was Created"
'This Code involves more code
'Dim str As String
'str = Mid(tbMessage.Text, tbMessage.Text.Length)
'If str <> " " Then
' tbMessage.Text = tbMessage.Text & " "
'End If
'Answer from Jimi Works Great
tbMessage.AppendText(ChrW(32))
tbMessage.SelectionStart = tbMessage.Text.Length
tbMessage.Select()
So you don't end up with a ton of spaces on the end of your message?
tbMessage.AppendText(If(tbMessage.Text.EndsWith(" "), "", " "))
tbMessage.SelectionStart = tbMessage.TextLength
tbMessage.Focus()
I'm new to VB.Net. I've implemented scripting to compare two text files that checks if the value or data is different from each other. The only problem is it shows only one line instead of two
Below is the data that is in text A and C:
Text A: Orange,Apple,Mango,Strawberry,Banana
Text B: Orange, Apple, Mango, Blueberry, Grapes
Here is my script
Sub Main()
Const ForReading = 1
Dim objFile1, objFile2, objFile3
Dim objFSO = CreateObject("Scripting.FileSystemObject")
objFile1 = objFSO.OpenTextFile("C:\Scripts\A.txt", ForReading) 'Current.txt represents Text from AWS network
Dim strAddresses, strCurrent, strNoAddress
strAddresses = objFile1.ReadAll
objFile1.Close()
objFile2 = objFSO.OpenTextFile("C:\Scripts\C.txt", ForReading) 'Current.txt represents Text from Shell network
Do Until objFile2.AtEndOfStream
strCurrent = objFile2.ReadLine
If InStr(strAddresses, strCurrent) = 0 Then
strNoAddress = strCurrent & vbCrLf
End If
Loop
objFile2.Close()
objFile3 = objFSO.CreateTextFile("C:\Scripts\Differences.txt")
objFile3.WriteLine(strNoAddress)
objFile3.Close()
End Sub
Your code does not work because you overwrite strNoAddress everytime the if conditions is true:
strNoAddress = strCurrent & vbCrLf
So when you hit Blueberry, strNoAddress becomes Blueberry\n.
When you hit Grapes, strNoAddress becomes Grapes\n instead of Blueberry\nGrapes\n.
You want to concatenate the strings instead:
strNoAddress &= strCurrent & vbCrLf
A more "up-to-date" version of your code without the legacy/leftover functions of VB6 could look like:
Dim addresses = File.ReadAllLines("C:\Scripts\A.txt")
Dim noAdress = String.Empty
Using reader = new StreamReader("C:\Scripts\B.txt")
Do Until reader.EndOfStream
Dim current = reader.ReadLine
If Not addresses.Contains(current) Then
noAdress &= current & Environment.NewLine
End If
Loop
End Using
...
Or, to make it even more simple (good enough for small files, and without a trainling newline):
Dim fileA = File.ReadAllLines("C:\Scripts\A.txt")
Dim fileB = File.ReadAllLines("C:\Scripts\B.txt")
Dim noAdress = String.Join(Environment.NewLine, fileB.Where(Function(b) Not fileA.Contains(b)))
I'm a student and I'm on my way to deliver my examproject in Programming on level C.
I'm in the very end of my project, I have programmed a game with a highscore. The highscore saves the score in notepad so it can read the old highscore again when the game is relaunched.
The problem is, everytime a new highscore comes it keep adding a new one. So if I have played 100 games there is 100 highscores and I don't want that. I want to set a limit on my highscore. I'm thinking about 15.
I have two ideas. the first idea is that the program only read the first 15 highscores.
The second idea is that I create a sub that reads the old highscorelist, then compare it with the new highscore and checks if the old highscorelist needs to be updated.
But the problem is, I'm having a big trouble programming that.. I'll now upload my highscore subs, and ask you for help.
This is where I write my highscorelist
Private Sub skrivhighscore()
ReDim Preserve HighscoreNavn(UBound(HighscoreNavn) + 1)
ReDim Preserve HighscoreLevel(UBound(HighscoreLevel) + 1)
'insets the new highscore on the right place so that level is on top
For i As Integer = 1 To UBound(HighscoreLevel)
If (level > HighscoreLevel(i)) Then
'the new highscore is bigger than highscorecount(i). inset the new here but first move the others
For j As Integer = UBound(HighscoreLevel) To i + 1 Step -1
'kopier array(j-1) til array(j)
HighscoreNavn(j) = HighscoreNavn(j - 1)
HighscoreLevel(j) = HighscoreLevel(j - 1)
Next j
HighscoreNavn(i) = brugernavn
' sets highscore name to username. brugernavn = username
HighscoreLevel(i) = level
'set shighscorelvel(I) to the level the user died on.
Exit For
End If
Next i
'clear username and change level to 0
brugernavn = ""
level = 0
'writes highscore to a file so it can be read next time
highscoreboardskriv()
End Sub
This is where I save my highscorelist to notepad
Private Sub highscoreboardskriv()
' create a file at the same place as the game
'append:=False means overwrite and not repleace
fileWriter = My.Computer.FileSystem.OpenTextFileWriter("HighScore.txt", append:=False)
For i As Integer = 1 To UBound(HighscoreLevel)
' In every line the name is on the first 20 spaces and the score is from space 22
'example: "Player1 : 2"
If (HighscoreNavn(i) IsNot Nothing) AndAlso (HighscoreNavn(i).Trim <> "") Then
' If username is empty, it will not be written in the highscorelist. by using this method a highscore can be removed.
FileLine = HighscoreNavn(i).PadRight(20) & ":" & HighscoreLevel(i).ToString.PadLeft(5)
fileWriter.WriteLine(FileLine)
End If
Next i
fileWriter.Close()
End Sub
This is where I show my highscorelist
Private Sub Highscore()
'Now we read both information again from the file
Dim HighScoreText As String = ""
'highscorelist line by line
For i As Integer = 1 To UBound(HighscoreLevel)
'takes every spaces in an array (we dont use the first line)
If (HighscoreNavn(i) IsNot Nothing) AndAlso (HighscoreNavn(i).Trim <> "") Then
If (HighScoreText <> "") Then
'new line by every highscore except the first line
HighScoreText = HighScoreText & vbNewLine
End If
'line 1 example: "player1 : 230"
HighScoreText = HighScoreText & HighscoreNavn(i).PadRight(20) & ":" & HighscoreLevel(i).ToString.PadLeft(5)
End If
Next i
'show highscorelist to user
MsgBox(HighScoreText, Title:="Highscore list")
End Sub
This is where I read my highscorelist from notepad :
Public Sub highscoreboardlæs()
Public HighscoreNavn(0) As String
Public HighscoreLevel(0) As Integer
Public level As Integer = 0
Public fileReader As System.IO.StreamReader
Public FileLine As String
Try
fileReader = My.Computer.FileSystem.OpenTextFileReader("HighScore.txt")
FileLine = fileReader.ReadLine()
While (FileLine <> "") 'loop så længe der er linjer i filen, for at få alle highscores med
'extend array with 1 extra line
ReDim Preserve HighscoreNavn(UBound(HighscoreNavn) + 1)
ReDim Preserve HighscoreLevel(UBound(HighscoreLevel) + 1)
HighscoreNavn(UBound(HighscoreNavn)) = Mid(FileLine, 1, 20)
HighscoreLevel(UBound(HighscoreLevel)) = Val(Mid(FileLine, 22, 5))
'read next line from the file
FileLine = fileReader.ReadLine()
End While
fileReader.Close()
Catch
'i use try method, else it will crash if there arent any highscorelist
End Try
'MsgBox("Highscore: " & vbNewLine & fileReader.ReadLine() & vbNewLine & fileReader.ReadLine() & vbNewLine & fileReader.ReadLine())
End Sub
If you just want to keep 15 scores in the file you could just read all the scores into a array, sort it and write the 15 highest back into the file.
I would not recommend doing that if you have longer score lists, as you load all the scores into the memory, which might give you an OOM (Out Of Memory) exception with bigger lists, but in your case it's completely fine.
Sub AddScore(score%, filePath$)
Dim Scores As New List(Of Integer)
' Loads all the scores into our list
Using Sr As New IO.StreamReader(filePath)
Do Until Sr.EndOfStream
Scores.Add(Sr.ReadLine)
Loop
End Using
Scores.Sort() ' Sort it
Scores.Reverse() ' Reverse it, as the the highest scores is at the bottom. You would property want to just read trough the last 15 items in the list rather than reversing it, but I'm just being lazy.
' Write the first 15
Using Sw As New IO.StreamWriter(filePath, False)
For i = 0 To Math.Min(Scores.Count - 1, 14)
Sw.WriteLine(Scores(i))
Next
End Using
End Sub
Oh, and btw, your Swedish right? Would you mind sending me a PM, as I'm quite interested in how programming school is in Sweden.
I'm writing in VB 2010 with a form with one button to be completely idiot. I haven't done VB in awhile and noticed 2010 has a lot of changes compare when I did it a couple of years ago.
What I need done is it to read from a file and write two new separate files while writing to original. It will read from a text file to get some contents and compare the current date.
The text content will be a serial and the next two columns will be dates.
Dim iFileName As New StreamReader("G:\SAP In and Out\test.txt", False)
Dim sFileExport As New StreamWriter(DateValue(Now)) + " SAP Export", False)
Dim sFileImport As New StreamWriter(DateAdd(DateInterval.Day, 10, DateValue(Now)) + " SAP Import", False)
Dim VTS As String 'Will be used to grab the VT serial
Dim CurrentDate As Date 'Will be used to compare to grabbed dates
Dim NextDateOut As Date 'Will be used to grab next date out value
Dim NextDateIn As Date 'Will be used to grab next date in value
'Setting a consistant value with daily'
CurrentDate = DateValue(Now)
Do While Not EOF(1)
Input(iFileName),VTS,NextDateOut,NextDateIn
If CurrentDate = NextDateOut Then
'Write to the export File
sFileExport.write(VTS)
'Write under the just read line in the open file
iFileName.write(/newline + VTS + /TAB + (DateAdd(DateInterval.Day, 20, DateValue(Now)) + /tab + (DateAdd(DateInterval.Day, 30, DateValue(Now)))
ElseIf CurrentDate = NextDateIn Then
'Write to import file
sFileImport.Write(VTS)
End If
Loop
End Sub
But my syntax is off and it's obviously not running since I'm asking for help.
Please help and thanks in advance. I've been working on this for hours and haven't had any positive results yet.
Well I think its right now, but i had to add an extra function so i could test it out.
I was receiving errors o the date format because I expect you use US date format (MM/DD/YYYY) and I use UK date format (DD/MM/YYYY).
Anyway you can strip the function out as I dont think you will need it, but I've left it in anyway so you can see whats going on its quite self explanatory and simply converts between the date formats, though it was made more difficult by the fact your days and month are not two digits long (no leading zero).
I hope it helps point you in the right direction and you can chop and change it to your preference.
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim iFileName As New System.IO.StreamReader("c:\temp\vttest.txt", False)
Dim iReadData As List(Of String)
Dim Buffer As String
'Read complete file into array
iReadData = New List(Of String)
Do While Not iFileName.EndOfStream()
Try
Buffer = ""
Buffer = iFileName.ReadLine()
iReadData.Add(Buffer)
Catch ex As Exception
'error or end of file
End Try
Loop
iFileName.Close()
'Not needed
'Dim VTS As String 'This is in iLineData(0) after we split the line
'Dim NextDateOut As Date 'This is in iLineData(1) after we split the line
'Dim NextDateIn As Date 'This is in iLineData(2) after we split the line
'Process
Dim iFileUpdated As New System.IO.StreamWriter("c:\temp\vttest_copy.txt", True)
Dim sFileExport As New System.IO.StreamWriter("c:\temp\vttest" & Replace(DateValue(Now), "/", "_") & " SAP Export.txt", True)
Dim sFileImport As New System.IO.StreamWriter("c:\temp\vttest" & Replace(DateAdd(DateInterval.Day, 10, DateValue(Now)), "/", "_") + " SAP Import.txt", True)
Dim iLineData() As String
'Setting a consistant value with daily'
Dim CurrentDate As Date = DateValue(Now)
Dim RowId = 0
Do While RowId < iReadData.Count()
iLineData = Split(iReadData(RowId), " ")
iFileUpdated.WriteLine(iLineData(0) & " " & iLineData(1) & " " & iLineData(2))
If CurrentDate = FormatDate(iLineData(1), "US", "UK") Then
'Write to the export File
sFileExport.WriteLine(iLineData(0))
'Write under the just read line in the open file
iFileUpdated.WriteLine(iLineData(0) & " " & (DateAdd(DateInterval.Day, 20, DateValue(Now))) & " " & (DateAdd(DateInterval.Day, 30, DateValue(Now))))
ElseIf CurrentDate = FormatDate(iLineData(2), "US", "UK") Then
'Write to import file
sFileImport.WriteLine(iLineData(0))
End If
RowId = RowId + 1
Loop
sFileExport.Close()
sFileImport.Close()
iFileUpdated.Close()
MsgBox("Finshed")
End Sub
'This section added because my PC is set to DD/MM/YYYY (UK)
'Expect yours is set to MM/DD/YYYY (US)
Function FormatDate(ThisDate As String, ThisFormat As String, ThisTargetFormat As String) As Date
Dim X As Integer = 0
Dim Day1 As Integer = 0
Dim Month1 As Integer = 0
Dim Year1 As Integer = 0
Dim Buf As String = ""
If ThisFormat = "US" Then
For X = 1 To Len(ThisDate)
If Mid(ThisDate, X, 1) = "/" Then
If Month1 > 0 Then
Day1 = Buf
Buf = ""
Else
Month1 = Buf
Buf = ""
End If
Else
Buf = Buf & Mid(ThisDate, X, 1)
End If
Next
Year1 = Buf
Else
For X = 1 To Len(ThisDate)
If Mid(ThisDate, X, 1) = "/" Then
If Day1 > 0 Then
Month1 = Buf
Buf = ""
Else
Day1 = Buf
Buf = ""
End If
Else
Buf = Buf & Mid(ThisDate, X, 1)
End If
Next
Year1 = Buf
End If
'reformat for output
If ThisFormat = "US" Then
If ThisTargetFormat = "US" Then
'USA
FormatDate = (Format(Month1, "00") & "/" & Format(Day1, "00") & "/" & Format(Year1, "0000"))
Else
'UK
FormatDate = (Format(Day1, "00") & "/" & Format(Month1, "00") & "/" & Format(Year1, "0000"))
End If
Else
If ThisTargetFormat = "US" Then
'USA
FormatDate = (Format(Month1, "00") & "/" & Format(Day1, "00") & "/" & Format(Year1, "0000"))
Else
'UK
FormatDate = (Format(Day1, "00") & "/" & Format(Month1, "00") & "/" & Format(Year1, "0000"))
End If
End If
End Function
Additionally i changed the file names so as not to overwrite the existing files (So i could compare the two files).
Most of the problems were arising from the back slashes in the dates in the FILENAMES - making the pc look for paths like /3/12 i guess it was translating the slashes into folder delimiters so I replaced them with UNDERSCORES on the fly.
Once you have edited the code to your preference you can OVERWRITE the existing file rather than generating a _copy.txt as thats how I tested with a _copy.txt in the sample.
Update
Thanks for the feedback. Well its strange that your (generated) files are empty, because in the ones I have ONE has data the other is empty. This leads me to the assumption that your tweaks may have something to do with it?
For your reference I have posted them below.
ORIGINAL FILE [VTSTEST.TXT]
VT1000 3/26/2013 4/5/2013
VT1100 3/26/2013 4/5/2013
VT2000 3/27/2013 4/6/2013
VT2200 3/27/2013 4/6/2013
COPY OF VTSTEST.TXT (after modification)
VT1000 3/26/2013 4/5/2013
VT1100 3/26/2013 4/5/2013
VT2000 3/27/2013 4/6/2013
VT2000 16/04/2013 26/04/2013
VT2200 3/27/2013 4/6/2013
VT2200 16/04/2013 26/04/2013
Note: I expect the two longer lines are the ones inserted inbetween the existing four lines of text
VTTEST06_04_2013 SAP Import.Txt
This file was empty
VTTEST27_03_2013 SAP Export.TXT
VT2000
VT2000