I have a csv file which has a size about 80MB.
When I use Workbooks.open method to open this csv file, it takes me 30 seconds.
However, Excel foramtted the data automatically during file opening. It formats some values like date, currency, etc. And I have no idea how to stop Excel from doing auto formatting....
To avoid this, now I use QueryTable to load a csv file instead.
Nevertheless, it's horribly slow. It took me over 90 seconds to open the same file. I have checked that it takes less than 10 seconds for excel to build a connection with the target file. Besides, I believe that I've already optimize the codes that I am using. (Or maybe not? any suggestion is appreciated)
Is there any other good idea to have excel open a csv file as quick as possible as Workbook.open without formatting it?
Either by improving my sample codes, or giving out a totally different way is acceptable. (This function is a part of a big automation process, so the solution must be using VBA)
By the way, the data in my csv file will certainly contains comma in the value. I need a safe way (without parsing comma by myself) to open the csv file quickly than what I currently have.
I once tried open a big csv file as text, but it cannot distinguish commas in values...
I also appreciate any explanation that why QueryTable takes much more time to open a file than using Workbooks.open...
Public Function ImportCsv(path As Variant, TargetWb As Workbook) As Worksheet
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
TargetWb.Activate
Dim QueryTableName As String
QueryTableName = "tmp_" & Format(Now, "hhmmss") & Right(Format(Timer, "0000"), 4) 'Use time stamp since delete might fail due to unexpected reason.
ActiveWorkbook.Queries.Add Name:=QueryTableName, Formula:= _
"let" & Chr(13) & "" & Chr(10) & " Source= Csv.Document(File.Contents(""" & path & """),[Delimiter="","", Columns=null, Encoding=932, QuoteStyle=QuoteStyle.Csv])," & Chr(13) & "" & Chr(10) & " Transformation = Table.TransformColumnTypes( Source, Table.ToRows(Table.FromColumns({Table.ColumnNames(Source), List.Repeat({type text}, List.Count(Table.ColumnNames(Source)) )})))" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " Transformation"
ActiveWorkbook.Worksheets.Add 'Only ActiveSheet works for some properties of QueryTable.
With ActiveSheet.ListObjects.Add(LinkSource:=False, SourceType:=0, Source:= _
"OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & QueryTableName & ";Extended Properties=""""" _
, Destination:=Range("$A$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = Array("SELECT * FROM [" & QueryTableName & "]")
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = False
.RefreshOnFileOpen = False
.BackgroundQuery = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = False
.AdjustColumnWidth = False
.RefreshPeriod = 0
.PreserveColumnInfo = False
.ListObject.DisplayName = QueryTableName
.ListObject.ShowHeaders = False
.ListObject.ShowTableStyleRowStripes = False
.Refresh BackgroundQuery:=False
.MaintainConnection = False
End With
ActiveSheet.Rows("1:1").Delete Shift:=xlUp 'Remove empty row which was once header.
'ActiveSheet.QueryTables(QueryTableName).Delete 'Delete unneeded TempQueryTable.
Set ImportCsv = ActiveSheet
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Function