在Excel公式中引用dynamic命名范围

Excel中有一个表格,列标题对应于工作簿中其他位置的dynamic命名区域的一部分。 例如,我有这些列标题:“10”,“20”等,以及这些dynamic命名范围:“ExampleRange10”,“ExampleRange2”等。我想input一个VLookup公式,通过连接引用ExampleRange10string“ExampleRange”和列标题“10”。 这将允许我简单地扩展表中所有列的公式,而不是在每列公式中手动input“ExampleRange10”,“ExampleRange20”等。

我意识到了INDIRECT函数,并且在过去已经成功地使用了它的命名范围,但是在这种情况下似乎并没有使用dynamic命名范围。 我猜这是一个细微差别,与Excel定义的dynamic命名范围有关(它们不会显示在公式栏左侧的命名范围下拉列表中,并且它们在VBA中有一些有趣的属性, 例如)。 有没有一种方法可以将INDIRECT公式与dynamic命名范围结合使用,还有另外一种方法可以解决这个问题吗?

编辑 :这里是使用的确切公式。
这是主要公式: =VLOOKUP(B2,INDIRECT("ExampleRange"&C1),2,FALSE)其中C1包含“10”,我的名为“ExampleRange10”的dynamic命名范围的公式为: =OFFSET(Sheet1!$F$2,0,0,COUNTA(Sheet1!$F$2:$F$25),2) 。 主公式返回“#REF!”,但是当我删除dynamic命名范围公式并将“ExampleRange10”简单定义为静态范围时,它会正常工作。

在进一步的研究之后,我可以说最好的办法是,Excel的INDIRECT函数根本不适用于dynamic范围。 有可能是一个聪明的方式来解决使用INDIRECT并坚持非VBA的Excel世界,但我不知道这样的方式。 相反,我最终创build了一个非常类似于这里描述的用户定义函数。 我改变了我的主要公式读取=VLOOKUP(B2,DINDIRECT("ExampleRange"&C1),2,FALSE) ,其中DINDIRECT是我创build的VBA函数的名称。

唯一的缺点(这可能是也可能不是这个缺点,取决于你如何看待这个select)是这个工作簿必须保存为一个启用macros的工作簿,而使用自定义函数不是很自我logging需要向其他用户稍加解释。 所有的事情考虑,但是,这是我可以接受的解决scheme。

对于链接厌恶,这里是代码:

 Public Function DINDIRECT(sName As String) As Range Dim nName As Name On Error Resume Next Set nName = ActiveWorkbook.Names(sName) Set nName = ActiveSheet.Names(sName) On Error GoTo 0 If Not nName Is Nothing Then Set DINDIRECT = nName.RefersToRange Else DINDIRECT = CVErr(xlErrName) End Function 

注意:尽pipe这个解决scheme有效,但我不打算接受我的答案,因为我不想阻止其他人发布更好的解决scheme。 此外,我是新来的网站,很抱歉,如果我通过回答我自己的问题打破任何礼仪守则……我只是想我会分享我使用的确切的解决scheme,以防其他人觉得有用。

我最近碰到了这个确切的砖墙,你已经猜到的答案就是你不能用INDIRECT来引用dynamic命名的范围。

但是,您可以使用dynamic范围公式本身作为INDIRECT的参数,但这对您想要执行的操作没有用处。 有点PITA,因为它是那种function,将是非常有用的。

如果你的数据有10,20等标题,那么你不需要使用间接。 为什么不使用索引/匹配来select你需要的数据呢?

例如命名整个表ExampleRanges并使用此公式:

 Index(ExampleRanges, match(B2, index(ExampleRanges, , 1), 0), match(C1, index(ExampleRanges, 1,), 0)) 

未经testing,但我认为这将工作:

用户定义的函数返回你的dynamic命名的范围的地址:

 Function Named_Range_Address(Range_Name As Range, _ Optional SheetName As Boolean) As String Dim strName As String Application.Volatile If SheetName = True Then strName = "'" & Range_Name.Parent.Name & "'!" & Range_Name.Address Else strName = Range_Name.Address End If Named_Range_Address = strName End Function 

那么你应该可以使用你的查找公式:

 =VLOOKUP(B2,INDIRECT(named_range_address("ExampleRange"&C1,TRUE)),2,FALSE) 

我知道这是相当古老的,但我只是遇到了这个,并认为我会添加一个解决scheme,避免任何VBA编码,以防止其他人谁在这个绊倒:

 =VLOOKUP(B2,CHOOSE(C1/10,example10,example20,example30,example40),2,0) 

这是假设命名约定是10,20,30等,并不会理想的数百个范围。

今天,我正在修补Excel命名的范围,我发现虽然你不能在INDIRECT()调用本身中计算范围的名字,但你仍然可以通过添加一个纯粹的“Excel方式”一个中间步骤:只要创build一个隐藏的单元格,在其中计算命名的范围。

例如,假设A1包含范围名称的“dynamic部分”,那么在A2使用公式= "ExampleRange" & A1 ,现在您可以使用全部范围名称,您可以使用它作为= INDIRECT(A2)

添加一个新的扭曲,有可能使用地址和间接函数命名的范围。 我有一个情况,我设置一系列表的命名范围,并使用以下内容:

 Named Range: WWDH-FF-PI which points to Linear!$A$19 (first cell in table) 

得到地址:$ T $ 56:= ADDRESS(MATCH(S56,Linear!A:A,0),1,1,1,“Linear”)

然后使用多次复制的偏移函数来创build数据透视表:

 =OFFSET(INDIRECT($T$56),C5,$T$57-1) 

所以,地址function可以embedded(或包装)到间接function来创build一个dynamic单元地址。

我知道这是一个非常古老的话题,但是我有同样的问题,所以也许我的解决scheme可以帮助未来的人。

基本上,我创build了一个macros,将保存时删除和重新定义的范围,并给它一个名字。 因此,INDIRECT函数可以工作,因为范围不是dynamic的。 您只需在将任何值添加到命名范围后保存工作簿

 Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Dim a, b, c, d, e, f As Integer Dim data As Worksheet Set data = ThisWorkbook.Worksheets("Data") a = data.Range("A" & Rows.count).End(xlUp).row b = data.Range("B" & Rows.count).End(xlUp).row c = data.Range("C" & Rows.count).End(xlUp).row d = data.Range("D" & Rows.count).End(xlUp).row e = data.Range("E" & Rows.count).End(xlUp).row f = data.Range("F" & Rows.count).End(xlUp).row ActiveWorkbook.Names("KP").Delete ActiveWorkbook.Names("KPT").Delete ActiveWorkbook.Names("AP").Delete ActiveWorkbook.Names("APT").Delete ActiveWorkbook.Names("DISC").Delete ActiveWorkbook.Names("SEATS").Delete ActiveWorkbook.Names.Add Name:="KP", RefersTo:="=Data!$A$2:$A$" & a ActiveWorkbook.Names.Add Name:="KPT", RefersTo:="=Data!$B$2:$B$" & b ActiveWorkbook.Names.Add Name:="AP", RefersTo:="=Data!$C$2:$C$" & c ActiveWorkbook.Names.Add Name:="APT", RefersTo:="=Data!$D$2:$D$" & d ActiveWorkbook.Names.Add Name:="DISC", RefersTo:="=Data!$E$2:$E$" & e ActiveWorkbook.Names.Add Name:="SEATS", RefersTo:="=Data!$F$2:$F$" & f End Sub