【问题标题】:Import excel rows into MS-Access without header, VBA, TransferSpreadsheet method将不带标题、VBA、TransferSpreadsheet 方法的 Excel 行导入 MS-Access
【发布时间】:2019-12-12 09:34:37
【问题描述】:

(使用 MS Office Professional Plus 2016)

我调整了这个子过程,将 MS-Excel 文件/它们的第一个工作表(称为“表”)导入 MS-Access 数据库。代码导航到指定的文件夹并导入该文件夹中的所有 .xls 文件。所有 .xls 文件都具有相同的格式。我正在使用 DoCmd.TransferSpreadsheetDo While

但是,各个 .xls 文件中“表格”工作表中的相关数据从第 29 行开始,字段名称在第 28 行。

我的问题是:有没有办法只将第 28 行中的字段名称和第 29 行中的数据导入到最后一个非空行 - 一种将其包含在 Do While 中的方法?也许使用 TransferSpreadsheet 命令中的 Range 选项,但我不知道如何在“第 x 行到最后一个非空行”范围内表达。

Option Compare Database

Sub importfiles()

Dim blnHasFieldNames As Boolean
Dim strWorksheet As String, strTable As String
Dim strPath As String, strPathFile As String

' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = False

' Replace C:\Documents\ with the real path to the folder that
' contains the EXCEL files
strPath = "E:\importfiles\"

' Replace worksheetname with the real name of the worksheet that is to be
' imported from each file
strWorksheet = "Table"

' Import the data from each workbook file in the folder
strFile = Dir(strPath & "*.xls")
Do While Len(strFile) > 0
      strPathFile = strPath & strFile
      strTable = "tbl_" & Left(strFile, InStrRev(strFile, ".xls") - 1)

      DoCmd.TransferSpreadsheet acImport, _
            acSpreadsheetTypeExcel9, strTable, strPathFile, _
            blnHasFieldNames, strWorksheet & "$"

      ' Uncomment out the next code step if you want to delete the
      ' EXCEL file after it's been imported
      ' Kill strPathFile

      strFile = Dir()
Loop
MsgBox ("The sub was run.")

End Sub


Public Function runImport()

Call importfiles

End Function
(I slightly adapted this code from http://www.accessmvp.com/KDSnell/EXCEL_Import.htm#ImpWktFilesSepTbls)


EDIT:
[Type mismatch, see Max's answer][1]
 [Screenshot of excel file][2]

 [access table][3]

 [Compile error(see Max's answer)][4]


[for max][5]
[for max2][6]
[for max3][7]


  [1]: https://i.stack.imgur.com/PZFnl.png
  [2]: https://i.stack.imgur.com/IjvKc.png
  [3]: https://i.stack.imgur.com/jzOXu.png
  [4]: https://i.stack.imgur.com/uHUTK.png
  [5]: https://i.stack.imgur.com/slAeG.png
  [6]: https://i.stack.imgur.com/g6fNr.png
  [7]: https://i.stack.imgur.com/gFNqA.png

【问题讨论】:

  • 据我所知,transferspreadsheet 只导入适合表格的行。如果您设置列定义,例如为第一行的“整数”并且 excel 为空或前 28 行中的文本,不会导入行。尝试找到一列,其中只有第 28:X 行满足特定要求,并将其设置在您的表格中。
  • 感谢您的建议。我确实将第一列设置为整数,只有相关数据在工作表的第一列中有一个整数(数字)。我收到错误消息:运行时错误“2391”:目标表“Test1212”中不存在字段“F1”。 Transferspreadsheet 似乎并不关心这一点。也许有一些代码会在每次导入之前删除相应 excel 工作表中不相关的标题?
  • 可以发一张excel的截图吗?
  • 我添加了截图链接。

标签: excel vba ms-access


【解决方案1】:

这里有一个建议,即在导入之前打开 excel 文件并定义要导入的区域。负 27 或多或少是被猜到的,请在该区域的 excel 中检查 - 可能不同,只需更改数字即可。 第二个更改是您在 transferspreadsheet-command 中定义要导入的区域。

我希望这会有所帮助。 最大

Sub importfiles()

Dim blnHasFieldNames As Boolean
Dim strWorksheet As String, strTable As String
Dim strPath As String, strPathFile As String

' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = False

' Replace C:\Documents\ with the real path to the folder that
' contains the EXCEL files
strPath = "E:\importfiles\"

' Replace worksheetname with the real name of the worksheet that is to be
' imported from each file
strWorksheet = "Table"

' Import the data from each workbook file in the folder
strFile = Dir(strPath & "*.xls")
Do While Len(strFile) > 0
      strPathFile = strPath & strFile



''''alter the excel file
        Call alter_excel(strPathFile, strWorksheet)

      DoCmd.TransferSpreadsheet acImport, _
            acSpreadsheetTypeExcel9, strTable, strPathFile, _
            blnHasFieldNames, "importarea"

      ' Uncomment out the next code step if you want to delete the
      ' EXCEL file after it's been imported
      ' Kill strPathFile

      strFile = Dir()
Loop
MsgBox ("The sub was run.")

End Sub

Function alter_excel(file As String, table As String)
Dim oXL As New Excel.Application
Dim oWB As Excel.Workbook
     Set oXL = CreateObject("Excel.Application") 
     Set oWB = oXL.Workbooks.Open(file)
        oWB.Activate
        Sheets(table).Select
        Range("A30:D" & WorksheetFunction.CountA(Columns(1)) + 5).Name = "importarea"

        oWB.Close True
        Set oWB = Nothing
        Set oXL = Nothing
End Function

【讨论】:

  • 非常感谢。我得到“编译错误:未定义用户定义的类型”(请参阅​​我帖子中的第三张图片)。我该怎么办?
  • 您必须添加对“Microsoft Excel 对象库”的引用,也可能是“Microsoft Office 对象库”
  • 好吧,我早就知道了……现在我得到:“运行时错误'91':对象变量或未设置块变量。也许它应该是“Dim oWS As Object” (函数的开头)而不是?调试器将“oWS.Select”标记为黄色
  • 不,我想我忘了设置工作表...我稍后再仔细看看...
  • 在 oWB.Activate 作为下一行添加 set oWS = table ... 我认为应该可以完成这项工作
【解决方案2】:

只需在TransferSpreadsheet范围 参数中使用从第一个到最后一个单元格的A1 样式地址,其中包括标题作为第一行。如果行是开放式的,请输入一个非常大的末尾行,有趣的是未导入未使用的范围!

Do While Len(strFile) > 0
   strPathFile = strPath & strFile

    DoCmd.TransferSpreadsheet acImport, _
        acSpreadsheetTypeExcel9, "myFinalTable", strPathFile, _
        True, strWorksheet & "$A29:D1000"

   strFile = Dir()
Loop

或者,您可以直接在 Access SQL 中查询 Excel 工作簿:

SELECT *
FROM [Excel 12.0 Xml; HDR = Yes;Database=C:\Path\To\myWorkbook.xlsx].[mySheet1$A29:D1000]

事实上,您可以随后从 Excel 源运行追加查询(可能比TransferSpreadsheet 更有效)。

Do While Len(strFile) > 0
   strPathFile = strPath & strFile

   sql = "INSERT INTO myFinalTable" _
         & " SELECT * " _
         & " FROM [Excel 12.0 Xml; HDR = Yes;Database=" & strPathFile & "].[" & strWorksheet & "$A29:D1000]"

   Currentdb.Execute sql, dbFailOnError

   strFile = Dir()
Loop

请注意:为了遵守数据库规范化,您应该将所有数据迁移到一个的长表,而不是可以运行到数百甚至更多的单独的电子表格表。与 Excel 电子表格不同,Access 表格没有行数限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多