在 Access 中使用 ADO 导入 CSV 数据
Posted
技术标签:
【中文标题】在 Access 中使用 ADO 导入 CSV 数据【英文标题】:Using ADO in Access to import CSV data 【发布时间】:2012-05-09 03:19:52 【问题描述】:因此,我导航到了以下MSDN Resource Page,其中介绍了如何使用 ADO 对象。我的问题是我无法让它工作。
我要做的是打开一个 CSV 文件并逐行读取它,然后创建 SQL INSERT 语句以将记录插入到 Access 2010 中的现有表中。我试图找到一种更简单的方法这个,但这似乎是我唯一的选择。使用随附的工具执行此操作,但到目前为止,我还没有运气。
这里的主要问题是我的 CSV 文件的标题不一致。我想将 5 个文件导入到同一个表中,但是每个文件都会根据包含数据的字段而有所不同。提取过程中将忽略那些没有数据的字段。这就是为什么我不能使用像 DoCmd.TransferText 这样的东西。
所以,现在我需要创建一个脚本来打开文本文件,读取第一行的标题,并根据该特定文件的配置创建一个 SQL INSERT 语句。
我觉得我对如何解决问题有很好的把握,但无论我尝试什么,我似乎都无法使用 ADO 来解决问题。
谁能解释我如何做到这一点?我的症结是让 Access DB 通过 ADO 从 CSV 文件中接收信息。
【问题讨论】:
您的方法似乎正确。发布您到目前为止所拥有的内容(失败的部分),社区应该能够更好地帮助您。 【参考方案1】:我认为您应该将文件作为 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 文件。还可以考虑添加错误处理。
【讨论】:
关于此方法的快速问题。为什么要同时使用 ADO 和 DAO?不能创建两个 ADO 连接吗?或者 DAO 是否为 MS 程序提供了更强大的功能集?今晚晚些时候我会试试这个。如果我可以让它为一个文件工作,我有一个脚本可以用来迭代所有文件夹/文件,我将从中调用工作函数。我会让你知道事情进展如何,感谢你的帮助! 对于存储在 Jet/ACE 中的数据,DAO 比 ADO 快得多。 还有一个问题要问您。顶部的 If 语句是怎么回事? 这些是条件编译指令。在模块中使用该代码,将光标放在#If
,然后按 F1 阅读帮助主题详细信息。基本上,我想向您展示如何将 ADO 与早期绑定(在 DEV 块下)或后期绑定(在 PROD 块下)一起使用。我使用#Const ProjectStatus
在它们之间切换。早期绑定在开发过程中很方便,但需要参考。我切换到后期绑定以进行生产并删除参考。【参考方案2】:
我认为前面的答案是不必要的复杂。您只需发送XMLHTTP
请求即可。这会将 CSV 数据作为字符串获取,然后可以将其解析为表格。
我在answer to a similar question 中发布了一个VBA 子例程。我在哪里找到这些技术的文档在代码 cmets 中。我在 Access 2019 中运行过它,它可以工作。
【讨论】:
以上是关于在 Access 中使用 ADO 导入 CSV 数据的主要内容,如果未能解决你的问题,请参考以下文章