我尝试将海量 CSV文件(1.2 GB)导入Access。我知道访问上限为2 GB。实际上我们甚至不需要整个文件,但我试图为每条记录拉入某些行。如有必要,我们可以使用SQL Server Express作为后端,但我尝试在Access中完成所有操作。
以下是我迄今为止编写的代码。这实际上有效,直到我收到错误:"出现错误9:下标超出范围"。对于我正在测试的文件,我注意到它导入了前29行。所以起初我认为这是一个糟糕的角色,额外的回车,类似的东西。但是我在Notepad ++中打开了文件,并没有看到任何可疑的内容。所以我从文件中删除了前29行并再次导入。现在我在得到相同的错误之前得到了大约400行。关于我做错了什么的任何建议?
如果你有关于重做导入方法的建议,如果你能给我一个很好的工作实例,我就打开了。我正在阅读有关文件系统对象的内容,但没有真正看到导入文件并将所需字段输入表格的完整示例。您可以在代码底部的注释部分中看到我尝试的第一种方法。此方法失败,因为MyData变量用尽了STRING的空间。
关注:我实施了评论中提到的一些更改。问题出现在" For Each X In rs.Fields'环。我宣称X是一个对象。当前循环位于下面代码的顶部。我稍微改了一下,以便检查X是否为NULL,但是现在我得到了424错误:需要对象。我对此感到困惑,因为如果没有其他X,我不明白我们如何进入For循环。
关注2:我使用拆分功能,因为每行包含在一个单元格中。我不确定我说该文件是在连接字符串中分隔的,这是对的。我注意到当记录集拉回多个值时,我遇到了问题。没有列标题,所以我通常只会得到" F1"对于每个记录集。但是当我遇到问题时,记录集会拉回两个字段F1和F2,F2为NULL。我真的不需要为记录集中的每个字段循环,我知道我总是只想要第一个字段。我怎么做而不是#34;对于rs.Fields中的每个fld"
Do While Not rs.EOF
For Each x In rs.Fields
If X Is Not Null Then
tmpData = Split(x.Value, ";")
SQL = "INSERT INTO TestMaster(BPARTNER, [CACONT_ACC], UCCONTRACT, [SITE_CITY_1]) SELECT " & tmpData(0) & "," & tmpData(1) & "," & tmpData(2) & ", '" & tmpData(5) & "'"
DoCmd.RunSQL (SQL)
End If
N = N + 1
Next
rs.MoveNext
Loop
Private Sub ImportMaster_Click()
On Error GoTo ErrorHandler
Dim MyData As String
Dim tmpData() As String
Dim N As Long
N = 1
'close tables/queries to prevent potential errors
Call CloseAll(False, False, True, True)
'Select Excel file
Dim FileName As Variant
FileName = selectFile
If Format(FileName) = vbNullString Then
'Canceled
Exit Sub
End If
Dim sPath As String
sPath = Left(FileName, InStrRev(FileName, "\"))
Dim sFileName As String
sFileName = Dir(FileName)
'open the please wait form
DoCmd.OpenForm ("Please Wait")
Dim rs As Object
Dim cn As Object
Dim SQL As String
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source= " & sPath & _
";Extended Properties=""text; HDR=No; FMT=Delimited(;);""")
rs.Open "Select * from " & sFileName, cn
DoCmd.SetWarnings False
Do While Not rs.EOF
For Each x In rs.Fields
tmpData = Split(x.Value, ";")
If tmpData(0) <> "" Then
SQL = "INSERT INTO TestMaster(BPARTNER, [CACONT_ACC], UCCONTRACT, [SITE_CITY_1]) SELECT " & tmpData(0) & "," & tmpData(1) & "," & tmpData(2) & ", '" & tmpData(5) & "'"
DoCmd.RunSQL (SQL)
End If
N = N + 1
Next
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
DoCmd.SetWarnings True
'Open FileName For Binary As #1
'MyData = Space$(LOF(1))
'Get #1, , MyData
'Close #1
'strData() = Split(MyData, vbCrLf)
'For I = LBound(strData) To 2 'UBound(strData) --changed to 2 for t3esting, should be UBound
'If Len(Trim(strData(I))) <> 0 Then
'tmpData = Split(strData(I), ";")
'ResultArray(N, 0) = Replace(tmpData(5), Chr(34), "")
'ResultArray(N, 1) = Replace(tmpData(1), Chr(34), "")
'ResultArray(N, 2) = Replace(tmpData(2), Chr(34), "")
'ResultArray(N, 3) = Replace(tmpData(3), Chr(34), "")
'N = N + 1
'End If
'Next I
答案 0 :(得分:0)
尝试一些额外的检查:
tmpData = Split(x.Value, ";")
if UBound(tmpData)<5 then
debug.print "At N=" & N & " there is a line with too few semicolons."
else
SQL = "INSERT INTO TestMaster(BPARTNER, [CACONT_ACC], UCCONTRACT, [SITE_CITY_1]) SELECT " & tmpData(0) & "," & tmpData(1) & "," & tmpData(2) & ", '" & tmpData(5) & "'"
DoCmd.RunSQL (SQL)
end if
而且,如果你正如你所说的那样迭代GB数据,那么在整个循环中散布这些语句可能是明智的:
DoEvents