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

时间:2015-05-15 12:33:35

标签: excel vba excel-vba

我正在寻找一种从任意工作簿返回值的方法(在运行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

这是理想的行为。

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

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

我经过几个小时的拔毛后发现,这个功能不能直接在UDF中直接使用,这个UDF设计用于手动打开的工作簿,而且这是微软方面的。但我也发现有一种可能的解决方法!

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

这些解决方案需要硬编码的文件路径,这违背了我的预期用途。

是否有人了解如何实现上述两个链接中的任何一个,但是具有任意文件路径(如在,与包含在调用UDF的单元格相邻的单元格中)? / p>

注意:我尝试在sub中执行繁重的工作,只需将sub调用为UDF中的第一行,将结果设置为全局var,并在子结束后将UDF返回值设置为相同的var ,但要么我崩溃和烧得很厉害,要么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

我没有针对打开的文件测试sub / func组合,但是当所有代码都在Function中并且有问题的文件是手动打开的时候,它运行得很完美。单步执行代码并使用Debug.Print,我看到即使“Workbooks.Open ...”没有任何可辨别的错误,工作簿实际上也没有打开,因此,当我们尝试使用工作簿对象时设置工作表,函数/子终止。

1 个答案:

答案 0 :(得分:1)

这可以通过 UDF() Event 宏的组合来实现。

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

  1. 路径
  2. 文件名
  3. sheetname
  4. 单元格地址
  5. 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
    

    记下单引号的位置。

    enter image description here

    然后我们使用 Calculate 事件宏来检测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
    

    Calculate宏需要知道UDF返回字符串(C3)的位置,并且还需要知道将检索到的数据放在何处(C4)。 / p>