使用CSV文件自动更新访问表

时间:2018-03-01 00:40:34

标签: csv ms-access access-vba ms-access-2013

问题背景:

我有一个Powershell脚本,我可以从我的Microsoft Access表单执行,该脚本扫描包含不同设施信息的文件夹,并生成类似于以下内容的CSV:

SiteCode    FacilityNumber  DocumentType    HyperlinkPath
DKFZ        10              DD1400          C:\FACILITIES DATABASE\path
DKFZ        10              FLRPLN          C:\FACILITIES DATABASE\path
SMQL        17              P1              C:\FACILITIES DATABASE\path
SMQL        17              P2              C:\FACILITIES DATABASE\path

因此,每次将新文件添加到这些文件夹时,我都可以运行此脚本并生成我所拥有的所有内容的更新列表:

C:\...\Output\scanResults.csv

我现在需要的是获取CSV文件并更新(甚至覆盖)我在Access数据库中拥有的表,该数据库与其他表有关系,并由数据库中的各种查询和表单使用。 CSV列已经以与访问表相同的方式命名和格式化。

我看过并尝试复制以下主题:

VBA procedure to import csv file into access

Access Data Project Importing CSV File In VBA

VBA Import CSV file

我找到的最接近的答案是:

Sub Import()
   Dim conn as new ADODB.Connection
   Dim rs as new ADODB.Recordset
   Dim f as ADODB.field

   conn.Open "DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=c:\temp;"
   rs.Open "SELECT * FROM [test.txt]", conn, adOpenStatic, adLockReadOnly, adCmdText

   While Not rs.EOF
      For Each f In rs.Fields
         Debug.Print f.name & "=" & f.Value
      Next
   Wend
End Sub

但是这显然不会将数据写入表中,我无法理解作者在更改Select to Insert方面所说的内容。

我也发现:

DoCmd.TransferText acImportDelim, "YourCustomSpecificationName", _
    "tblImport", "C:\SomeFolder\DataFile.csv", False

由于这些都来自2010年,我想知道在Access 2013中是否没有更好的方法来实现这一点。虽然我可以手动完成所有这些,但我想将其合并到我使用的VBA代码中告诉Powershell生成CSV,这样我就可以制作它,然后立即上传。

非常感谢任何帮助或建议。一般来说,我对Access,VBA和SQL语句仍然非常环保,所以这一直是一个“随时随地学习”的过程。

2 个答案:

答案 0 :(得分:2)

我更喜欢使用SQL子句和查询来导入此类数据。细节取决于您的确切配置,但它往往看起来像这样:

SELECT *
INTO MyTable
FROM [Text;FMT=CSVDelimited;HDR=No;DATABASE=C:\...\Output].[scanResults#csv]

或者将信息附加到表格中:

INSERT INTO MyTable
(SiteCode,    FacilityNumber,  DocumentType,    HyperlinkPath)
SELECT *
FROM [Text;FMT=CSVDelimited;HDR=No;DATABASE=C:\...\Output].[scanResults#csv]

这允许您在导入之前进行检查(使用WHERE子句),仅导入特定值,并允许您自定义批次而不使用外部文件。

DATABASE=之后是您的文件夹名称(如果有字符需要转义,请使用{}),然后是.替换为{{1}的文件名}}

您可以通过将其另存为查询或将其用作VBA或宏中的字符串来执行它。请注意,我很少推荐使用宏,但可以使用计划任务执行它们,并在导入后关闭Access。

要在更新前后备份和恢复关系,可以使用以下功能:

#

然后,导入时:

Public Function DeleteRelationsGiveBackup(strTablename As String) As Collection
    Dim ReturnCollection As Collection
    Set ReturnCollection = New Collection
    Dim i As Integer
    Dim o As Integer
    Do While i <= (CurrentDb.Relations.Count - 1)
        Select Case strTablename 
            Case Is = CurrentDb.Relations(i).Table
                ReturnCollection.Add DuplicateRelation(CurrentDb.Relations(i))
                o = o + 1
                CurrentDb.Relations.Delete CurrentDb.Relations(i).NAME
            Case Is = CurrentDb.Relations(i).ForeignTable
                ReturnCollection.Add DuplicateRelation(CurrentDb.Relations(i))
                o = o + 1
                CurrentDb.Relations.Delete CurrentDb.Relations(i).NAME
            Case Else
                i = i + 1
        End Select
    Loop
    Set DeleteRelationsGiveBackup = ReturnCollection
End Function

Public Sub RestoreRelationBackup(collRelationBackup As Collection)
    Dim relBackup As Variant
    If collRelationBackup.Count = 0 Then Exit Sub
    For Each relBackup In collRelationBackup
        CurrentDb.Relations.Append relBackup
    Next relBackup
End Sub

Public Function DuplicateRelation(SourceRelation As Relation) As Relation
    Set DuplicateRelation = CurrentDb.CreateRelation(SourceRelation.NAME, SourceRelation.Table, SourceRelation.ForeignTable)
    DuplicateRelation.Attributes = SourceRelation.Attributes
    Dim i As Integer
    Dim fldLoop As Field
    Do While i < SourceRelation.Fields.Count
        Set fldLoop = DuplicateRelation.CreateField(SourceRelation.Fields(i).NAME)
        fldLoop.ForeignName = SourceRelation.Fields(i).ForeignName
        DuplicateRelation.Fields.Append fldLoop
        i = i + 1
    Loop
End Function

(请注意,代码很长,是几年前为项目开发的,并没有经过广泛测试。如果字段名称/类型不像导入前那样完全,那么恢复备份可能会失败,关系将永久丢失。

答案 1 :(得分:1)

所以一些高级架构师建议:替换数据与替换表

更换数据更容易 - 新的传入数据必须与现有表格完全相同(即相同的字段名称和新字段)。

    • 只需向现有表格中删除查询即可清除所有记录
    • 然后向链接的CSV文件发出追加查询,该文件将所有这些记录写入现有表

非常简单。

如果必须,您可以替换表格 - 而且您已经走了这条路。您可以完全删除这些表关系。该表关系功能很有用 - 但不是强制性的。您可以在查询级别创建关系作为替代方案。本质上,表关系只是自动创建查询级别关系。如果删除表关系,则必须手动在查询级别创建表关系 - 它们不会自动显示。但请注意,如果依赖级联删除或参照完整性,那么删除表关系将撤消 - 因此您应该检查这些点。

删除表关系不会破坏任何现有查询。他们的表关系连接线将保持不变。