Home
About me



 VBA Programming
Download my Add-In tool (run on 32-bit MS Office Excel)
VBA Basic for beginners
Excel Main Objects
More with Rows, Columns, Cells, Range ...
Working around your Worksheet ...
Statements
Functions
Conditional Statements and Loops Structure
Errors Handling
UserForms
Pivot Tables
Charting
AutoFilter, Advanced Filter
File I/O VBA Examples
ADO and DAO, integrating Excel and Access
Other VBA fun staff

File I/O In Visual Basic

File Manager Commands
File I/O Commands
File Access via a FileSystemObject
FreeFile(file_number)
The Open Statement
Input #file_num, varlist
Line Input #file_num, strVar
Print #file_number, variable1, variable2, ...
Write #file_num[, output_list]
EOL(file_number) and LOF(file_number)
Opening and Reading a File
The Get Statement
The Input Function
The Put Statement
MRP files EXAMPLES
(Note:  After download, you must unzip the folder to C:\ in order for it to work)

Visual Basic supports 3 types of files - sequential files, random-access files and binary files. Sequential files are mostly text files, and even the numbers are stored as string and not numeric values (for example, 123.4 is stored as a string "123.4"). Sequential files are read from the beginning to the end. Therefore, you can't read and write at the same time to a sequential file. If you must read from and write to the file simultaneously, you must open two sequential files, one for reading from and another one for writing to. If the size of the file is small, you can read all the data into the memory, process them, and open the same file for output and overwrite the old data. However, if you require frequent access to the file's data, you should use random-access files.

Random-access files store text as characters, and numbers are stored in their native format (as integers, single, double, etc). Random-access files are used for storing data that are organized in segments of equal length called records. Random-access files allow you to move to any record. Because all records are of equal length, it is easy to locate any record in the file by its index. Unlike sequential files, random-access files can be opened for reading and writing at the same time. Sequential and random-access file types have a definitive structure, and there are mechanisms built into the language to read and write these files based on that structure. For example, the Input # statement reads a sequential comma-delimited file field-by-field, the Line Input statement reads a sequential file line by line, etc.

On the other hand, it is necessary to process a file in binary mode when that file does not have a simple line-based or record-based structure. For instance, characters, images, contents of an executable file, Excel file, are stored in binary files. If you really want to process an Excel .xls file at a very low level, you could open the file in binary mode and move to certain byte locations within the file to access data contained in the various internal data structures. However, in order to process a file that does not contain simple line-oriented or record-oriented data, the binary mode needs to be used and you must traverse or parse through the file to get at the data that you need.

In the process of handling file, the OS reserves some memory for storing the file's data. A file can be opened for reading from, writing to, or reading and writing at the same time. When the file closed, the OS releases the memory reserved for the file (i.e. using Close statement or the Reset statement to close all open files).


 

File Manager Commands

 
Change Directory ChDir "c:\path"
Make Directory MkDir "c:\path"
Remove Directory RmDir "c:\path"
Change Drive ChDrive "d"
Rename a File Name "test.txt" as "string.tst"
(May fail if directories are not specified)
Delete a File Kill "c:\*.tst"
Search for File temp$ = Dir ("c:\*.tst")
Current Drirectory temp$ = CurDir ("d")    ' Drive letter is optional
Get File Attributes temp = GetAttr ("c:\filename.tst")
Get File Mode temp = FileAttr ("c:\filename.tst", attributes)
Set File Attributes SetAttr "c:\filename.tst", vbReadOnly
Get File Length FileLen ("c:\filename.tst")
Get File Date/Time tempDate = FileDateTime ("c:\filename.tst")
Set File Date/Time ????

Return To Top


Write places strings in double quotes, separates values with commas, and adds a CR/LF pair at the end of each command. Read the data back with Input.

Print does not add extra delimiters, but does concatenate a final CR/LF to each line. The CR/LF can be suppressed by ending the command with a semicolon (;).

Read it back with Line Input. (Line Input assumes a DOS type ASCII input file where each line is terminated with CR/LF. It does not recognize the Unix line termination character.)


Return To Top

File Access via a FileSystemObject

VB 6.0 provides a poorly documented FileSystemObject for File I/O. Help on these commands was found be basically "stumbling" onto them. This is the only File I/O method supported via VBScript. The basic syntax is

      Set fs = CreateObject("Scripting.FileSystemObject")
      Set a = fs.CreateTextFile("c:\mytestfile.txt", True)
      a.WriteLine("This is only a test.")
      a.Close

Return To Top

FreeFile (file_number)

Each file is identified with a unique number, which is assigned to the file the moment it is opened. Because that you open and close many files, and you may not know in advance which numbers are available. Therefore, you can use the FreeFile() function, which returns the next available file number. Use FreeFile() with the Open statement.

      Dim FileNo As Long, LineNo As Long, LineText As String
      FileNo = FreeFile    ' Get next available file number

      Open "c:\mytestfile.txt" For Input Access Read Shared As #FileNo
      Do Until EOF(FileNo)    ' Repeat until end of file...
         Line Input #FileNo, LineText      ' Read a line from the file
         LineNo = LineNo + 1
         Debug.Print Format(LineNo, "00000"); ": "; LineText
         DoEvents   ' Allow Windows to handle other tasks
      Loop
      Close #FileNo

After the above two statements execute, all subsequent commands that operate on the specific file can refer to it as fNum. The FreeFile() returns the next available file number, and unless this number is assigned to a file, FreeFile() returns the same number if called again. Each time you call FreeFile() to get a new file number, you must use it as the following example shows.

      fNum1 = FreeFile()
      Open "c:\mytestfile.txt" For Input As #fNum1
      fNum2 = FreeFile()
      Open "c:\yourtestfile.txt" For Input As #fNum2


Return To Top

The Open Statement 

The full syntax for the Open statement, taken from MSDN, is:

Open pathname For mode [Access access] [lock] As [#]filenumber [Len=reclength]

The Open statement syntax has these parts:

Part

Description

pathname

Required. String expression that specifies a file name — may include directory or folder, and drive.

Input

mode

Required. Keyword specifying the file mode: Append, Binary, Input, Output, or Random. If unspecified, the file is opened for Random access.
Input - File is opened for input (reading from) only.
Output -
File is opened for output (writing to) only.
Append
- File is opened for appending new data to its existing contents.
Random - File is opened for random access (reading or writing one record at a time).
Binary - File is opened in binary mode.

Note:
Input, Output and Append file types refer to sequential files; Random refers to random-access files, and Binary is used with binary files.

access

Optional. Keyword specifying the operations permitted on the open file: Read, Write, or Read Write.

lock

Optional. File-Locking keyword specifying the operations restricted on the open file by other processes: Shared, Lock Read (the file is locked for reading), Lock Write (the file is locked for writing), and Lock Read Write (other applications can't access this file).

filenumber

Required. A valid file number in the range 1 to 511, inclusive. Use the FreeFile function to obtain the next available file number.

reclength

Optional. Number less than or equal to 32,767 (bytes). For files opened for random access, this value is the length of the record in bytes, and you must declare with a Len keyword. The record's length is the sum of the bytes taken by all record fields, and you can use the Len(record) function to calculate it. For sequential files, this value is the number of characters buffered.

You must open a file before any I/O operation can be performed on it. Open allocates a buffer for I/O to the file and determines the mode of access to use with the buffer.
If the file specified by pathname doesn't exist, it is created when a file is opened for Append, Binary, Output, or Random modes.
If the file is already opened by another process and the specified type of access is not allowed, the Open operation fails and an error occurs.

The Len clause is ignored if mode is Binary.

In Binary, Input, and Random modes, you can open a file using a different file number without first closing the file. In Append and Output modes, you must close a file before opening it with a different file number.

' the syntax to open a binary file for input:
Open "c:\mytestfile.txt" For Binary Access Read As #1

' and the syntax to open a binary file for output: 
Open "c:\mytestfile.txt" For Binary Access Write As #1


Return To Top

Input #file_num, varlist

The Input# statement reads data from a sequential file and assigns them to the variables listed in the varlist argument. varlist is a comma-separated list of arguments. In the following example, Input #1 reads two values from the open file, a numeric value and a date:

      Dim numVal as Long, dateVal As Date
      Input #1, numVal, dateVal


Return To Top

Line Input #file_num, strVar

You use the Line Input # statement to read from sequential files. The Line Input statement reads a single line of text from the file and assigns it to a string variable. It reads all the characters from the beginning of the file to the first new character. When you call it again, it returns the following characters, up to the next newline character. The new line characters are not part of the information stored to or read from the file, and they are used only as delimiters.

The file_number argument is the file's number, and strVar is the name of a variable where data read from the file will be stored. The following lines will read the first 2 text lines and assign them to the string variable textLine1 and textLine2.

      Line Input #fNum, textLine1
      Line Input #fNum, textLine2

The following lines write the same data as what the Print # statement will show you in the next example.

      Kill "C:\temp1.txt"
      Open "C:\temp1.txt" For Output As #1
      Write
#1, "Poh Beng William", "Snr Planning Manager", 30
      Write #1, "Irene Zhang", "Planning Manager", 26
      Write #1, "Emily Seng", "Senior Planner", 25
      Write #1, "Josephine Kok", "Planner", 23

Print #file_number, variable1, variable2, ...

The Print statement writes data to a sequential file. The first argument is the number of file to be written, and the subsequent arguments are the variables to be written to the file. After all the variable values have been written to the file, the Print # statement inserts a line break.

The semicolon (;) specifies that the 1st character of the new value will be placed right after the last character of the last value. The comma specifies that the next character will be printed in the next print zone. The Print # statement writes data to the file exactly as the DOS Command displays them on the screen. The Print # statement is used to create text files that can be viewed on a DOS Window. Data saved  with the Print # statement can be read  with the Line Input and Input statement.

The following statements create a text file using the Print # file_number.

      On Error Resume Next
      Kill "C:\temp1.txt"
      Open "C:\temp1.txt" For Output As #1
      Print #1, "[First Name]"; Tab(15); "[Last Name]"; Tab(30); "[Job Position]"; Tab(58); "[Age]"
      Print #1, "Poh Beng"; Tab(15); "William"; Tab(30); "Global Planning Manager"; Tab(58); 30
      Print #1, "Zhang"; Tab(15); "Irene"; Tab(30); "Production Planning Manager"; Tab(58); 26
      Print #1, "Seng"; Tab(15); "Emily"; Tab(30); "Senior Planner"; Tab(58); 25
      Print #1, "Kok"; Tab(15); "Josephne"; Tab(30); "Planner"; Tab(58); 23
      Close #1

This is the output produced by the above statements: 

[First Name] [Last Name]  [Job Position] [Age]
Poh Beng William   Regional Planning Manager 30
Zhang Irene Planning Manager 36
Seng  Emily                Senior Planner 25
Kok Josephine Planner 23

Return To Top

Write #file_num[, output_list

You use the Write # statement to write data to a sequential file. The data to be written is supplied in the output_list, which is a comma-separated list of variables and literals. The following line writes a numeric, a string and a date value to a sequential file:

      Dim numVal as Long, strBuff As String, dateVal As Date

      numVal = 9876543.210
      strBuff = "I love Mother Earth"
      dateVal = #21/12/2012#
      Write #1, numVal, strBuff, dateVal


Return To Top

EOL(file_number) and LOF(file_number)

EOF() function accepts as an argument the number of an open file and returns True if the end of file has been reached. The LOF() function returns the length of the file, whose number is passed as an argument. The code below parses a text file, extract any lines containing the string called "PCBA", and add those lines to a listbox.

DOWNLOAD  (Note: After download, you must unzip the folder to C:\ in order for it to work)

Private Sub CommandButton1_Click()
      Dim dText As String, sLine As String, Filename$
      Dim fNum As Integer

      Filename$ = "c:\vbautomation.110mb.dotcom\MyPartsList.txt"

      If Dir(Filename$) = "" Then Exit Sub
      fNum = FreeFile
       Open Filename$ For Input As #fNum

        While Not EOF(fNum)    
' returns True if it reaches end of file
        Line Input #fNum, sLine
        Debug.Print Seek(1), Left$(sLine, 5)     
 ' Seek statement sets the position for the next read/write operation.
             If (InStr(1, sLine, "PCBA") <> 0) Then
                    ListBox1.AddItem sLine
             End If
        Wend
        Close #fNum   
' this closes the file opened as fNum
End Sub


Return To Top

Opening and Reading a File

When you open a sequential file, you can't change its data. You can either read them, store them to another file, or overwrite the entire file with the new data. To do so, you must open the file for Input, read its data, then close the file. To overwrite the file, open it for Output, and save the data to it. When you open a file for Output, VisualBasic wipes out its entire contents, even if you don't write anything to it. if you don't want to overwrite an existing file but instead to append data to it, open it for Append.

The following command opens the file as a sequential file type with the number 1

Open "c:\CustomerList.txt" For Input As #1

To open a random-access file, you first must know its record's length. The record is the smallest piece of information you can write to a random-access file. To find the length of the record, you must first decide how the data will be organized in fields and then declare the record's type. See below example.

      Private Type MyRecord
          PartNumber As String*13
          Description As String*30
          PO_Date As Date
          Delivered_Date As Date
          Quantities As Integer
      End Type

      ' then declare the record's type
      Dim Mrec as MyRecord

The following statement opens a random-access file for reading from and writing to, using the record structure shown above:

Open "c:\CustomerList.txt" For Random As #1 Len=Len(Mrec)

Below example demonstrates opening and reading a text file, replaces the character ", one line at a time, and print the lines to range A1 in active sheet.
Dim dText As String, TextLine$, Filename$
Dim fNum as Integer

Filename$ = "c:\mytestfile.txt"

If Dir(Filename$) = "" Then Exit Sub      ' Test if the file exists
fNum = FreeFile       ' This is safer than assigning a number, as in Open "C:\myfiletest.txt" For Input As #1
Open Filename$ For Input As #fNum

Do While Not EOF(fNum)           ' Loop until end of file
       Line Input #fNum, TextLine$       ' Read line into variable
       TextLine$ = Replace(TextLine$, Chr$(34), "")        'Chr$(34) is "
       dText = dText & TextLine & vbCrLf 
Loop
Debug.Print dText
ActiveSheet.Cells(1, 1).Value = dText
Close #fNum       ' this closes the file opened as fNum

Note: 
You can also call the Close statement with multiple file numbers, as in Close #fNum1, fNum2, fNum3
You can also use the Reset statement to close all files opened with the Open statement.
Line Input assumes a DOS type ASCII input file where each line is terminated with CR/LF. It does not recognize the Unix line termination character.

Return To Top

The Get Statement

The Get statement is used read data from a file opened in binary mode. The syntax, as it applies to binary files is: 

Get [#]filenumber, [byte position], varname 

The filenumber is any valid filenumber as defined above. 

Byte position is the byte position within the file at which the reading begins. The byte position is "one-based", meaning the first byte position in the file is 1, the second position is 2, and so on. You can omit this entry, in which case the next byte following the last Get or Put statement is read. If you omit the byte position entry, you must still include the delimiting commas in the Get statement, for example: 

Get #intMyFile, , strData 

Varname is a string variable into which the data will be read. This string variable is often referred to as a "buffer" when processing binary files. It is important to note that the length, or size, of this string variable determines how many bytes of data from the file will be read. Thus, it is necessary to set the length of the string variable prior to issuing the Get statement. This is commonly done by using the String$ function to pad the string variable with a number of blank spaces equal to the number of bytes you want to read at a given time. 

For example, the following statement pads the string variable strData with 10,000 blank spaces: 

strData = String$(10000, " ") 

Now that VB "knows" how big "strData" is, the following Get statement will read the first (or next) 10,000 bytes from file number "intMyFile" and overlay strData with that file data: 

Get #intMyFile, , strData 

Depending on the application, it is sometimes necessary to process the file in "chunks". Recall that you can omit the "byte position" entry, in which case VB will "keep track" of where it is in the file. For example, the first time the above Get statement is executed, bytes 1 through 10000 will be read; the second time the above Get statement is executed, bytes 10001 through 20000 will be read; and so on.  

In that a VB string variable can hold in the neighborhood of 2 GB worth of data, it would not be unreasonable in most cases to read in the whole file in "one shot", as opposed to reading it in "chunks" as described above. To do this, you can set the length of the "buffer" string variable to the size of the file using the LOF (length of file) function as the first argument of the String$ function. The LOF function takes the filenumber of the file to be processed as its argument, and returns the length of the file in bytes. Thus, the following statement will fill the variable "strData" with a number of blank spaces equal to the size of the file: 

strData = String$(LOF(intMyFile), " ") 

Then, when the subsequent Get statement is executed, the entire contents of the file will be stored in strData: 

Get #intMyFile, , strData


Return To Top

 The Input Function

The Input function (not to be confused with the Input # or Line Input statements) can be used as an alternative to the Get statement. The syntax is:

varname = Input(number, [#] filenumber

where varname is the string variable into which the file data will be stored, number is the number of characters to be read, and filenumber is a valid filenumber identifying the file from which you want to read. 

The following table contains examples that contrast the Get statement and Input function as ways of reading data from a binary file: 

String Setup and Get Statement

Input Function

 strData = String$(10000, " ")
 Get #intMyFile, , strData
 

 strData = Input(10000, #intMyFile)

 strData = String$(LOF(intMyFile), " ")
 Get #intMyFile, , strData

 strData = Input(LOF(intMyFile), #intMyFile)


Return To Top

 The Put Statement

The Put statement is used write data to a file opened in binary mode. The syntax, as it applies to binary files is: 

Put [#]filenumber, [byte position], varname 

The filenumber is any valid filenumber as defined above. 

Byte position is the byte position within the file at which the writing begins. The byte position is "one-based", meaning the first byte position in the file is 1, the second position is 2, and so on. You can omit this entry, in which case the next byte following the last Get or Put statement is written. If you omit the byte position entry, you must still include the delimiting commas in the Put statement, for example: 

Put #intMyFile, , strData 

Varname is a string variable from which the data will be written. This string variable is often referred to as a "buffer" when processing binary files. It is important to note that the length, or size, of this string variable determines how many bytes of data will be written to the file. 

For example, the following statements cause 1 byte of data to file number "intMyFile": 

strCharacter = Mid$(strData, lngCurrentPos, 1)

Put #intMyFile, , strCharacter 

Recall that you can omit the "byte position" entry, in which case VB will "keep track" of where it is in the file. For example, the first time the above Put statement is executed, byte 1 will be written; the second time the above Put statement is executed, byte 2 will be written; and so on.

Return To Top

free counters
This site was created in Feb.2007
by William Tan