【问题标题】:Method 'Add' of object "workbooks" failed - Importing excel workbook with vba Access 2007对象“工作簿”的“添加”方法失败 - 使用 vba Access 2007 导入 excel 工作簿
【发布时间】:2013-04-10 18:18:19
【问题描述】:

已解决:我已接受 Siddharth 的以下回答。我非常感谢大家的帮助,我对迅速的反应感到惊讶。来到这个社区寻求帮助时,我总是能学到一些新东西,你们太棒了。


感谢您花点时间查看我的消息。我已经编写了一个脚本(这在很大程度上要感谢这里对 SO 的大力帮助),它需要一个 excel 工作簿并将每个工作表导入到 Access 2007 数据库中的一个单独的表中。该脚本过去在我的 PC 上运行良好,但由于最近从硬件故障中恢复,我无法让该脚本运行。最重要的是,我的客户收到的错误消息与我自己的不同。

问题的很大一部分与我的对象引用有关,当我从工具菜单添加 Microsoft Excel 14 对象库作为引用时,一切正常。但是,客户在其系统上安装了不同版本的 Office,并希望将此应用分发给可能安装了其他版本的 Office 的其他人。我试图实现某种形式的后期绑定,但我可能没有正确地解决这个问题。代码如下:

编辑:当前代码再次更新,与下面 Siddharth 接受的帖子相关

Private Sub Command101_Click()
    On Error GoTo Err_Command101_Click

    ' Set up excel object
    Dim excelApp As Object
    Set excelApp = CreateObject("Excel.Application")

    ' Set up workbook object
    Dim excelbook As Object

    ' Set up file selection objects with parameters
    Dim fileSelection As Object
    Dim intNoOfSheets As Integer, intCounter As Integer
    Dim strFilePath As String, strLastDataColumn As String
    Dim strLastDataRow As String, strLastDataCell As String

    ' Prompt user with file open dialog
    Set fileSelection = Application.FileDialog(1)
    fileSelection.AllowMultiSelect = False
    fileSelection.Show

    ' Get the selected file path
    strFilePath = fileSelection.SelectedItems.Item(1)
    ' Open the workbook using the file path
    Set excelbook = excelApp.Workbooks.Open(strFilePath)
    ' Get the number of worksheets
    intNoOfSheets = excelbook.Worksheets.Count
    ' Set up object for current sheet name
    Dim CurrSheetName As String
    ' Disable errors
    DoCmd.SetWarnings False

    ' Loop through each sheet, adding data to the named table that matches the sheet
    For intCounter = 1 To intNoOfSheets
        excelbook.Worksheets(intCounter).Activate

        DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, _
        excelbook.Worksheets(intCounter).Name, strFilePath, True, _
        excelbook.Worksheets(intCounter).Name & "!" & _
        Replace(excelbook.Worksheets(intCounter).UsedRange.Address, "$", "")
    Next

    ' Close Excel objects
    excelbook.Close
    excelApp.Quit
    Set excelApp = Nothing
    ' Confirmation message
    MsgBox "Data import Complete!", vbOKOnly, ""
    DoCmd.SetWarnings True

Err_Command101_Click:
    MsgBox Err.Description
End Sub

Set excelbook = excelApp.Workbooks.Add 行上的客户端似乎出现此消息:

我的问题有点双重: a) 我是否正确实施了后期绑定?和 b) 如何在确保脚本独立于特定 Office 版本的同时解决此错误?

感谢您提供的任何帮助!

【问题讨论】:

  • 那行没有错。能不能暂时把On Error GoTo Err_Command101_Click去掉,在Set excelApp = CreateObject("Excel.Application")后面加上这个excelApp.Visible = True现在调试每一行。哪一行给出了错误?
  • 在我自己的机器上:文件打开提示打开,我选择了一个文件。我收到错误“运行时错误'424:需要对象”。不幸的是,客户端是远程的,所以我无法在他们的机器上进行测试。
  • FWIW,我尝试编译您的代码,但它被 DoCmd.TransferSpreadsheet 语句中的 ActiveSheet 引用阻塞:“编译错误:未定义变量。”。
  • 我同意@GordThompson:我在测试中成功到达For Loop
  • I get the error "Run-time error '424: Object required" 哪一行?

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


【解决方案1】:

我相信错误在这一行

DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, ActiveSheet.Name, _
    strFilePath, True, _
    excelbook.Worksheets(intCounter).Name & "!" & _
    Replace(excelbook.Worksheets(intCounter).UsedRange.Address, "$", "")

ActiveSheet.Name

将其更改为excelbook.Worksheets(intCounter).Name

在后期绑定中,代码将无法理解Activesheet 是什么

跟进

您收到编译错误,因为您没有在DoCmd.TransferSpreadsheet 的第一行末尾添加“_”

复制以下代码并将其粘贴到您的代码中。

DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, _
excelbook.Worksheets(intCounter).Name, _
strFilePath, True, _
excelbook.Worksheets(intCounter).Name & "!" & _
Replace(excelbook.Worksheets(intCounter).UsedRange.Address, "$", "")

【讨论】:

  • 确定调试该行,除了 MSACCESS 常量,检查变量其余部分的值是多少。例如excelbook.Worksheets(intCounter).NamestrFilePathexcelbook.Worksheets(intCounter).Name & "!" & _ Replace(excelbook.Worksheets(intCounter).UsedRange.Address, "$", "")
  • DoCmd.TransferSpreadsheet 中,将ActiveSheet.Name 替换为excelApp.ActiveSheet.Name。 (ActiveSheet 是 Excel 应用程序对象的属性。该更改允许代码在没有 Excel 引用集的情况下从我的 Access 2007 编译而不会出错。)
  • @HansUp:是的,这也可以,但由于 Miguet 使用这条线excelbook.Worksheets(intCounter).Activate,这意味着excelbook.Worksheets(intCounter) 是活动表。
  • 您是否在DoCmd.TransferSpreadsheet 的第一行之后添加了, _
  • 刷新页面。从FOLLOWUP 复制代码。现在测试一下?
【解决方案2】:

Workbooks.Add 方法创建一个新工作簿。我不明白你为什么要使用它。似乎您希望用户选择现有工作簿并打开它,因此您应该改用Workbooks.Open

至于您是否正确实现了后期绑定,请确保您的代码模块在其声明部分包含Option Explicit(有关有用的详细信息,请参阅 Gord 的回答),然后从 VB 编辑器的主菜单运行 Debug->Compile。这种努力会提醒您代码中的任何内容(对象、属性、方法、常量),您需要进一步工作以使其与后期绑定兼容。

这是一个很大的危险信号:

DoCmd.SetWarnings False

关闭SetWarnings 可以抑制错误信息,您需要这些信息来帮助理解为什么您的代码没有按照您的意愿运行。如果您觉得必须在生产代码中关闭 SetWarnings,至少在开发和调试期间将其保持打开状态。

【讨论】:

  • 我已注释掉该行并采纳了 Siddharth 的建议添加 excelApp.Visible = True。有了这个文件确实打开并显示了,但我仍然收到“需要对象”运行时错误。
  • 感谢您的编辑。我现在将禁用警告 False。
  • + 1 BTW 不错的收获 - 关于使用 Workbooks.Add 是徒劳的
【解决方案3】:

我将添加此内容仅供参考...在 VBA IDE 窗口中选择 Tools > Options... 并确保“需要变量声明”框中有复选标记:

然后,检查所有现有模块以确保前两行是

Option Compare Database
Option Explicit

Option Explicit 语句将添加到您创建的任何新模块中,但您需要自己为任何现有模块添加它。

【讨论】:

  • @MiguetSchwab Option Explicit 告诉编译器只接受已明确声明的变量引用(例如,在 Dim 语句中)。如果没有该选项,编译器将“错过”拼写错误并假设 itemiten 是两个不同的变量,即使您的代码具有 Dim item As whatever 但从未声明过 iten
猜你喜欢
  • 2018-12-29
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多