ms-access - 从 CSV 导入 Access 时字段顺序错误

标签 ms-access import vba ms-access-2010

我在我的应用程序中提供了一个导入工具,以允许用户使用基本的起始数据填充它。我无法控制他们如何创建导入的数据,或者他们是否真正遵循我提供的导入规范(迄今为止的 beta 测试经验充分证明了这一点)。我还了解到,他们导入的数据集比我预期的要大得多(到目前为止最大的是 750,000 条记录),因此导入需要表现良好。

需要导入五到六组不同的数据,从 4 列到 24 列不等,我正在尝试找出一种可以用于所有数据的方法,从最简单的数据集开始。

这个最简单的导入文件是一个 csv 文件,有 4 列,没有标题,并且最终应该出现在一个临时 Access 表中,其中的字段如下。

GenID: text (up to 255 chars) 

Surname: text (up to 255 chars)

GivenNames: text (up to 255 chars)

OtherInfo: multi-line memo (as long as they want)

数据应导入到临时表中,在附加到最终主目录中的现有数据之前将在该临时表中进行验证。

我首先尝试使用 docmd.transfertext 和已保存的导入规范——它可以工作,但对于除最小导入文件之外的任何其他文件来说速度都慢得令人痛苦。 (我不能发誓它不会表现出我在下面讨论的第二种方法中相同的一些缺陷,因为我还没有对其进行详尽的测试)。

我尝试的下一个方法是基于 https://stackoverflow.com/a/11147920/1943174 的方法。 ,尽管我一直在努力寻找有关使用 Xml 导入规范执行导入时应预期的确切行为或应使用的 XML 语法的任何文档。

我在 VBA 中创建并执行导入规范。 strFilePath 标识要导入的 csv 文件,strTableName 标识要用于导入的临时表。

Dim strXML As String

strXML = ""
strXML = strXML & "<?xml version=""1.0"" encoding=""utf-8"" ?>" & vbCrLf
strXML = strXML & "<ImportExportSpecification Path=" & Chr(34) & strFilePath & Chr(34) & " xmlns=""urn:www.microsoft.com/office/access/imexspec"">" & vbCrLf
strXML = strXML & "   <ImportText TextFormat=""Delimited"" FirstRowHasNames=""false"" FieldDelimiter="","" CodePage=""437"" Destination=" & Chr(34) & strTableName & Chr(34) & " >" & vbCrLf
strXML = strXML & "      <DateFormat DateOrder=""DMY"" DateDelimiter=""/"" TimeDelimiter="":"" FourYearDates=""true"" DatesLeadingZeros=""false"" />" & vbCrLf
strXML = strXML & "      <NumberFormat DecimalSymbol=""."" />" & vbCrLf
strXML = strXML & "           <Columns PrimaryKey=""{none}"">" & vbCrLf
strXML = strXML & "                    <Column Name=""Col1"" FieldName=""GenID"" Indexed=""NO"" SkipColumn=""false"" DataType=""Text"" />" & vbCrLf
strXML = strXML & "                    <Column Name=""Col2"" FieldName=""Surname"" Indexed=""NO"" SkipColumn=""false"" DataType=""Text"" />" & vbCrLf
strXML = strXML & "                    <Column Name=""Col3"" FieldName=""GivenNames"" Indexed=""NO"" SkipColumn=""false"" DataType=""Text"" />" & vbCrLf
strXML = strXML & "                    <Column Name=""Col4"" FieldName=""OtherInfo"" Indexed=""NO"" SkipColumn=""false"" DataType=""Memo"" />" & vbCrLf
strXML = strXML & "         </Columns>" & vbCrLf
strXML = strXML & "     </ImportText>" & vbCrLf
strXML = strXML & "</ImportExportSpecification>"

CurrentProject.ImportExportSpecifications.Add "MyImportSpec", strXML 'Add it to the project
DoCmd.RunSavedImportExport "MyImportSpec"'Run it

导入非常快,我使用的测试输入数据格式正确,但结果是结构正确的 Access 表,但数据导入到了错误的字段:

GenID -- in the right place

GivenNames  -- in the Other Info (memo) field

OtherInfo -- in the Surname (text) field

Surname -- in the Given Names (field).

如果我更改导入文件中列的顺序,使其按字母顺序排列(GenID、GivenNames、OtherInfo、Surname),则导入可以正常工作,但该顺序对用户或用户来说没有意义易于生成,因此他们最终可能会错误地填充其导入文件。 (此外,由于我即将描述的缺陷,它也会失败)。

如果我将临时表中创建的字段名称更改为 XA、XB、XC、XD(计划在导入后更改字段名称,一旦数据经过验证并正在附加该表,该表将成为其最终的表) home)正确的数据会进入“正确”字段,但前提是导入文件中正好有 4 列。如果存在第五个,我会得到以下字段:

Field5 -- contains GenID data

XA -- contains Surname

XB -- contains GivenNames

XC -- contains OtherInfo

XD -- contains the data that was in the 5th column in the import file

如果我将导入的数据附加到具有正确结构的现有(空)表而不是允许导入创建新表,也会出现同样的问题。

关于如何完成这项工作的任何建议,或者对于其他可以处理大型导入 csv 数据集中的文本和多行备注字段的方法的建议,在这些方法中不能保证用户不包含无关的列结束?我没有任何能力编辑导入 csv - 所有数据更改都需要在 Access 内进行,并且 csv 文件必须在整个过程中保持不变。

Blindingly Obvious 部门为您带来的此更新:

如果我将导入的字段命名为“Field1”、“Field2”等,任何额外的字段都应按顺序插入这些字段之后,因此额外的字段不是问题。我仍然更愿意导入正确的字段名称。

最佳答案

考虑使用查询来导入 CSV 数据。此查询从我的 CSV 文件中选择前 4 列:

SELECT csv.F1, csv.F2, csv.F3, csv.F4
FROM [Text;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=437;DATABASE=C:\Users\hans\Documents].[no_field_names.csv] As csv;

该 CSV 文件不包含字段名称,因此 Access 将它们分配为 F1 到 F4。实际上,CSV 包含超过 4 列,但我只想要前 4 列(我认为这符合您的情况)。

如果您在查询设计器中构建并测试类似的查询,请注意它可能会将 FROM 子句更改为类似这样的内容...

FROM (Text;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=437;DATABASE=C:\Users\hans\Documents) no_field_names.csv As csv;

...那是行不通的。因此,每次 Access 进行无用的更改时,您都必须再次检查并更正它。

一旦获得返回所需内容的 SELECT 查询,您就可以将其转换为 INSERT 查询。

INSERT INTO YourTable (GenID, Surname, GivenNames, OtherInfo)
SELECT csv.F1, csv.F2, csv.F3, csv.F4
FROM [Text;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=437;DATABASE=C:\Users\hans\Documents].[no_field_names.csv] As csv;

但是,我不确定数据源中的备注字段会发生什么情况。如果它不会阻止查询正常工作,至少这种方法应该允许您提取正确的字段并将它们存储在正确的目标字段中。

关于ms-access - 从 CSV 导入 Access 时字段顺序错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20329806/

相关文章:

ms-access - MS Access 太多子窗体错误 "There isn' t 没有足够的内存来执行此操作”

vba - 在 VBA 中遍历对象浏览器

oracle - 如何在Windows中通过SqlDeveloper或CMD将dmp文件导入到oracle DB?

excel - 当 Target 在验证列表中时,Application.Intersect 失败

python - 根据值将成对转换为具有不同行数的列表

sql - 在 Access 中聚合 bool 数据

database - 使用 SQL Azure 部署 Microsoft Access 应用程序

将 csv 数据文件导入 DB2 的 Linux shell 脚本

r - 通过可共享的谷歌驱动器链接将 csv 读入 R

vba - 忽略图表VBA中的空单元格