【问题标题】:How do I insert a blank value when field does not exist in Access?Access中不存在字段时如何插入空白值?
【发布时间】:2016-09-22 08:33:03
【问题描述】:

我在 Microsoft Access 中使用 vba 代码一次导入多个 csv 文件,不幸的是,并非所有 csv 文件都具有相同的格式;有些文件只有 [SKU-1],但有些文件有第二个字段 [SKU-2]。

对于在 csv 文件中同时具有 sku-1 和 sku-2 作为字段的文件,我的代码如下所示,但是,如果文件只有 [SKU-1],则导入失败并显示“参数太少. 预期 1。

如果字段本身不存在以供从中提取,是否有任何方法可以使用某种 case 语句来删除 SKU-2 的 NULL 值?

CurrentDb.Execute "INSERT INTO MumbyCSV (OrderID, Email, FirstName, LastName, Company, Phone, SecondaryPhone," & _
        "Fax, ApproveStatus, OrderDate, [SKU-1], [SKU-2], Total, ShiptoName, ShipToAddress1, ShipToAddress2," & _
        "ShipToCity, ShipToState, ShipToZip, ShipToCountry, ShippingMethod, Comments)" & _
        "SELECT OrderID, Email, FirstName, LastName, Company, Phone, SecondaryPhone," & _
        "Fax, ApproveStatus, OrderDate, [SKU-1], [SKU-2], Total, ShiptoName, ShipToAddress1, ShipToAddress2," & _
        "ShipToCity, ShipToState, ShipToZip, ShipToCountry, ShippingMethod, Comments " & _
        "FROM [Text;FMT=Delimited;HDR=YES;DATABASE=C:\ImportPath].[test.csv]"

【问题讨论】:

  • 在插入之前对 CSV 文件运行一个选择,然后调整您的 SQL 语句以匹配实际文件。

标签: sql vba csv ms-access import


【解决方案1】:

首先检查文件中的字段数:

dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
dim file : Set file = fso.OpenTextFile("C:\ImportPath\test.csv")
firstLine = file.ReadLine ' read first line
fieldArray = Split(firstLine, "whateverfielddelimiteryouhave")
numFields = UBound(fieldArray) + 1  'index on arrays from zero

这将告诉您有多少字段。如果您定义了带有和不带有[SKU-2] 的SQL,那么您可以使用简单的IF 来选择要执行的SQL:

If numFields = 22 Then
sql = "INSERT INTO MumbyCSV (OrderID, Email, FirstName, LastName, Company, Phone, SecondaryPhone," & _
        "Fax, ApproveStatus, OrderDate, [SKU-1], [SKU-2], Total, ShiptoName, ShipToAddress1, ShipToAddress2," & _
        "ShipToCity, ShipToState, ShipToZip, ShipToCountry, ShippingMethod, Comments)" & _
        "SELECT OrderID, Email, FirstName, LastName, Company, Phone, SecondaryPhone," & _
        "Fax, ApproveStatus, OrderDate, [SKU-1], [SKU-2], Total, ShiptoName, ShipToAddress1, ShipToAddress2," & _
        "ShipToCity, ShipToState, ShipToZip, ShipToCountry, ShippingMethod, Comments " & _
        "FROM [Text;FMT=Delimited;HDR=YES;DATABASE=C:\ImportPath].[test.csv]" 
Else
sql = "INSERT INTO MumbyCSV (OrderID, Email, FirstName, LastName, Company, Phone, SecondaryPhone," & _
        "Fax, ApproveStatus, OrderDate, [SKU-1], Total, ShiptoName, ShipToAddress1, ShipToAddress2," & _
        "ShipToCity, ShipToState, ShipToZip, ShipToCountry, ShippingMethod, Comments)" & _
        "SELECT OrderID, Email, FirstName, LastName, Company, Phone, SecondaryPhone," & _
        "Fax, ApproveStatus, OrderDate, [SKU-1], Total, ShiptoName, ShipToAddress1, ShipToAddress2," & _
        "ShipToCity, ShipToState, ShipToZip, ShipToCountry, ShippingMethod, Comments " & _
        "FROM [Text;FMT=Delimited;HDR=YES;DATABASE=C:\ImportPath].[test.csv]"
End If

CurrentDB.Execute sql

第二个选项是读取要导入数组的值,如果该值是空字符串,则将其替换为 NULL,这样该字段就不会在 INSERT 步骤中设置。但是,如果您必须根据您的代码直接从文件中导入,我认为您不能这样做。

【讨论】:

  • 这是一个很好的解决方法,根据具体情况而定,但我应该只有 2-3 种不同的格式,这些格式会有不同的列数。在代码的第一部分,numfields 字符串似乎最终成为整个文件中的逗号数,而不仅仅是第一行。我该如何解决这个问题?
  • 我想通了。我的 csvs 有回车 CR 而不是行结束 CRLF。它总是一些东西。
【解决方案2】:

考虑使用TransferText,它不需要任何列顺序并忽略丢失的列,只要当前正在导入的文件在表中的某处维护列:

DoCmd.TransferText acImportDelim, , "MumbyCSV", "C:\ImportPath\test.csv", True

【讨论】:

  • 我原来是用这个方法的,但是在设置导入规范文件之前,它给出了很多导入错误表。但是,当我第二次定义导入规范时,如果我尝试导入具有与规范文件不同的字段的 csv,它就会中断(这首先是我的问题;不同格式的 csv 文件流入)
  • 嗯...导入规范是可选的,并且专门针对结构化文件进行定制。但是,如果您的文件明确用逗号分隔,列标题和数据类型与目标表对齐,这应该可以工作。
  • 谢谢,我确实最终使用了您的建议,使用了几个不同的规范文件,并且 Dave 的建议现在结合起来获得了相当强大的导入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多