2

因此,我导航到了以下MSDN 资源页面,其中介绍了如何使用 ADO 对象。我的问题是我无法让它工作。

我想要做的是打开一个 CSV 文件并逐行读取它,然后创建 SQL INSERT 语句以将记录插入到 Access 2010 中的现有表中。我试图找到一种更简单的方法,但是这似乎是我唯一的选择。使用随附的工具执行此操作,但到目前为止,我还没有运气。

这里的主要问题是我的 CSV 文件的标题不一致。我想将 5 个文件导入到同一个表中,但是每个文件都会根据包含数据的字段而有所不同。提取过程中将忽略那些没有数据的字段。这就是为什么我不能使用像 DoCmd.TransferText 这样的东西。

所以,现在我需要创建一个脚本来打开文本文件,读取第一行的标题,并根据该特定文件的配置创建一个 SQL INSERT 语句。

我有一种感觉,我对如何解决这个问题有很好的处理,但无论我尝试什么,我似乎都无法使用 ADO 来解决问题。

谁能解释我如何做到这一点?我的症结是让 Access DB 通过 ADO 从 CSV 文件中接收信息。

4

2 回答 2

3

我认为您应该将文件作为 ADO 记录集打开,而不是逐行读取 CSV 文件,然后对每一行进行处理。并为您的访问目标表打开一个 DAO 记录集。

然后,您可以遍历 ADO 记录集的每一行中的字段,并将它们的值添加到 DAO 记录集的新行中。只要目标表包含与 CSV 字段具有相同名称和兼容数据类型的字段,这可以相当顺利。

Public Sub Addikt()
#If ProjectStatus = "DEV" Then
    ' needs reference for Microsoft ActiveX Data Objects
    Dim cn As ADODB.Connection
    Dim fld As ADODB.Field
    Dim rs As ADODB.Recordset
    Set cn = New ADODB.Connection
    Set rs = New ADODB.Recordset
#Else ' assume PROD
    Const adCmdText As Long = 1
    Const adLockReadOnly As Long = 1
    Const adOpenForwardOnly As Long = 0
    Dim cn As Object
    Dim fld As Object
    Dim rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
#End If
    Const cstrDestination As String = "tblMaster"
    Const cstrFile As String = "temp.csv"
    Const cstrFolder As String = "C:\share\Access"
    Dim db As DAO.Database
    Dim rsDao As DAO.Recordset
    Dim strConnectionString As String
    Dim strName As String
    Dim strSelect As String

    strConnectionString = "Provider=" & _
        CurrentProject.Connection.Provider & _
        ";Data Source=" & cstrFolder & Chr(92) & _
        ";Extended Properties='text;HDR=YES;FMT=Delimited'"
    'Debug.Print strConnectionString
    cn.Open strConnectionString

    strSelect = "SELECT * FROM " & cstrFile
    rs.Open strSelect, cn, adOpenForwardOnly, _
        adLockReadOnly, adCmdText

    Set db = CurrentDb
    Set rsDao = db.OpenRecordset(cstrDestination, _
        dbOpenTable, dbAppendOnly + dbFailOnError)

    Do While Not rs.EOF
        rsDao.AddNew
        For Each fld In rs.Fields
            strName = fld.Name
            rsDao.Fields(strName) = rs.Fields(strName).value
        Next fld
        rsDao.Update
        rs.MoveNext
    Loop

    rsDao.Close
    Set rsDao = Nothing
    Set db = Nothing
    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
End Sub

这是我保存该过程的模块的声明部分:

Option Compare Database
Option Explicit
#Const ProjectStatus = "DEV" '"DEV" or "PROD"

更改这些常量的值以在您的系统上对其进行测试:

Const cstrDestination As String = "tblMaster"
Const cstrFile As String = "temp.csv"
Const cstrFolder As String = "C:\share\Access"

请注意,文件夹名称不包含尾部反斜杠。

您将需要调整该过程以将文件名作为参数传递,而不是将其保留为常量。而且,如果您的 CSV 文件存储在多个目录中,您也需要将文件夹名称作为参数传递。

希望向您展示如何为一个文件执行此操作就足够了,然后您可以从这里获取它来处理所有 CSV 文件。还要考虑添加错误处理。

于 2012-05-09T05:47:00.443 回答
0

我认为前面的答案是不必要的复杂。您只需发送XMLHTTP请求即可。这会将 CSV 数据作为字符串获取,然后可以将其解析为表。

我已经发布了一个 VBA 子例程,它在对类似问题的回答中做到了这一点。我在哪里找到这些技术的文档在代码注释中。我已经在 Access 2019 中运行了它,它可以工作。

于 2021-04-26T07:29:26.553 回答