Workbooks.OpenText 未正确解析 csv 文件 Excel 2016
Workbooks.OpenText not parsing csv files properly Excel 2016
我很确定这在以前的 Excel
版本中工作正常
测试文件:
d/mm/yyyy hh:mm:ss
5/12/1999 6:01:12
30/11/2001 5:00:00
并且日期和时间之间的分隔符是一个Space(ASCII码32)
如果文件另存为 .txt
文件,OpenText 方法会正确解析。
如果文件保存为.csv
文件,OpenText方法似乎根本不起作用
如果空格替换为逗号,并且文件另存为 .csv
文件,OpenText 方法会将行分成两列,但不会正确解释日期字符串.
我的 Windows 区域设置是 mdy,我的 Excel 版本是 2016
Option Explicit
Sub foo()
Dim WB As Workbook
Dim sFN As String
Dim FD As FileDialog
Set FD = Application.FileDialog(msoFileDialogFilePicker)
With FD
.AllowMultiSelect = False
.Filters.Add "Text or CSV", "*.txt, *.csv", 1
.Show
sFN = .SelectedItems(1)
End With
Workbooks.OpenText Filename:=sFN, DataType:=xlDelimited, origin:=437, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=True, Other:=False, _
FieldInfo:=Array(Array(1, xlDMYFormat), Array(2, xlGeneralFormat))
Set WB = ActiveWorkbook
End Sub
看来这可能与此线程中解决的问题相同:
CSV files are Character Separated Value files, not Comma separated.
For more than half the world the separator character is semicolon (;),
not a comma (,)
Excel 2016 properly respects your Windows regional settings, and uses
the specified "List separator" character
One solution is to change your regional settings for the "List
separator" attribute to the character you want Excel to default to
using, e.g. a comma (,)
This can be changed in:
Control Panel / Region / Additional Settings / List separator:
CSV
和 Text
实际上 与 Excel
不同 。不仅 CSV
的定界符设置非常特殊,而且 不能 使用 Workbooks.OpenText
中的参数设置。打开 CSV
文件时,也不会考虑字段类型 (FieldInfo
) 等其他参数。而且 unicode 处理对于 CSV
来说是一个非常特殊的情况,并且与 Text
.
有明显的不同
您可以像这样尝试使用 QueryTables
:
Sub foo1()
Dim WB As Workbook
Dim sFN As String
Dim FD As FileDialog
Set FD = Application.FileDialog(msoFileDialogFilePicker)
With FD
.AllowMultiSelect = False
.Filters.Add "Text or CSV", "*.txt, *.csv", 1
.Show
sFN = .SelectedItems(1)
End With
Set WB = Workbooks.Add
With WB.Worksheets(1).QueryTables.Add(Connection:= _
"TEXT;" & sFN & "", Destination:=Range("$A"))
.Name = "test"
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = True
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(xlDMYFormat, xlGeneralFormat)
.Refresh BackgroundQuery:=False
End With
End Sub
但是使用 QueryTables 当然你必须小心,不要在没有必要的情况下多次添加它们,而是刷新它们或者先删除它们然后再添加它们。
感谢大家的建议。在可能的解决方案中,为了我的目的,我决定从文件中删除 *.csv
后缀。这有效并且可以适应。 QueryTable
方法也可以工作,以及 Axel 发布的警告。
如果有人感兴趣,这是适用于我的方法的代码。
Option Explicit
Sub foo()
Dim WB As Workbook, wbCSV As Workbook, swbCSV As String
Dim sFN As String, sCopyFN
Dim FD As FileDialog
Set WB = ThisWorkbook
Set FD = Application.FileDialog(msoFileDialogFilePicker)
With FD
.AllowMultiSelect = False
.Filters.Add "Text or CSV", "*.txt, *.csv", 1
.Show
sFN = .SelectedItems(1)
End With
'If CSV, remove suffix
sCopyFN = ""
If sFN Like "*.csv" Then
sCopyFN = Left(sFN, Len(sFN) - 4)
FileCopy sFN, sCopyFN
sFN = sCopyFN
End If
Workbooks.OpenText Filename:=sFN, DataType:=xlDelimited, origin:=437, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=True, Other:=False, _
FieldInfo:=Array(Array(1, xlDMYFormat), Array(2, xlGeneralFormat))
Set wbCSV = ActiveWorkbook
'Get path as string since it will not be available after closing the file
swbCSV = wbCSV.FullName
'Move the data into this workbook
Dim rCopy As Range, rDest As Range
With WB.Worksheets("sheet1")
Set rDest = .Cells(.Rows.Count, 1).End(xlUp)
End With
Set rCopy = wbCSV.Sheets(1).UsedRange
rCopy.Copy rDest
'must close the file before deleting it
wbCSV.Close False
Kill swbCSV
End Sub
巩固我的实验和 Axel Richter 的回答 with dwirony's answer to a related question :
- 通过
OpenText
或 Open
导入具有 .csv 扩展名的 CSV 文件会将所有日期视为 MDY(美国)格式。
OpenText
忽略扩展名为 .csv 的 CSV 文件的所有格式选项。
- 对于扩展名为 .txt 并使用
xlDelimited
选项的 CSV 文件,OpenText
会考虑 FileInfo
参数,但会忽略列号,因此数组从 1 开始的每一列都必须存在元素,直到描述了具有 non-default 格式的所有列。
令人沮丧的是用户界面工作正常(包括默认为区域日期格式),但 VBA 界面存在这些问题。
问题存在于 Excel 2013 年和 Excel 2016 年。
我很确定这在以前的 Excel
版本中工作正常测试文件:
d/mm/yyyy hh:mm:ss
5/12/1999 6:01:12
30/11/2001 5:00:00
并且日期和时间之间的分隔符是一个Space(ASCII码32)
如果文件另存为
.txt
文件,OpenText 方法会正确解析。如果文件保存为
.csv
文件,OpenText方法似乎根本不起作用如果空格替换为逗号,并且文件另存为
.csv
文件,OpenText 方法会将行分成两列,但不会正确解释日期字符串.
我的 Windows 区域设置是 mdy,我的 Excel 版本是 2016
Option Explicit
Sub foo()
Dim WB As Workbook
Dim sFN As String
Dim FD As FileDialog
Set FD = Application.FileDialog(msoFileDialogFilePicker)
With FD
.AllowMultiSelect = False
.Filters.Add "Text or CSV", "*.txt, *.csv", 1
.Show
sFN = .SelectedItems(1)
End With
Workbooks.OpenText Filename:=sFN, DataType:=xlDelimited, origin:=437, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=True, Other:=False, _
FieldInfo:=Array(Array(1, xlDMYFormat), Array(2, xlGeneralFormat))
Set WB = ActiveWorkbook
End Sub
看来这可能与此线程中解决的问题相同:
CSV files are Character Separated Value files, not Comma separated. For more than half the world the separator character is semicolon (;), not a comma (,)
Excel 2016 properly respects your Windows regional settings, and uses the specified "List separator" character
One solution is to change your regional settings for the "List separator" attribute to the character you want Excel to default to using, e.g. a comma (,)
This can be changed in:
Control Panel / Region / Additional Settings / List separator:
CSV
和 Text
实际上 与 Excel
不同 。不仅 CSV
的定界符设置非常特殊,而且 不能 使用 Workbooks.OpenText
中的参数设置。打开 CSV
文件时,也不会考虑字段类型 (FieldInfo
) 等其他参数。而且 unicode 处理对于 CSV
来说是一个非常特殊的情况,并且与 Text
.
您可以像这样尝试使用 QueryTables
:
Sub foo1()
Dim WB As Workbook
Dim sFN As String
Dim FD As FileDialog
Set FD = Application.FileDialog(msoFileDialogFilePicker)
With FD
.AllowMultiSelect = False
.Filters.Add "Text or CSV", "*.txt, *.csv", 1
.Show
sFN = .SelectedItems(1)
End With
Set WB = Workbooks.Add
With WB.Worksheets(1).QueryTables.Add(Connection:= _
"TEXT;" & sFN & "", Destination:=Range("$A"))
.Name = "test"
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = True
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(xlDMYFormat, xlGeneralFormat)
.Refresh BackgroundQuery:=False
End With
End Sub
但是使用 QueryTables 当然你必须小心,不要在没有必要的情况下多次添加它们,而是刷新它们或者先删除它们然后再添加它们。
感谢大家的建议。在可能的解决方案中,为了我的目的,我决定从文件中删除 *.csv
后缀。这有效并且可以适应。 QueryTable
方法也可以工作,以及 Axel 发布的警告。
如果有人感兴趣,这是适用于我的方法的代码。
Option Explicit
Sub foo()
Dim WB As Workbook, wbCSV As Workbook, swbCSV As String
Dim sFN As String, sCopyFN
Dim FD As FileDialog
Set WB = ThisWorkbook
Set FD = Application.FileDialog(msoFileDialogFilePicker)
With FD
.AllowMultiSelect = False
.Filters.Add "Text or CSV", "*.txt, *.csv", 1
.Show
sFN = .SelectedItems(1)
End With
'If CSV, remove suffix
sCopyFN = ""
If sFN Like "*.csv" Then
sCopyFN = Left(sFN, Len(sFN) - 4)
FileCopy sFN, sCopyFN
sFN = sCopyFN
End If
Workbooks.OpenText Filename:=sFN, DataType:=xlDelimited, origin:=437, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=True, Other:=False, _
FieldInfo:=Array(Array(1, xlDMYFormat), Array(2, xlGeneralFormat))
Set wbCSV = ActiveWorkbook
'Get path as string since it will not be available after closing the file
swbCSV = wbCSV.FullName
'Move the data into this workbook
Dim rCopy As Range, rDest As Range
With WB.Worksheets("sheet1")
Set rDest = .Cells(.Rows.Count, 1).End(xlUp)
End With
Set rCopy = wbCSV.Sheets(1).UsedRange
rCopy.Copy rDest
'must close the file before deleting it
wbCSV.Close False
Kill swbCSV
End Sub
巩固我的实验和 Axel Richter 的回答
- 通过
OpenText
或Open
导入具有 .csv 扩展名的 CSV 文件会将所有日期视为 MDY(美国)格式。 OpenText
忽略扩展名为 .csv 的 CSV 文件的所有格式选项。- 对于扩展名为 .txt 并使用
xlDelimited
选项的 CSV 文件,OpenText
会考虑FileInfo
参数,但会忽略列号,因此数组从 1 开始的每一列都必须存在元素,直到描述了具有 non-default 格式的所有列。
令人沮丧的是用户界面工作正常(包括默认为区域日期格式),但 VBA 界面存在这些问题。
问题存在于 Excel 2013 年和 Excel 2016 年。