bpl5000
asked on
Do While loop
I have a nested loop that works fine, but I would like to improve it. I need to read in a line of the input file before entering into the loop because the last field on the first line of the file will become the file name of the new file being created. The file(myFile.txt) looks like this...
fname1,lname1,teacherA
fname2,lname2,teacherA
fname3,lname3,teacherA
fname4,lname4,teacherB
fname5,lname5,teacherB
fname6,lname6,teacherB
The code will create 2 files called teacherA.txt and teacherB.txt
TeacherA.txt would contain: TeacherB.txt would contain:
fname1,lname1 fname4,lname4
fname2,lname2 fname5,lname5
fname3,lname3 fname6,lname6
Here's the code:
Open "F:\myFile.txt" For Input As #1
Line Input #1, strLine
Do '// Open file for output per teacher
teacher = Split(strLine, ",")(2)
FileName = Split(strLine, ",")(2) + ".txt"
Open "H:\micrograms\" + FileName For Output As #2
'// Populate teacher file with student names
Do While teacher = Split(strLine, ",")(2) And Not EOF(1)
fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
Print #2, fullName
Line Input #1, strLine
Loop
If EOF(1) Then
fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
Print #2, fullName
End If
Close #2
Loop Until EOF(1)
Close #1
The code works, but it bothers me that I cannot handle all the outputting within the loop. After the code reaches EOF and exits the inner loop, I have to use an If statement to capture the last line from the input file. Any ideas on how I can do this cleaner?
Thanks for the help!
fname1,lname1,teacherA
fname2,lname2,teacherA
fname3,lname3,teacherA
fname4,lname4,teacherB
fname5,lname5,teacherB
fname6,lname6,teacherB
The code will create 2 files called teacherA.txt and teacherB.txt
TeacherA.txt would contain: TeacherB.txt would contain:
fname1,lname1 fname4,lname4
fname2,lname2 fname5,lname5
fname3,lname3 fname6,lname6
Here's the code:
Open "F:\myFile.txt" For Input As #1
Line Input #1, strLine
Do '// Open file for output per teacher
teacher = Split(strLine, ",")(2)
FileName = Split(strLine, ",")(2) + ".txt"
Open "H:\micrograms\" + FileName For Output As #2
'// Populate teacher file with student names
Do While teacher = Split(strLine, ",")(2) And Not EOF(1)
fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
Print #2, fullName
Line Input #1, strLine
Loop
If EOF(1) Then
fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
Print #2, fullName
End If
Close #2
Loop Until EOF(1)
Close #1
The code works, but it bothers me that I cannot handle all the outputting within the loop. After the code reaches EOF and exits the inner loop, I have to use an If statement to capture the last line from the input file. Any ideas on how I can do this cleaner?
Thanks for the help!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Well that would work, but all you have done is moved the If statement inside the loop and added another variable. You still are capturing the last line of data outside the loop and outputing the last line outside the loop. I was looking for something cleaner.
I just came up with this...
I removed the "NOT EOF(1) condition on the loop and added after "If EOF(1) Then Exit Do" after "Print #2, fullName". The code now looks like this:
Open "F:\myFile.txt" For Input As #1
Line Input #1, strLine
Do '// Open file for output per teacher
teacher = Split(strLine, ",")(2)
FileName = Split(strLine, ",")(2) + ".txt"
Open "F:\" + FileName For Output As #2
'// Populate teacher file with student names
Do While teacher = Split(strLine, ",")(2)
fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
Print #2, fullName
If EOF(1) Then Exit Do
Line Input #1, strLine
Loop
Close #2
Loop Until EOF(1)
Close #1
I just came up with this...
I removed the "NOT EOF(1) condition on the loop and added after "If EOF(1) Then Exit Do" after "Print #2, fullName". The code now looks like this:
Open "F:\myFile.txt" For Input As #1
Line Input #1, strLine
Do '// Open file for output per teacher
teacher = Split(strLine, ",")(2)
FileName = Split(strLine, ",")(2) + ".txt"
Open "F:\" + FileName For Output As #2
'// Populate teacher file with student names
Do While teacher = Split(strLine, ",")(2)
fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
Print #2, fullName
If EOF(1) Then Exit Do
Line Input #1, strLine
Loop
Close #2
Loop Until EOF(1)
Close #1
ASKER
After looking at DeadlyTrev's code more closely, I realized he was able to remove the inner loop completely. The only issue I see is that lastteacher never changes. I think within the If statement, lastteacher should be set equal to teacher.
Anyway, I like the idea of getting rid of the inner loop completely. Thanks for the help DeadlyTrev!
Anyway, I like the idea of getting rid of the inner loop completely. Thanks for the help DeadlyTrev!
ASKER
Here's the final code. When using "Loop while not eof(inFile)", the last line would get missed because each line from the input file is read in at the bottom of the loop. I replaced "Loop while not eof(infile)" with just Loop and then put "If EOF(inFile) Then Exit Do" inside the do loop. Not sure if this is a good practice, but the only other way I can see to do this is to add a print statement after the loop finishes to catch that last line. I wish there was some way of saying "Loop until one more time after EOF".
Dim fullName As String, strLine As String, teacher As String
Dim lastTeacher As String, inFile As Integer, outFile As Integer
inFile = FreeFile
Open "F:\myFile.txt" For Input As #inFile
Line Input #inFile, strLine
Do
teacher = Split(strLine, ",")(2)
MsgBox teacher
If teacher <> lastTeacher Then
lastTeacher = teacher
FileName = teacher + ".txt"
Close #outFile
outFile = FreeFile
Open "F:\" + FileName For Output As #outFile
End If
fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
Print #outFile, fullName
If EOF(inFile) Then Exit Do
Line Input #inFile, strLine
Loop
Close #inFile
Close #outFile
Dim fullName As String, strLine As String, teacher As String
Dim lastTeacher As String, inFile As Integer, outFile As Integer
inFile = FreeFile
Open "F:\myFile.txt" For Input As #inFile
Line Input #inFile, strLine
Do
teacher = Split(strLine, ",")(2)
MsgBox teacher
If teacher <> lastTeacher Then
lastTeacher = teacher
FileName = teacher + ".txt"
Close #outFile
outFile = FreeFile
Open "F:\" + FileName For Output As #outFile
End If
fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
Print #outFile, fullName
If EOF(inFile) Then Exit Do
Line Input #inFile, strLine
Loop
Close #inFile
Close #outFile
Oops. Sorry. Left out the line lastTeacher = Teacher. Glad you noticed it.
You can remove the If EOF(infile) ... line and replace Do with Do while not eof(infile). That will make the code a little neater, and will also take care of the situation where your input file might be empty.
You can remove the If EOF(infile) ... line and replace Do with Do while not eof(infile). That will make the code a little neater, and will also take care of the situation where your input file might be empty.
ASKER
I did try "Do while not eof(infile)", but the problem isn't the input file being empty, the problem is that strLine still has the last line of data in it when the eof occurs. I think I would either need to output the last line after the loop exits or have some way of saying "after eof is reached, loop one more time."
No. There is a 'priming read' of the data file before you go into the loop. You need to attempt to read from the file before you know that you've hit EOF. Then the loop starts; Do While not EOF(f). This means that if the priming read hit EOF then you won't even enter the loop (takes care of empty files). If processing proceeds into the loop then we have work to do ... open a new file if this teacher is different to the last and output data, then after that we read another line from the input. Code jumps back to the test at the top of the loop. If the read hit EOF then the loop will end, otherwise more work ... , etc.
Also, typos in the above code;
Print #2, fullname -> Print #outfile, fullname
Line input #1, strline -> Line Input #infile, strline