我被分配了将大约180个csv文件导入访问2007数据库的任务。这些文件多年来一直放在一起,将被放入3个文件夹中的1个。我没有为这些表设置任何数据检查或限制(例如主键,验证规则或关系)。这将在导入数据后完成。这些文件中包含的数据来自多年来发生变化的调查。此更改导致字段更改。它们的顺序已经改变,或者有时候有一个字段,有时它不是。我确实有一个可能的所有字段的列表,以及每个csv文件应导入哪个表,并且知道所有这些字段都可以是文本。
这是我的问题:不知道列的顺序或列是否存在,是否可以通过将文本文件中的每一列映射到它的相关联来运行函数将这些文本文件导入到它们的相关表中访问表中的列?
每个文本文件都有标题,这对于查看它们实际上是很有用,但是在处理完全由数字组成的id代码时,没有文本限定符可能非常烦人。以下是我到目前为止所尝试的内容。它从其他地方的函数获取文件位置,将该位置中的每个文件名添加到集合中,然后对于该集合中的每个文件,它尝试将其导入到它的相对字段中。
'Get file names from the folder and store them in a collection
temp = Dir(location & "\*.*")
Do While temp <> ""
fileNames.Add temp
temp = Dir
Loop
'Go through each file in the collection and preccess it as needed
For Each temp2 In fileNames
If (temp2 Like "trip*") Then 'Import trip files
'Gets the data from a query 'DoCmd.RunSQL "SELECT * FROM [Text;FMT=Delimited;HDR=YES;IMEX=2;CharacterSet=437;DATABASE=" & location & "].[" & temp2 & "] As csv;"
DoCmd.TransferText acImportDelim, "Trips_Import", "tbl_Trips", location & "\" & temp2, -1
End If
If (temp2 Like "catch*") Then 'Import catch files
DoCmd.TransferText acImportDelim, "Catch_Import", "tbl_Catch", location & "\" & temp2, -1
End If
If (temp2 Like "size*") Then 'Import size files
DoCmd.TransferText acImportDelim, "Size_Import", "tbl_Size", location & "\" & temp2, -1
End If
Next temp2
答案 0 :(得分:1)
您可以为每个CSV文件创建SELECT *
查询,并将查询作为记录集打开。打开目标表的另一个记录集。
然后,对于CSV记录集中的每一行,向目标记录集添加一行,循环访问CSV Fields
集合,并将每个CSV字段值添加到具有相同名称的目标字段。
此方法与字段在CSV文件中的显示顺序无关。 CSV文件是否仅包含目标表中存在的字段的子集也无关紧要。只要每个CSV字段也存在于表中,它就应该工作(假设兼容的数据类型,该值满足验证规则/约束等)。
Dim db As DAO.Database
Dim fld As DAO.Field
Dim rsDest As DAO.Recordset
Dim rsSrc As DAO.Recordset
Dim strSelect As String
Dim strTableName As String
Set db = CurrentDb
'Go through each file in the collection and preccess it as needed
For Each temp2 In fileNames
Select Case Left(temp2, 4)
Case "trip"
strTableName = "tbl_Trips"
Case "catc"
strTableName = "tbl_Catch"
Case "size"
strTableName = "tbl_Size"
Case Else
' what should happen here?
' this will trigger an error at OpenRecordset(strTableName) ...
strTableName = vbNullString
' figure out a better alternative
End Select
strSelect = "SELECT csv.* FROM " & _
"[Text;FMT=Delimited;HDR=YES;IMEX=2;CharacterSet=437;DATABASE=" & _
Location & "].[" & temp2 & "] As csv;"
Debug.Print strSelect
Set rsSrc = db.OpenRecordset(strSelect, dbOpenSnapshot)
Set rsDest = db.OpenRecordset(strTableName, dbOpenTable, dbAppendOnly)
With rsSrc
Do While Not .EOF
rsDest.AddNew
For Each fld In .Fields
rsDest.Fields(fld.Name).value = fld.value
Next
rsDest.Update
.MoveNext
Loop
.Close
End With
rsDest.Close
Next temp2
注意:这是一个RBAR(通过痛苦行排)的方法,因此性能将低于恒星。但是,我认为你只会这样做一次,所以性能打击不会是一个交易破坏者。如果您需要更快的基于集合的方法,则可以为每个CSV文件构建并执行“追加查询”。为此,您首先需要获取CSV字段名称,然后构建相应的INSERT INTO
语句。