The New Kid: TextFieldParser
After the 'Training the Trainer' class and after my own work with VB 2005 Beta 2, I look forward to this fall's class and VB 2005. The My object gives me back a way to use file I/O easily in my class. Let's discuss this TextFieldParser, a component within the My object. Let's see how a new object in VB 2005 can solve our problems.
How did we associate a record field with a label's caption in VB 6? First, we associated an opened file with a file number.
In contrast to cryptic numbers, just what will VB 2005 give us? Let's open the file C:\students.txt:
Using MyReader As New _ Microsoft.VisualBasic.FileIO.TextFieldParser ("C:\students.txt")
So now we have a file handle named MyReader. The old VB 6 version naturally assumed that the comma was the delimiter. The help page states it plainly when it defines varlist as follows: Comma-delimited list of variables that are assigned values read from the file.
What if a field includes a comma? Some of us placed the data in quotation marks. Sometimes that worked. VB 2005 is more versatile; it allows you to write or read a file to or from disk with any character as delimiter. Have an old file that uses tabs, ampersands, or @ signs? You can use the text parser with it. How difficult is it to define the parser delimiter?
MyReader.TextFieldType = FileIO.FieldType.Delimited MyReader.SetDelimiters(",")
So that seems simple enough and very logical. You let MyReader know that the text fields are delimited and that the delimiter is a comma. So far this is a breeze, and gives us much more flexibility when working with organizational files put together with all kinds of delimiters. What's more, we do it once instead of calling the split function each time we grab a record.
Now that we know how to parse each record for the fields, we need to place the fields into label captions. Our processing will need to check whether we're at the end of the file and, if not, get a line and make fields of it. For this example, let's assume that the fields are name, ID number, and birth date.
Let's examine my sample code carefully. In this section, I create and use a loop index to show that loops are very usable with the field parser. We'll enter the processing with a while loop that will check for the EOF (end of file):
Dim index As Integer = 0 While Not MyReader.EndOfData Try currentRow = MyReader.ReadFields()
The try command takes us into robust error-detection in VB 2005. C coders will be very familiar with the syntax, and long-time VB 6 coders will welcome the accurate error reporting.
The first thing we do is call the ReadFields() function within MyReader to put the fields into an array. I know, this is very much like the old split functionality I rejected for complexity. In my opinion, this tool is cleaner, because it doesn't need continuing calls to split, to call out the delimiter, etc. But this is the good thing with Visual Basic .NET—there are plenty of accommodating ways to get the job done. Overall, I think you'll agree that this example is cleaner than implementing the split function within the loop.
Okay, we have our little loop that shows off each part of the record in a message box. Now we know that we're successfully parsing fields, after doing little more than declaring the delimiter and writing one line of coding. After each field is displayed, we have the straightforward assignment of a string to the text property of a text box. Hmm, it looks as if I'll have to go into arrays a little bit, if only to explain the concept zero-based.
For index = 0 To 2 MsgBox(currentRow(index)) Next txtName.Text = currentRow(0) txtID.Text = currentRow(1) txtBdate.Text = currentRow(2)
Overall, nice error checking that provides excellent feedback at the point of error—that's a big plus. With VB 2005, we have error reporting that can return excellent information on malformed lines. File corruption, inept editing, weird star alignments—all corrupt a file into being bad for your application.
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException MsgBox("Line " & ex.Message & _ "is not valid and will be skipped.") End Try End While
After all this time, we can parse our records cleanly and set those values into the textbox quickly!
Figure 1 shows the test application at work. The application is displaying the first field of the next record, after displaying the previous record in the text boxes. The figure illustrates the importance of good interfaces, by supplying my students really ugly interfaces. I like to use a really bad shade of orange as a background, along with a woeful lack of menus. This sort of shock treatment triggers great discussions on interface needs and specifics. From here, we can talk about what works in nicely designed applications. Why, in my view, the best demonstration applications look as if they were coded with a stick and clay tablet. Applying boring, unexciting application names is another sure way to make people avoid wanting to use an application.
Figure 1 Parsing fields and records easily.