How do I get errors only for the files that error out - vba

At my company we need to convert a lot of text files each month to excel and some of the columns we need to change the data types of the columns. They used to convert all of them manually which was very time consuming. I created an access program that they can do it in much easier. They just hit a button and it transfers them, with a running list of all the files converted. Some of the files will change here and there, so when running the program I have another list that is supposed to show all the files that cause an error. Unfortunately, what it does, at the moment, once it receives the error from one file - every file after that also says there is an error. So if there are 100 files witch file 5 and 25 as errors, it would still show all files from 5 to 100 are errors. Here is the code I am using:
Public Sub ImportTextFile(ByVal xl As Excel.Application, ByVal strFileName As String, ByVal iNumOfCols As Integer, Optional aDataTypes As Variant = Nothing)
On Error GoTo Sub_Err
Dim sPathAndFile As String: sPathAndFile = cPath & strFileName
Dim wb As Workbook: Set wb = xl.Workbooks.Add
Dim ws As Worksheet: Set ws = wb.Sheets(1)
With ws.QueryTables.Add(Connection:="TEXT;" & sPathAndFile & ".txt", Destination:=ws.Range("$A$1"))
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SaveData = True
.AdjustColumnWidth = False
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = GetColumnDataTypes(iNumOfCols, aDataTypes)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
Call SaveFile(wb, sPathAndFile)
Forms("Dashboard").lbCompleted.AddItem strFileName
Forms("Dashboard").lbCompleted.Selected(Forms("Dashboard").lbCompleted.ListCount - 1) = True
Sub_End:
Set wb = Nothing
Set ws = Nothing
Err.Clear
Exit Sub
Sub_Err:
'MsgBox Err.Description
Forms("Dashboard").lbError.AddItem strFileName
Resume Sub_End
End Sub
and then each file calls back like this:
Call ImportTextFile(xl, "DGXC094P", 11)
Call ImportTextFile(xl, "DGAC081", 18, Array(, , , , , , , , , , , , , , , , , , 2))
I tried clearing the error but it doesn't clear. What am I doing wrong? How can I get it to show only the files that have errors?

Concerning the Sub to import the Textfile: Make it a function. Then you are able to give a callback if there was an error or not. Like this:
Public Function ImportTextFile(ByVal xl As Excel.Application, ByVal strFileName As String, ByVal iNumOfCols As Integer, Optional aDataTypes As Variant = Nothing) as string
On Error GoTo ErrorHandling
Dim sPathAndFile As String: sPathAndFile = cPath & strFileName
Dim wb As Workbook: Set wb = xl.Workbooks.Add
Dim ws As Worksheet: Set ws = wb.Sheets(1)
With ws.QueryTables.Add(Connection:="TEXT;" & sPathAndFile & ".txt", Destination:=ws.Range("$A$1"))
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SaveData = True
.AdjustColumnWidth = False
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = GetColumnDataTypes(iNumOfCols, aDataTypes)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
Call SaveFile(wb, sPathAndFile)
Forms("Dashboard").lbCompleted.AddItem strFileName
Forms("Dashboard").lbCompleted.Selected(Forms("Dashboard").lbCompleted.ListCount - 1) = True
Set wb = Nothing
Set ws = Nothing
ImportTextFile = "ok"
Exit Function
ErrorHandling:
Set wb = Nothing
Set ws = Nothing
ImportTextFile = Err.Description
End Function
Your procedure to call the function should look like this:
Dim ImportResult as string
ImportResult = ImportTextFile(xl, "DGAC081", 18, Array(, , , , , , , , , , , , , , , , , , 2))
'Case Import Error
If ImportResult <> "ok" then
MsgBox (ImportResult)
Forms("Dashboard").lbError.AddItem strFileName
end if
'Case Import OK
If ImportResult = "ok" then
'What you want
end if
When using a function instead of a sub you will be able to treat each import individually.

Related

Excel Macro: Import specific CSV-file instead of selecting it

I use the following Macro to import a CSV-file into Excel.
The Macro itself works fine, but when I start the Macro, I always have to select which CSV-file I want to import (a file selection dialog appears).
Is there a way to automatically select C:\test\testfile.csv instead of the file selection dialog?
Thank you!
Sub GetCSVList()
Dim dlgOpen As FileDialog
Set dlgOpen = Application.FileDialog(msoFileDialogFilePicker)
Application.DisplayAlerts = False
On Error Resume Next
Worksheets("Tickets").Delete
On Error GoTo 0
Application.DisplayAlerts = True
With dlgOpen
.AllowMultiSelect = False
''Start in
.InitialFileName = "C:\test"
.Show
End With
For Each fname In dlgOpen.SelectedItems
ImportCSV fname
Next
End Sub
Sub ImportCSV(fname)
Set ws = Worksheets.Add(after:=Worksheets(Worksheets.Count))
ws.Name = "Tickets"
With ws.QueryTables.Add( _
Connection:="TEXT;" & fname, _
Destination:=Range("A1"))
.Name = "Test" & Worksheets.Count + 1
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.TextFilePromptOnRefresh = False
.TextFilePlatform = 65001
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.Refresh BackgroundQuery:=False
'.UseListObject = False
End With
End Sub
Something along the lines of the following where you don't open the dialog picker and instead open by using the filepath?
Sub GetCSVList()
' Dim dlgOpen As FileDialog
' Set dlgOpen = Application.FileDialog(msoFileDialogFilePicker)
Dim filepath As String
filepath = "C:\test\testfile.csv"
Application.DisplayAlerts = False
On Error Resume Next
Worksheets("Tickets").Delete
On Error GoTo 0
Application.DisplayAlerts = True
' With dlgOpen
' .AllowMultiSelect = False
' ''Start in
' .InitialFileName = "C:\test"
' .Show
'End With
'For Each fname In dlgOpen.SelectedItems
ImportCSV filepath
'Next
End Sub
change your GetCSVList sub ....
Sub GetCSVList()
Application.DisplayAlerts = False
On Error Resume Next
Worksheets("Tickets").Delete
On Error GoTo 0
Application.DisplayAlerts = True
ImportCSV "C:\test\testfile.csv"
End Sub

How to load CSV in a workbook replacing existing sheet?

I have the following Macro which imports a CSV-file as a new sheet which is called "Tickets". When this file aready exists, I get a runtime-error. Is there a way to just overwrite the existing file if it already exists?
Sub GetCSVList()
Dim dlgOpen As FileDialog
Set dlgOpen = Application.FileDialog(msoFileDialogFilePicker)
With dlgOpen
.AllowMultiSelect = False
''Start in
.InitialFileName = "C:\test"
.Show
End With
For Each fname In dlgOpen.SelectedItems
ImportCSV fname
Next
End Sub
Sub ImportCSV(fname)
Set ws = Worksheets.Add(after:=Worksheets(Worksheets.Count))
ws.Name = "Tickets"
With ws.QueryTables.Add( _
Connection:="TEXT;" & fname, _
Destination:=Range("A1"))
.Name = "Test" & Worksheets.Count + 1
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.TextFilePromptOnRefresh = False
.TextFilePlatform = 65001
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.Refresh BackgroundQuery:=False
'.UseListObject = False
End With
End Sub
After adding a new worksheet at the end, try to delete any existing worksheet named "Tickets" before renaming the new worksheet to "Tickets":
Application.DisplayAlerts = False
On Error Resume Next
Worksheets("Tickets").Delete
On Error GoTo 0
Application.DisplayAlerts = True
On Error Resume Next will ignore the error that would arise if there aren't any existing worksheets named "Tickets". This is a little lazy, but that's pretty much the only error that will arise from the Worksheet.Delete method, so you can get away it.
Do not "On Error Resume Next" to just ignore other types of errors in programming!

Set file origin when Importing text files to excel with VBA

I'm working with a VBA code to import TEXT files from a folder to excel workbooks.
My text file contains non-English encoding/origin and I want to import the file with 1253 Greek windows encoding but can't figure out how to add the origin:="1253" (if i'm right) in this code:
Sub LoadPipeDelimitedFiles()
'UpdatebyKutoolsforExcel20151214
Dim xStrPath As String
Dim xFileDialog As FileDialog
Dim xFile As String
Dim xCount As Long
On Error GoTo ErrHandler
Set xFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
xFileDialog.AllowMultiSelect = False
xFileDialog.Title = "Select a folder [Kutools for Excel]"
If xFileDialog.Show = -1 Then
xStrPath = xFileDialog.SelectedItems(1)
End If
If xStrPath = "" Then Exit Sub
Application.ScreenUpdating = False
xFile = Dir(xStrPath & "\*.txt")
Do While xFile <> ""
xCount = xCount + 1
Sheets(xCount).Select
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" _
& xStrPath & "\" & xFile, Destination:=Range("A1"))
.Name = "a" & xCount
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileOtherDelimiter = "|"
.TextFileColumnDataTypes = Array(1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
xFile = Dir
End With
Loop
Application.ScreenUpdating = True
Exit Sub
ErrHandler:
MsgBox "no files txt", , "Kutools for Excel"
End Sub
I guess I was in a rush...
Here is the answer:
.TextFilePlatform = 1253

Want to import bits (a couple of rows) of an .txt to excel

Hey so i found a specific query to import a file into excel from a specific row and delete the following datga each time you open it again. but is it also pssible to stop adding rows at a specific line? and is it possible to leave some rows out if there for example is a specific word in that line?
Sub Sample()
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;C:\Users\sample.txt", Destination:=Range("$A$1") _
)
.Name = "Sample"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
You can do it, but not with a Querytable.
Try this code:
Private Sub Open_Click()
Dim fn As Variant, myLine As Long, txt As String, x As Variant, ouput As String
Dim i As Integer, j As Integer: j = 1
Dim sht As Worksheet
Set sht = Worksheets("Sheet1") 'Modify Sheet Name
fn = Application.GetOpenFilename("Text Files (*.txt),*.txt", , _
"Open File")
If fn = False Then Exit Sub
txt = CreateObject("Scripting.FileSystemObject").OpenTextFile(fn).ReadAll
x = Split(txt, vbNewLine)
For i = 0 To UBound(x)
If x(i) <> "SomeCriteria" Then 'Check for some criteria
sht.Cells(j, 1).Value = x(i)
j = j + 1
End If
Next i
End Sub
So what it does basically, it opens a user selected txt file and stores it in the variable txt. Do seperate the rows you can use the split-function. Now each line is stored in an array x. You could go trough the array/each line and take out the ones you want. To check if a specific word is in a line, use the InStr-function.

Importing multiple CSV to multiple worksheet in a single workbook

How do I do this? Basically I want my multiple CSV files to be imported to multiple worksheet but in a single workbook only. Here's my VBA code that I want to loop. I need the loop to query all the CSV in C:\test\
Sub Macro()
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;C:\test\test1.csv", Destination:=Range("$A$1"))
.Name = "test1"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
Sheets.Add After:=Sheets(Sheets.Count)
End Sub
This guy absolutely nailed it. Very concise code and works perfectly for me on 2010. All credit goes to him (Jerry Beaucaire). I found it from a forum here.
Option Explicit
Sub ImportCSVs()
'Author: Jerry Beaucaire
'Date: 8/16/2010
'Summary: Import all CSV files from a folder into separate sheets
' named for the CSV filenames
'Update: 2/8/2013 Macro replaces existing sheets if they already exist in master workbook
Dim fPath As String
Dim fCSV As String
Dim wbCSV As Workbook
Dim wbMST As Workbook
Set wbMST = ThisWorkbook
fPath = "C:\test\" 'path to CSV files, include the final \
Application.ScreenUpdating = False 'speed up macro
Application.DisplayAlerts = False 'no error messages, take default answers
fCSV = Dir(fPath & "*.csv") 'start the CSV file listing
On Error Resume Next
Do While Len(fCSV) > 0
Set wbCSV = Workbooks.Open(fPath & fCSV) 'open a CSV file
wbMST.Sheets(ActiveSheet.Name).Delete 'delete sheet if it exists
ActiveSheet.Move After:=wbMST.Sheets(wbMST.Sheets.Count) 'move new sheet into Mstr
Columns.Autofit 'clean up display
fCSV = Dir 'ready next CSV
Loop
Application.ScreenUpdating = True
Set wbCSV = Nothing
End Sub
Beware, this does not handles errors like you would have a duplicate sheet name if you imported a csv.
This uses early binding so you need to Reference Microsoft.Scripting.Runtime under Tools..References in the VBE
Dim fs As New FileSystemObject
Dim fo As Folder
Dim fi As File
Dim wb As Workbook
Dim ws As Worksheet
Dim sname As String
Sub loadall()
Set wb = ThisWorkbook
Set fo = fs.GetFolder("C:\TEMP\")
For Each fi In fo.Files
If UCase(Right(fi.name, 4)) = ".CSV" Then
sname = Replace(Replace(fi.name, ":", "_"), "\", "-")
Set ws = wb.Sheets.Add
ws.name = sname
Call yourRecordedLoaderModified(fi.Path, ws)
End If
Next
End Sub
Sub yourRecordedLoaderModified(what As String, where As Worksheet)
With ws.QueryTables.Add(Connection:= _
"TEXT;" & what, Destination:=Range("$A$1"))
.name = "test1"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
Sheets.Add After:=Sheets(Sheets.Count)
End Sub
You can use Dir to filter out and run with just the csv files
Sub MacroLoop()
Dim strFile As String
Dim ws As Worksheet
strFile = Dir("c:\test\*.csv")
Do While strFile <> vbNullString
Set ws = Sheets.Add
With ws.QueryTables.Add(Connection:= _
"TEXT;" & "C:\test\" & strFile, Destination:=Range("$A$1"))
.Name = strFile
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
strFile = Dir
Loop
End Sub
I had 183 csv files to condense into one workbook, one worksheet per csv file to facilitate analysis of the data and did not want to manually do this one at a time. I tried the highest rated solution on this question but had the same problem as another user; the csv files would open, but nothing would be inserted to the target workbook. I spent some time and adjusted the code so that it works as in Excel 2016. I haven't tested on older versions. I have not coded in Visual Basic in ages so there's probably a ton of room for improvement in my code, but it worked for me in a pinch. In case anyone happens to stumble upon this question as I did, I'm pasting the code I used below.
Option Explicit
Sub ImportCSVs()
'Author: Jerry Beaucaire
'Date: 8/16/2010
'Summary: Import all CSV files from a folder into separate sheets
' named for the CSV filenames
'Update: 2/8/2013 Macro replaces existing sheets if they already exist in master workbook
'Update: base script as seen in: https://sites.google.com/a/madrocketscientist.com/jerrybeaucaires-excelassistant/merge-functions/csvs-to-sheets
'Update: adjusted code to work in Excel 2016
Dim fPath As String
Dim fCSV As String
Dim wbName As String
Dim wbCSV As Workbook
Dim wbMST As Workbook
wbName = "this is a string"
Set wbMST = ThisWorkbook
fPath = "C:\pathOfCSVFiles\" 'path to CSV files, include the final \
Application.ScreenUpdating = False 'speed up macro
Application.DisplayAlerts = False 'no error messages, take default answers
fCSV = Dir(fPath & "*.csv") 'start the CSV file listing
On Error Resume Next
Do While Len(fCSV) > 0
Set wbCSV = Workbooks.Open(fPath & fCSV) 'open a CSV file
If wbName = "this is a string" Then 'this is to check if we are just starting out and target workbook only has default Sheet 1
wbCSV.Sheets.Copy After:=wbMST.Sheets(1) 'for first pass, can leave as is. if loading a large number of csv files and excel crashes midway, update this to the last csv that was loaded to the target workbook
Else
wbCSV.Sheets.Copy After:=wbMST.Sheets(wbName) 'if not first pass, then insert csv after last one
End If
fCSV = Dir 'ready next CSV
wbName = ActiveSheet.Name 'save name of csv loaded in this pass, to be used in the next pass
Loop
Application.ScreenUpdating = True
Set wbCSV = Nothing
End Sub
I didn't try this, but I'd go with this:
Dim NumFound As Long
With Application.FileSearch
.NewSearch
.LookIn = "C:\test\"
.FileName = "*.csv"
If .Execute() > 0 Then
For i = 1 To .FoundFiles.Count
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & "C:\test\" & (Application.FileSearch.FoundFiles(i)), Destination:=Range("$A$1"))
...
End With
Sheets.Add After:=Sheets(Sheets.Count)
Next i
End If
End With