Excel VBA无法打开工作簿

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

我的问题是以下几点:我需要访问不同的工作簿中的单元格,可能会被closures。 以下代码可以在networking上find:

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和一个有用的语言:/)。 绝对path是正确的,并指向一个有效的Excel的xlsx文件。

另外我假设这样做的最好方法是“caching”工作簿,而不是在每次调用函数时都打开/closures它? 任何可能出现的问题(除了在工作簿已经打开的情况下处理这种情况之外)?

图片,而通过: 调试信息

我可以重现这个问题。 它只发生在我尝试将此代码粘贴到用户定义的函数中。

我相信这是由devise(引用是XL 2003,但同样的事情发生在我的XL 2010)

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

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

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

我发现唯一的解决方法是通过一个普通的macros调用这种代码。 就像select单元格来应用它,然后循环select或类似的东西。

要从Workbook没有打开数据,您可以使用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;\ 

[]的

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

我有一个类似的问题,但在我的情况下,它是一个“Workbooks.Open(filename)”命令在embeddedWorkbook_BeforeSave的一个小例程开始。 VBA只是跳过代码行,就好像它不在那里,甚至不报告Err.Code或Err.Description。

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

看来,Workbook_BeforeSave禁用Excel打开更多的文件,我想这样做的一个很好的理由,因为文件>打开选项仍然在文件菜单中可见,但它不能被点击。 奇怪的是,打开工具栏图标/button仍然有效,所以虽然我可以从那里手动打开文件,但是不知道是不是因为从VBA代码中调用这个动作是不可能的,这就是为什么他们允许它?

你可以使用这个(类似于Bruno Leite提出的,但是要简单得多):

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

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

我花了一些想法,得出的结论是,你不能在执行UDF的时候混淆当前的excel实例的工作簿。 另一方面,打开excel的第二个例子就可以不受干扰地完成工作。

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

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

我build议您在打开调用工作簿的时候在worbook_open事件中为您打开新的工作簿。

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

然后由您的单元格调用的函数使用该全局variables,而不是试图打开一个新的工作簿。 这样你绕过的限制。

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