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

时间:2015-05-18 15:48:05

标签: excel excel-vba ms-access access-vba vba

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

事实证明,当我使用DoCmd.TransferSpreadsheet导入时,它几乎复制了所有记录。在4000行电子表格中,我创建的Access表有7998行。在研究这个问题时,我遇到了一些关于如何在导入后删除重复项的建议。在我的情况下,这根本不是解决方案,因为我的数据中包含我需要保留的重复行。

简而言之,我需要完全导入电子表格,因为它位于重复的行和所有...但没有导入过程创建额外的重复项。看来这应该是一个非常基本的过程,我真的很想知道这个导入过程是如何创建重复的行开头的?我的意思是它应该只导入那些数据!

这是在紧迫的截止日期前的关键时刻,我没有指望这个令人惊讶的问题...所以任何帮助都会非常感激。

以下是令人讨厌的代码行:

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

我觉得这不重要......但我正在使用Open File Dialog来获取电子表格。如果有人认为这会有所帮助,我可以发布完整的程序。

如需进一步说明,请参阅此程序的完整代码。请注意,我正在将导入的文件名中的表名更改为我自己的枚举名,因为我一次导入多张表。

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

End Sub

1 个答案:

答案 0 :(得分:3)

注意:在我们了解问题的真正原因之前,我提交了这个答案。跳至 Post Mortem 获取解释。我将保留此答案的其余部分,因为查询包含在查询的FROM子句中的连接字符串的电子表格是一种有用的技术,可以帮助未来的读者。

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

同时,考虑到您的时间紧迫,请创建一个Access查询来获取工作表数据。

以下是在Access 2010系统上测试的示例:

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

如果您创建了一个类似的查询,并且它只返回您想要的数据(没有多余的重复项),则可以将其转换为“追加查询”并将该数据添加到合适的现有表中。这也意味着DoCmd.TransferSpreadsheet正在返回正确的结果,您需要检查这段代码是否多次运行。

找出嵌入式连接字符串的快捷方法是创建指向工作表的链接。然后,您可以检查链接属性以获取查询所需的内容:

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

收集该信息后,您无需保留链接以使查询正常工作。另一方面,如果您可以保留链接,查询可能更简单。

Post Mortem

Anthony为同一组选项发现了两次名为DoCmd.TransferSpreadsheet acImport的代码。因此,每个电子表格的数据都是无意中导入的两次。

相关问题