使用ADODB导入CSV文件时尾缀负号数字丢失问题求助
解决ADODB导入CSV时尾缀负号丢失的问题
针对你遇到的尾缀负号(如123-)被ADODB RecordSet丢失的问题,提供两种高效解决方案,适配大文件处理需求:
方案1:通过Schema.ini强制文本读取,再批量转换为负数
ADODB的Jet引擎会自动推断列数据类型,将带尾缀负号的内容识别为数值并丢弃负号。通过Schema.ini指定目标列为文本类型,可完整保留原始内容,之后用VBA批量转换为正确的负数。
修改Schema.ini配置
在生成Schema.ini的代码中,添加目标列的类型定义(假设第3列是带尾缀负号的列,列名为Amount):
'Create Schema file Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject") Dim oFile As Object Set oFile = fso.CreateTextFile(strFilePath & "\\Schema.ini") oFile.WriteLine ("[" & strFileName & "]") oFile.WriteLine ("Format=Delimited(;)") oFile.WriteLine ("ColNameHeader=True") oFile.WriteLine ("CharacterSet=OEM") oFile.WriteLine ("MaxScanRows=25") ' 添加列类型定义,将带尾缀负号的列设为Text oFile.WriteLine ("Col3=Amount Text") ' Coln对应列的序号,从1开始
导入后批量转换为负数
导入数据后,用数组批量处理目标列,避免逐个单元格操作的性能损耗:
With ws .UsedRange.ClearContents .Range("A1:Z1") = headers copyRng.CopyFromRecordset recordSet ' 批量处理带尾缀负号的列(假设是第3列,即C列) Dim dataArr As Variant Dim i As Long dataArr = .Range("C2:C" & .Cells(.Rows.Count, "C").End(xlUp).Row).Value For i = LBound(dataArr) To UBound(dataArr) If Right(dataArr(i, 1), 1) = "-" Then dataArr(i, 1) = -CDbl(Left(dataArr(i, 1), Len(dataArr(i, 1)) - 1)) Else ' 保留原始数值(如果是正常格式) If IsNumeric(dataArr(i, 1)) Then dataArr(i, 1) = CDbl(dataArr(i, 1)) End If Next i .Range("C2:C" & .Cells(.Rows.Count, "C").End(xlUp).Row).Value = dataArr End With
方案2:在SQL查询中直接转换尾缀负号
无需修改Schema.ini,直接在SELECT语句中处理尾缀负号,让RecordSet直接返回正确的负数,省去后续转换步骤:
修改RecordSet查询代码
' 替换原有的SELECT语句,针对带尾缀负号的列进行处理 Dim sqlStr As String ' 假设需要处理的列是Amount,其他列正常选择 sqlStr = "SELECT " & _ "Col1, " & _ ' 替换为你的实际列名 "IIF(RIGHT(Amount, 1)='-', -1*LEFT(Amount, LEN(Amount)-1), Amount) AS Amount, " & _ "Col3, Col4 " & ' 替换为你的实际列名 "FROM " & strFileName recordSet.Open sqlStr, conn, 3, 1
说明
IIF函数判断列值最后一位是否为-,若是则取前面的内容转换为数值后乘以-1,否则保留原始值。- 若有多列需要处理,只需在SELECT语句中重复上述逻辑即可。
注意事项
- 若不确定哪些列存在尾缀负号,可将所有数值列在Schema.ini中设为Text类型,或在SQL中统一处理。
- 两种方案均避免了Query Table和Power Query的性能问题,适配大文件批量处理。
内容的提问来源于stack exchange,提问作者đức anh phạm ngọc
相关产品推荐
相关产品推荐

