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!
LVL 5
bpl5000Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DeadlyTrevCommented:
   Dim infile as integer
    Dim outfile as integer
    Dim lastteacher as string
    lastteacher = ""
    infile = freefile
    Open "F:\myFile.txt" For Input As #infile
    Line Input #infile, strLine
    Do
        teacher = Split(strLine, ",")(2)
        if teacher <> lastteacher then
            FileName =teacher + ".txt"
            close #outfile
            outfile = freefile
            Open "H:\micrograms\" + FileName For Output As #outfile
                '// Populate teacher file with student names
        end if
        fullName = Split(strLine, ",")(0) + " " + Split(strLine, ",")(1)
        Print #2, fullName
        Line Input #1, strLine
    Loop while not eof(infile)
    Close #infile
    Close #outfile

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DeadlyTrevCommented:
As above, assuming teachers are grouped together in the input file.  If teacher data is intermingled then just open the output file (for append access) once for each line then close it.

Also, typos in the above code;
    Print #2, fullname         ->    Print #outfile, fullname
    Line input #1, strline     ->    Line Input #infile, strline

bpl5000Author Commented:
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

C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

bpl5000Author Commented:
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!
bpl5000Author Commented:
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
DeadlyTrevCommented:
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.

bpl5000Author Commented:
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."
DeadlyTrevCommented:
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.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.