使用DoCmd.TransferSpreadsheet将Excel电子表格导入到Access中创build重复项

我碰到一个非常意外的问题,我有一个Excel电子表格,我正在导入到Microsoft Access数据库使用: DoCmd.TransferSpreadsheet 。 它似乎工作正常…但现在,我已经到了我的项目的最后阶段,并开始计算导入的数据…我注意到,所有的计算都是他们应该的两倍。 罪魁祸首原来是来自一个非常惊人的来源!

事实certificate,当我使用DoCmd.TransferSpreadsheet导入时,它几乎是复制每个logging。 在4000行电子表格中,我创build的Access表格有7998行。 在研究这个问题时,我已经遇到了多个关于如何在导入之后删除重复项的build议。 这对我来说根本就不是一个解决scheme,因为我的数据里面有重复的行,我需要保留。

总之,我需要完全导入电子表格,因为它位于重复行和所有…但没有导入过程中创build额外的重复项。 看来这应该是一个非常基本的过程,并且真的很好奇,知道这个导入过程是如何创build重复行? 我的意思是,它应该只导入那里的数据!

这是紧迫的时间紧迫的时间,我没有指望这个令人惊讶的问题…所以任何帮助将非常感激。

这是违规的代码行:

 DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel8, strTableName, strFileName, True 

我不认为这很重要,但我正在使用打开文件对话框来获取电子表格。 如果有人认为它会帮助,我可以发布完整的程序。

为了进一步澄清这里是我完整的代码这个过程。 请注意,我正在将导入的文件名称中的表名更改为我自己的枚举名称,因为我一次导入多个工作表。

 Private Sub ImportFiles() Dim strFileName As String Dim strTableName As String Dim fDialog As Office.FileDialog Dim varFile As Variant Dim lngProcessID As Long CancelProcessing = False ' Set up the File Dialog. ' Set fDialog = Application.FileDialog(msoFileDialogFilePicker) With fDialog ' Allow user to make multiple selections in dialog box ' .AllowMultiSelect = True ' Set the title of the dialog box. ' .Title = "Select files to import" .Filters.Clear .Filters.Add "All Files", "*.*", 1 .Filters.Add "Excel Files", "*.xlsl", 2 .Filters.Add "Excel Files", "*.xls", 3 .Filters.Add "Excel Files", "*.accdb", 4 .Filters.Add "Excel Files", "*.mdb", 5 ' Show the dialog box. If the .Show method returns True, the ' ' user picked at least one file. If the .Show method returns ' ' False, the user clicked Cancel. ' If .Show = True Then lngProcessID = OpenCustomLoader() CountOfFiles = 0 ' Validate That All Fields Have Been Mapped For Each varFile In .SelectedItems If CancelProcessing = False Then CountOfFiles = CountOfFiles + 1 strTableName = "tblImport" & CountOfFiles strFileName = .SelectedItems(CountOfFiles) ' Import Table Into Access DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel8, strTableName, strFileName, True Call ValidateFields(strTableName) If CancelProcessing = True Then DoCmd.DeleteObject acTable, strTableName End If Next ' Prime File Count CountOfFiles = 0 'Loop through each file selected and add it to our list box. ' If CancelProcessing = False Then For Each varFile In .SelectedItems CountOfFiles = CountOfFiles + 1 strTableName = "tblImport" & CountOfFiles strFileName = .SelectedItems(CountOfFiles) ' Import Table Into Access DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel8, strTableName, strFileName, True DoCmd.TransferDatabase acExport, "ODBC Database", CurrentDb.TableDefs("dbo_tblStagingTable").Connect, acTable, strTableName, strTableName Call ImportFileData(strTableName) Next Call CopyStagingToInterests End If Call CloseCustomLoader(lngProcessID) Call CloseCustomLoader(lngProcessID) End If End With 

结束小组

注意 :在我们理解问题的真正原因之前,我提交了这个答案。 跳到Post Mortem的解释。 我将留下这个答案的其余部分,因为查询电子表格embedded查询的FROM子句中的连接string是一个有用的技术,这将有助于未来的读者。

我不明白为什么TransferSpreadsheet会复制您的电子表格数据。 这可能有助于向我们展示更多使用TransferSpreadsheet VBA过程的上下文,但可能不是全部。

同时,考虑到您的时间框架很紧,创build一个Access查询来获取工作表数据。

这是在我的Access 2010系统上testing的一个例子:

 SELECT s1.* FROM [Excel 8.0;HDR=YES;IMEX=2;DATABASE=C:\share\Access\temp.xls].[Sheet1$] AS s1 

如果你创build了一个类似的查询,并且它只返回你想要的数据(没有额外的重复),那么你可以将它转换为“附加查询”并将这些数据添加到合适的现有表中。 这也意味着DoCmd.TransferSpreadsheet返回正确的结果,你需要检查这段代码是否被多次运行。

找出embedded的连接string的一个快速方法是创build一个工作表的链接。 然后,您可以检查链接属性,以获取您需要查询的内容:

 ? CurrentDb.TableDefs("tblExcelData").Connect Excel 8.0;HDR=YES;IMEX=2;DATABASE=C:\share\Access\temp.xls ? CurrentDb.TableDefs("tblExcelData").SourceTableName Sheet1$ 

收集完这些信息之后,您不需要保持链接正常工作。 另一方面,如果你可以保持链接,查询可能会更简单。

postMortem

安东尼发现了相同的一组选项代码称为DoCmd.TransferSpreadsheet acImport两次。 所以每个电子表格的数据都被无意中导入了两次。