我正在寻找一种从任意工作簿返回值的方法(在运行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 ...”没有任何可辨别的错误,工作簿实际上也没有打开,因此,当我们尝试使用工作簿对象时设置工作表,函数/子终止。
答案 0 :(得分:1)
这可以通过 UDF()和 Event 宏的组合来实现。
要从已关闭的工作簿中检索数据,我们需要做四件事:
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 事件宏来检测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>