Excel UDF:从任意closures的外部工作簿中检索值

我正在寻找一种方法来从任意工作簿中返回值(在运行UDF时工作簿也不会打开),这是根据UDF中的计算定义的。

伪代码:

Start by calling =someFunc(currentCell) in any cell Function someFunc(adr As Range) region_eval = "C" & Range(adr).Row ' where column C contains string entries, all of which have a corresponding sub-dir (see fileReference). networkLocation = ActiveWorkbook.Path networkPath = networkLocation & "\Locations\" fileReference = networkPath & region_eval & "\ProductList.xlsx" Workbook.Open fileReference readonly Perform index/match call against some sheet in this workbook someFunc = returned value Close workbook and end function 

这是所需的行为。

返回所需值的逻辑是OK的,我已经尝试了一个更简单的公式,并在一个UDF依赖于手动打开的文件:

 INDEX(locationlist_$A$5000, MATCH(masterlist_A1, locationlist_$B$5000)) 

我经过几个小时的摸索,发现这个function并不是直接可用在一个UDF中,而这个UDF是专门用来处理那些没有手动打开的工作簿的,而且这个function是微软方面的。 但我也发现有一个可能的解决方法!

参考:
1. https://stackoverflow.com/a/27844592/4604845
http://numbermonger.com/2012/02/11/excel-pull-function-creating-dynamic-links-to-closed-workbooks/

这些解决scheme需要硬编码的文件path,这打破了我预期的用途。

有没有人知道如何实现上述两个链接中的任何一个,而是使用任意的文件path(如在UDF被调用的单元格附近的单元格中所包含的)?

注意:我试着在一个子文件中执行繁重的操作,只要将这个子文件作为UDF中的第一行调用,将结果设置为一个全局variables,并在子文件完成后将UDF的返回值设置为相同的variables,我崩溃,烧得相当沉重,Excel看透了我的诡计,否认了这一点。

编辑:

这是sub / func组合。

 Option Explicit Public networkLocation As String, networkPath As String, fileReference As String, c_formula As String Public sheet_src As Worksheet, sheet As Worksheet, wb_src As Workbook, wb As Workbook Public region_eval As String, sheetName_src As String, sheetName As String, regionPath As String, fileName As String Sub findProductStatus(adr As Range) networkLocation = ActiveWorkbook.Path networkPath = networkLocation & "\Locations\" sheetName_src = "Sheet1" sheetName = "Sheet1" Set wb_src = ThisWorkbook Set sheet_src = wb_src.Sheets(sheetName_src) region_eval = Range("I" & adr.Row) regionPath = networkPath & region_eval 'fileReference = regionPath & "\ProductList.xlsx" fileName = "ProductList.xlsx" ChDir regionPath Workbooks.Open fileName:=fileName, ReadOnly:=True 'Set wb = Workbooks.Open(fileName:=ThisWorkbook.Path & "\Locations\Test\ProductList.xlsx", ReadOnly:=True) Set wb = Workbooks("ProductList.xlsx") Set sheet = wb.Sheets(sheetName) c_formula = Application.WorksheetFunction.Index(sheet.Range("$K$2:$K$5000"), Application.WorksheetFunction.Match(sheet_src.Range("A" & adr.Row), sheet.Range("$A$2:$A$5000"), 0)) End Sub Function getProductStatus(adr As Range) As String Call findCourseStatus(adr) getCourseStatus = c_formula wb.Close End Function 

我还没有testing打开的文件的子/ func组合,但是当所有的代码都在函数里面,而且这个文件被手动打开的时候,它的工作是完美无缺的。 通过代码和使用Debug.Print,我看到,即使“Workbooks.Open …”通过没有任何可辨别的错误,工作簿实际上并没有打开,因此,当我们尝试使用工作簿对象设置工作表,函数/子终止。

这可以通过UDF()Eventmacros组合来实现。

要从封闭的工作簿中检索数据,我们需要四件事情:

  1. path
  2. 文件名
  3. 工作表名称
  4. 单元地址

UDF唯一要做的就是以非常特定的格式显示这些项目:

 Public Function someFunc() As String Dim wbPath As String, wbName As String Dim wsName As String, CellRef As String Dim Ret As String wbPath = "C:\TestFolder\" wbName = "ABC.xls" wsName = "xxx" CellRef = "B9" someFunc = "'" & wbPath & "[" & wbName & "]" & _ wsName & "'!" & Range(CellRef).Address(True, True, -4150) End Function 

注意单引号的位置。

在这里输入图像说明

然后,我们使用Calculate事件macros来检测UDF的执行并检索数据:

 Private Sub Worksheet_Calculate() Dim r1 As Range, r2 As Range Set r1 = Range("C3") Set r2 = Range("C4") r2.Value = ExecuteExcel4Macro(r1.Value) End Sub 

计算macros需要知道UDF返回string(C3)的位置 ,而且还需要知道将检索到的数据(C4)放在哪里。