Excel VBA无法打开工作簿

时间:2011-10-07 22:40:17

标签: excel vba

首先:我使用的是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
遗憾的是,wbk在开放声明之后是没有的(我想提供更好的错误信息,但不知道我是怎么做的;我为真正的IDE和有用的语言提供了什么:/) 。绝对路径是正确的,并指向有效的excel xlsx文件。

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

单步执行时的图像: debugging info

7 个答案:

答案 0 :(得分:6)

我可以重现这个问题。当我尝试将此代码粘贴到用户定义的函数中时,它才会发生在我身上。

我相信这是设计的(引用是针对XL 2003的,但XL 2010上的情况也是如此)

  

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

     

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

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

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

答案 1 :(得分: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的第二个实例将不受干扰地完成工作。

答案 2 :(得分:1)

要在没有打开的情况下从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;\

[]的

答案 3 :(得分:1)

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

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

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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

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

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

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

答案 6 :(得分:0)

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

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"

我知道这不回答这个问题(这就是为什么我也登陆这个帖子,因为我无法打开文件而无法理解为什么会这样)

干杯, RV