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更好。