【问题标题】:Excel VBA can't open WorkbookExcel VBA 无法打开工作簿
【发布时间】:2018-05-24 22:52:43
【问题描述】:

首先:我使用的是 Excel 2007,但代码也必须适用于 Excel 2003。

我的问题如下:我需要访问不同工作簿中的单元格,该工作簿可能已关闭。以下代码随处可见:

Function Foo()
    Dim cell As Range
    Dim wbk As Workbook
    Set wbk = Workbooks.Open("correct absolute path")
    ' wbk is Nothing here so the next statement fails.
    Set cell = wbk.Worksheets("Sheet1").Range("A1")
    Foo = cell.Value
    wbk.Close
End Function

遗憾的是,在 open 语句之后 wbk 什么都没有(我很乐意提供更好的错误消息,但不知道该怎么做;我会为真正的 IDE 和有用的语言提供什么:/) .绝对路径正确,指向有效的excel xlsx文件。

我还假设最好的方法是“缓存”工作簿而不是每次调用函数时都打开/关闭它?任何可能的问题(除了必须处理工作簿显然已经打开的情况)?

单步执行时的图像:

【问题讨论】:

  • 您没有收到任何错误消息,Open 语句只返回 Nothing?我已尝试重现您的问题,但没有成功。你将不得不给我们更多的细节和背景。
  • @Jean-FrançoisCorbett 说“不”错误信息就是说,excel 只是继续执行。我看了一点,但找不到任何GetLastError() 或类似的,On Error Goto 没有指定任何异常对象?引用的东西基本上是整个函数,但我把它改成了完整的函数,也许有帮助。
  • "? Err.Number" 和 "? Err.Description" 在即时窗口中将为您提供有关运行时错误的信息。您需要为 On Error Goto 提供错误处理程序。当您说“下一条语句失败”时,您的意思是您在那里遇到运行时错误吗?如果是这样,是什么?如果不是,那么 Cell 是否也等于无?您是否尝试过使用非常简单的路径,例如指向“我的文档”中的文件?
  • @DougGlancy 我在生成的 excel 单元格中得到一个 #VALUE! ,一旦它尝试执行该行,执行就会停止(但这是意料之中的,我基本上是在尝试取消引用 null那里的指针)。是的,我已经尝试过D:\test.xlsx(所以权利肯定没有问题,也不会变得更简单)和我的用户文件夹。什么是即时窗口?我将“?Err.Description”作为监视表达式,但这显然不是您的意思,只是告诉我这是一个包含“?Err.Description”的字符串。
  • 好吧,我只是在 Open() 语句之后放了一个MsgBox Err.Description,遗憾的是它是空的,Err.Number 是 0..

标签: excel vba


【解决方案1】:

我可以重现这个问题。仅当我尝试将此代码粘贴到用户定义的函数中时才会发生这种情况。

我相信这是设计使然(报价适用于 XL 2003,但同样的事情发生在 XL 2010 上)

在自定义函数中使用 VBA 关键字

您可以在自定义函数中使用的 VBA 关键字的数量少于您可以在宏中使用的数量。除了将值返回到工作表中的公式或另一个 VBA 宏或函数中使用的表达式之外,不允许自定义函数执行任何操作。例如,自定义函数无法调整窗口大小、编辑单元格中的公式或更改单元格中文本的字体、颜色或图案选项。如果您在函数过程中包含此类“操作”代码,该函数将返回 #VALUE!错误。

http://office.microsoft.com/en-us/excel-help/creating-custom-functions-HA001111701.aspx

我发现的唯一解决方法是通过普通宏调用这种代码。比如选择要应用它的单元格,然后循环选择等。

【讨论】:

  • 其实这个错误是由UDF限制引起的。不允许在 UDF 中直接调用.Open。看看here
【解决方案2】:

你可以使用这个(类似于 Bruno Leite 提出的,但写起来更简单):

Dim excelApp As New Excel.Application
excelApp.Visible = False
Set WB = excelApp.Workbooks.Open(FileName, xlUpdateLinksNever, True)

由于 UDF 被重复调用,您应该确保在退出函数之前执行 excelApp.Quit(以及之前的 WB.close(False))以避免在您的盒子上运行无数 Excel 实例。

我对此进行了一些思考,得出的结论是,在执行 UDF 时,不能乱用当前 excel 实例的工作簿。另一方面,打开第二个 excel 实例可以不受干扰地完成这项工作。

【讨论】:

  • 但是...如果您必须重复使用 UDF,它会非常慢。
【解决方案3】:

要在未打开的情况下从 Workbook 获取数据,您可以使用 this,通过 ADO 连接。

要在 Excel 2007 中使用,请更改此设置

Microsoft.Jet.OLEDB.4.0

Provider=Microsoft.ACE.OLEDB.12.0

Extended Properties=\"Excel 8.0;HDR=Yes;\

Extended Properties=\"Excel 12.0;HDR=Yes;\

[]的

【讨论】:

    【解决方案4】:

    将我的例程放入工作簿模块中的单独宏中并从 Workbook_BeforeSave 代码中调用该宏的解决方法似乎成功了。

    我遇到过类似的问题,但在我的情况下,它是 Workbook_BeforeSave 中嵌入的一个小例程开始时的“Workbooks.Open(filename)”命令。 VBA 只是跳过代码行,就好像它不存在一样,它甚至不报告 Err.Code 或 Err.Description。

    对我来说唯一的线索是它是 Workbook_BeforeSave 例程的一部分,上面的 Functions 限制似乎表明这可能是一个可能的原因。所以我进一步挖掘以找到更多细节。

    Workbook_BeforeSave 似乎禁止 Excel 打开更多文件,我想这样做是有充分理由的,因为“文件”>“打开”选项在“文件”菜单中仍然可见,但无法单击。奇怪的是,打开工具栏图标/按钮仍然有效,所以虽然我可以从那里手动打开文件,但我想知道是不是因为无法从 VBA 代码调用此操作,这就是他们允许它的原因?

    【讨论】:

      【解决方案5】:

      您不必“设置”单元格,它是工作簿类的一部分(据我所知)。只需使用以下...

      foo = wbk.Worksheets("Sheet1").Range("A1").Value
      

      【讨论】:

      • Cell 不属于任何类。这是一个声明为范围的变量,因此必须对其进行设置。也许您正在考虑“单元格”,它是 Worksheet 对象的一个​​属性。您的建议确实缩短了代码,但没有解决问题。 -1
      • 是的,我可以重写所有内容以适应一行 - 如果我开始用 1 个字符命名我的变量,我什至可能会进入 Perl 程序员俱乐部,但唉,这真的不是总体目标;)
      • 你是对的,我忽略了我的答案。但是回去再试一次,它现在可以工作了。嗯,也许向我们发布您的(“正确的绝对路径”)?如果可能的话。因为否则您的代码可以正常工作..
      【解决方案6】:

      我建议您在打开调用工作簿时在 worbook_open 事件中打开新工作簿。

      然后您将新的工作簿引用存储在全局变量中。

      然后您的单元格调用的函数使用所述全局变量而不是尝试打开新工作簿。这样你就可以绕过限制。

      PS:当然要避免全局变量,某种容器会比直接全局变量更好。

      【讨论】:

        【解决方案7】:

        您可以使用以下代码以正确的方式检查错误:

        filelocation = c:\whatever\file.xlsx
        
        On Error GoTo Handler 'this is key as if the next row returns an error while opening the file it will jump to the Handler down there.
        Set wkb2 = Workbooks.Open(filelocation, ReadOnly)
        
        Handler:
        MsgBox "File " & filelocation & " does not exist or cannot be reached, please review and try again"
        

        我知道这并不能回答问题(这就是为什么我也登陆了这个帖子,因为我无法打开文件并且不明白为什么会这样)

        干杯, 房车

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-29
          • 1970-01-01
          • 2014-09-12
          相关资源
          最近更新 更多