从CSV导入到Access时字段顺序错误

科尔谷女孩

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

将要导入五到六组不同的数据集,范围从4列到24列,并且我试图从最简单的数据集开始提出一种可用于所有这些方法的方法。

这个最简单的导入文件将是一个具有4列且没有标题的csv文件,并且应最终出现在具有以下字段的临时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(计划在导入后更改字段名称,则在数据经过验证并被追加到表之后,它将成为其最终位置)正确的数据进入“正确”字段,但前提是导入文件中恰好有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文件必须不更改地通过此过程。

致盲部门向您带来的此更新:

如果我将导入的字段命名为“ 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;

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章