ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

VBA: Batch Import from Text Files with Error Handling

VBA (Visual Basic for Applications)

Goal -- WPM

Ready
Exercise Algorithm Area
1Sub BatchImportTextFiles(sourceFolderPath As String, destinationSheetName As String, errorLogSheetName As String)
2' Imports data from multiple text files in a folder to a destination sheet.
3' Appends data and logs errors to a separate sheet.
4' Handles file access, format, and data type errors.
5
6Dim fso As Object ' FileSystemObject
7Dim folder As Object
8Dim file As Object
9Dim ts As Object ' TextStream
10Dim wsDest As Worksheet
11Dim wsErrorLog As Worksheet
12Dim lastDestRow As Long
13Dim lastErrorRow As Long
14Dim lineNum As Long
15Dim fileNum As Long
16Dim lineData() As String
17Dim importError As Boolean
18Dim errorDescription As String
19Dim headerRow As String
20Dim fileCounter As Integer
21
22' --- Initialization and Setup ---
23On Error GoTo ErrorHandler
24
25' Create FileSystemObject
26Set fso = CreateObject("Scripting.FileSystemObject")
27
28' Validate source folder
29If Not fso.FolderExists(sourceFolderPath) Then
30Err.Raise vbObjectError + 2001, "BatchImportTextFiles", "Source folder not found: " & sourceFolderPath
31End If
32Set folder = fso.GetFolder(sourceFolderPath)
33
34' Get destination worksheet, create if it doesn't exist
35On Error Resume Next
36Set wsDest = ThisWorkbook.Sheets(destinationSheetName)
37On Error GoTo ErrorHandler
38If wsDest Is Nothing Then
39Set wsDest = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
40wsDest.Name = destinationSheetName
41' Add header row if new sheet
42wsDest.Cells(1, 1).Value = "FileName"
43wsDest.Cells(1, 2).Value = "LineNumber"
44wsDest.Cells(1, 3).Value = "ErrorDescription"
45wsDest.Cells(1, 4).Value = "OriginalLine"
46lastDestRow = 1 ' Start appending from row 2
47Else
48lastDestRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Row
49If lastDestRow = 1 And IsEmpty(wsDest.Cells(1, 1).Value) Then ' Handle case where sheet exists but is empty
50wsDest.Cells(1, 1).Value = "FileName"
51wsDest.Cells(1, 2).Value = "LineNumber"
52wsDest.Cells(1, 3).Value = "ErrorDescription"
53wsDest.Cells(1, 4).Value = "OriginalLine"
54lastDestRow = 1
55End If
56End If
57
58' Get error log worksheet, create if it doesn't exist
59On Error Resume Next
60Set wsErrorLog = ThisWorkbook.Sheets(errorLogSheetName)
61On Error GoTo ErrorHandler
62If wsErrorLog Is Nothing Then
63Set wsErrorLog = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
64wsErrorLog.Name = errorLogSheetName
65' Add header row for error log
66wsErrorLog.Cells(1, 1).Value = "FileName"
67wsErrorLog.Cells(1, 2).Value = "LineNumber"
68wsErrorLog.Cells(1, 3).Value = "ErrorDescription"
69wsErrorLog.Cells(1, 4).Value = "OriginalLine"
70lastErrorRow = 1
71Else
72lastErrorRow = wsErrorLog.Cells(wsErrorLog.Rows.Count, "A").End(xlUp).Row
73If lastErrorRow = 1 And IsEmpty(wsErrorLog.Cells(1, 1).Value) Then ' Handle case where sheet exists but is empty
74wsErrorLog.Cells(1, 1).Value = "FileName"
75wsErrorLog.Cells(1, 2).Value = "LineNumber"
76wsErrorLog.Cells(1, 3).Value = "ErrorDescription"
77wsErrorLog.Cells(1, 4).Value = "OriginalLine"
78lastErrorRow = 1
79End If
80End If
81
82' --- File Processing Loop ---
83Application.ScreenUpdating = False
84Application.EnableEvents = False ' Prevent worksheet events
85Application.Calculation = xlCalculationManual
86
87fileCounter = 0
88For Each file In folder.Files
89' Process only text files (e.g., .txt, .csv)
90If LCase(fso.GetExtensionName(file.Name)) = "txt" Or LCase(fso.GetExtensionName(file.Name)) = "csv" Then
91fileCounter = fileCounter + 1
92lineNum = 0
93importError = False
94errorDescription = ""
95
96' Get a free file number
97fileNum = FreeFile
98
99On Error Resume Next ' Handle file open/read errors
100Set ts = fso.OpenTextFile(file.Path, 1) ' 1 for reading
101If Err.Number <> 0 Then
102importError = True
103errorDescription = "Error opening file: " & Err.Description
104GoTo LogError
105End If
106On Error GoTo ErrorHandler ' Reset to main error handler
107
108' Read file line by line
109Do While Not ts.AtEndOfStream
110lineNum = lineNum + 1
111Dim originalLine As String
112originalLine = ts.ReadLine
113
114' Attempt to parse and import the line
115On Error Resume Next ' Handle parsing/data type errors
116lineData = Split(originalLine, ",") ' Assuming comma-separated values
117If Err.Number <> 0 Then
118importError = True
119errorDescription = "Error splitting line: " & Err.Description
120GoTo LogError
121End If
122
123' Basic check for expected number of columns (adjust delimiter if needed)
124' This is a simplified check; more robust validation might be needed
125If UBound(lineData) < 0 Then ' Empty line or parsing issue
126If Trim(originalLine) <> "" Then ' If not just an empty line
127importError = True
128errorDescription = "Line appears malformed or empty after split."
129GoTo LogError
130End If
131Else
132' Append data to destination sheet
133lastDestRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Row + 1
134wsDest.Cells(lastDestRow, 1).Value = file.Name ' Store filename
135wsDest.Cells(lastDestRow, 2).Value = lineNum ' Store line number
136wsDest.Cells(lastDestRow, 3).Value = "Success"
137wsDest.Cells(lastDestRow, 4).Value = originalLine ' Store original line for reference
138
139' Populate actual data columns
140Dim colIndex As Integer
141For colIndex = 0 To UBound(lineData)
142' Ensure destination column exists, expand if necessary
143If wsDest.Cells(1, 5 + colIndex).Value = "" Then
144wsDest.Cells(1, 5 + colIndex).Value = "Col " & (colIndex + 1) ' Auto-generate header
145End If
146wsDest.Cells(lastDestRow, 5 + colIndex).Value = Trim(lineData(colIndex))
147Next colIndex
148End If
149On Error GoTo ErrorHandler ' Reset to main error handler
150
151Loop
152ts.Close
153End If
154Next file
155
156' --- Finalization ---
157Application.ScreenUpdating = True
158Application.EnableEvents = True
159Application.Calculation = xlCalculationAutomatic
160
161If fileCounter = 0 Then
162MsgBox "No text files (.txt or .csv) found in the specified folder.", vbExclamation
163ElseIf lastErrorRow > 1 Then ' Check if any errors were logged
164MsgBox "Batch import completed with errors. Please check the '" & errorLogSheetName & "' sheet.", vbExclamation
165Else
166MsgBox "Batch import completed successfully.", vbInformation
167End If
168
169Exit Sub
170
171LogError:
172' Log the error to the error log sheet
173lastErrorRow = wsErrorLog.Cells(wsErrorLog.Rows.Count, "A").End(xlUp).Row + 1
174wsErrorLog.Cells(lastErrorRow, 1).Value = file.Name
175wsErrorLog.Cells(lastErrorRow, 2).Value = lineNum
176wsErrorLog.Cells(lastErrorRow, 3).Value = errorDescription
177wsErrorLog.Cells(lastErrorRow, 4).Value = originalLine
178
179' If error occurred during file open, mark it
180If ts Is Nothing Then ' Error opening file
181' No 'originalLine' to log in this specific case, but we have file name and error desc
182Else
183ts.Close ' Ensure stream is closed if opened
184End If
185importError = True ' Flag that an error occurred for this file/line
186GoTo ContinueProcessing ' Continue to next file/line if possible
187
188ContinueProcessing:
189If Not ts Is Nothing Then
190If Not ts.AtEndOfStream Then ' If not end of stream, try to continue reading
191Resume Next ' Attempt to continue reading from the current file
192Else
193ts.Close
194End If
195End If
196GoTo SkipMainErrorHandler ' Prevent main handler from firing if we handled it
197
198ErrorHandler:
199Application.ScreenUpdating = True
200Application.EnableEvents = True
201Application.Calculation = xlCalculationAutomatic
202
203If Not ts Is Nothing Then ts.Close ' Ensure file is closed
204
205If Err.Number = vbObjectError + 2001 Then ' Specific folder not found error
206MsgBox Err.Description, vbCritical
207ElseIf importError Then ' Error logged in LogError section
208' Message already displayed or handled by LogError logic
209' If we reached here due to an unhandled error after LogError, show it
210If Err.Number <> 0 Then
211MsgBox "An unhandled error occurred during processing: " & Err.Description & " (Error " & Err.Number & ")", vbCritical
212End If
213Else ' General unexpected error
214MsgBox "An unexpected error occurred: " & Err.Description & " (Error " & Err.Number & ")", vbCritical
215End If
216On Error GoTo 0 ' Reset error handling
217
218SkipMainErrorHandler:
219
220End Sub
Algorithm description viewbox

VBA: Batch Import from Text Files with Error Handling

Algorithm description:

This VBA macro facilitates the batch import of data from multiple text files (like .txt or .csv) residing in a specified folder into a single Excel worksheet. It intelligently appends data from each file, creating new columns as needed, and meticulously logs any import errors (file access, formatting, data type issues) to a dedicated error log sheet. This is crucial for processing large volumes of structured data from external sources reliably.

Algorithm explanation:

The `BatchImportTextFiles` subroutine orchestrates the import process. It utilizes `FileSystemObject` to navigate and read files from a `sourceFolderPath`. It sets up two worksheets: `wsDest` for imported data and `wsErrorLog` for recording issues, creating them if they don't exist and ensuring they have appropriate headers. The macro iterates through each `file` in the `folder`. For text files (`.txt`, `.csv`), it opens them using `OpenTextFile` and reads them line by line. Each line is split (assuming comma delimiter, which can be customized) into `lineData`. Data is appended to `wsDest`, with filenames, line numbers, and original lines logged for traceability. If a line cannot be split or processed correctly, an error is logged in `wsErrorLog` with details including the filename, line number, error description, and the original line content. `Application.ScreenUpdating`, `Application.EnableEvents`, and `Application.Calculation` are managed for performance. The `LogError` label handles specific error logging, allowing the macro to potentially continue processing other files or lines. The main `ErrorHandler` catches broader issues like folder not found or unhandled exceptions. Time complexity is roughly O(F * L * C), where F is the number of files, L is the average number of lines per file, and C is the average number of columns per line, due to reading and processing each piece of data. Space complexity is O(L_max * C_max) for storing a single line's data and O(E * 4) for the error log, where E is the number of errors. Edge cases include missing source folder, non-existent destination/error sheets, empty files, malformed lines, incorrect delimiters, and data type mismatches.

Pseudocode:

SUB BatchImportTextFiles(sourceFolderPath, destinationSheetName, errorLogSheetName)
  INITIALIZE FileSystemObject
  VALIDATE sourceFolderPath
  GET folder object

  GET or CREATE destinationSheet
  IF destinationSheet is new THEN ADD headers (FileName, LineNumber, ErrorDesc, OriginalLine)
  GET lastDestRow

  GET or CREATE errorLogSheet
  IF errorLogSheet is new THEN ADD headers (FileName, LineNumber, ErrorDesc, OriginalLine)
  GET lastErrorRow

  DISABLE screen updating, events, set calculation to manual

  FOR EACH file IN folder.Files DO
    IF file is a text file (.txt or .csv) THEN
      SET lineNum = 0, importError = FALSE, errorDescription = ""
      GET free file number
      TRY to OPEN file for reading
      IF error opening file THEN
        importError = TRUE
        errorDescription = "Error opening file: " & Err.Description
        GOTO LogError
      END IF

      WHILE NOT end of file stream DO
        lineNum = lineNum + 1
        READ originalLine from file

        TRY to SPLIT originalLine by delimiter (e.g., comma)
        IF error splitting THEN
          importError = TRUE
          errorDescription = "Error splitting line: " & Err.Description
          GOTO LogError
        END IF

        IF line is valid (e.g., not empty after split) THEN
          INCREMENT lastDestRow
          WRITE file.Name to wsDest(lastDestRow, 1)
          WRITE lineNum to wsDest(lastDestRow, 2)
          WRITE "Success" to wsDest(lastDestRow, 3)
          WRITE originalLine to wsDest(lastDestRow, 4)
          FOR EACH data element in split line DO
            IF destination column header doesn't exist THEN CREATE it
            WRITE data element to wsDest(lastDestRow, corresponding column)
          END FOR
        ELSE IF originalLine is not empty THEN
          importError = TRUE
          errorDescription = "Malformed or empty line after split."
          GOTO LogError
        END IF
      END WHILE
      CLOSE file stream
    END IF
  END FOR

  ENABLE screen updating, events, set calculation to automatic

  IF no text files found THEN DISPLAY message
  ELSE IF errors were logged THEN DISPLAY error summary message
  ELSE DISPLAY success message

  EXIT SUB

LogError:
  INCREMENT lastErrorRow
  WRITE file.Name to wsErrorLog(lastErrorRow, 1)
  WRITE lineNum to wsErrorLog(lastErrorRow, 2)
  WRITE errorDescription to wsErrorLog(lastErrorRow, 3)
  WRITE originalLine to wsErrorLog(lastErrorRow, 4)
  IF file stream is open THEN CLOSE it
  SET importError = TRUE
  GOTO ContinueProcessing

ContinueProcessing:
  IF file stream is not at end THEN Resume Next to continue reading current file
  ELSE CLOSE file stream
  GOTO SkipMainErrorHandler

ErrorHandler:
  ENABLE screen updating, events, set calculation to automatic
  IF file stream is open THEN CLOSE it
  DISPLAY appropriate error message based on Err.Number
  RESET error handling

SkipMainErrorHandler:
END SUB