访问VBA导入CSV文件并使用记录集

时间:2017-05-25 19:19:49

标签: vba csv ms-access import

我尝试将海量 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

1 个答案:

答案 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