在UDF中使用命名范围
我试图创build一个使用命名范围的UDF。 我命名的范围(“best_Grade”)是一个具有值的单个单元格。 (命名范围的范围是工作簿)。
在工作簿模块中,当我尝试使用命名范围创buildvariables时,我得到了
运行时错误'1004':对象'_Global'的'范围'的方法失败
两条线都不起作用:
Dim namedRng As Range Dim locDataWS As Worksheet Set locDataWS = Sheets("Approval matrix 16") Set namedRng = Range("best_Grade") ' errors Set namedRng = locDataWS.Range("best_Grade") ' When I take above line out, this line errors too
我试过了:
Dim wb As Workbook Set wb = ActiveWorkbook Set namedRng = wb.Names("best_Grade").RefersToRange
怎么会出错? 这页说它应该工作,不是? 我是否必须将这个UDF放在实际的工作簿对象上,而不是工作簿模块中?
编辑:注意:命名的范围没有设置为单元格,但SumIf公式(best_Grade = SumIf(A2:A10,“X”,…)`这可能会导致错误?
编辑2:是的,这就是为什么我想。 我创build了一个随机单元格的命名区域,并且能够使用Range("a_grade").Value
并且它返回了期望的值。 由于我的best_Grade
是一个公式,所以我认为这就是错误的原因。 然而,我不知道为什么,因为我认为一个命名的范围是一个命名范围,不pipe它是由什么组成的…
编辑n + 1:注意这里有两个“答案”。 如果我想继续使用命名范围作为Range
variables,请参阅下面的答案。 不过,我真正想做的是@MacroMarc发布的内容,所以我select了“答案”。
您需要使用Names集合:
Sub t5() ' named range "Test" is `=Sum($A$1:$A$4)` Dim rng As Double rng = Evaluate(Names("Test").Value) Debug.Print rng End Sub
Name对象必须返回不同的属性才能返回string表示。
Sub t5() ' named range "Test" is `=Sum($A$1:$A$4)` Set wb = ActiveWorkbook Dim rng As String rng = wb.Names("Test").RefersTo Debug.Print rng rng = Application.Evaluate(wb.Names("Test").RefersTo) Debug.Print rng End Sub
经过一些testing,我发现上面的工作…有趣的一种。 我从Macro Man的评论以及Chip Pearson的post中获得了领先。
关键是定义的名字返回一个string=“你的结果”,所以你可以评估它得到答案,或者你可以做一些string操作来拉引号和等号。 你真的很接近你的RefersToRangeselect。
看到Vegard的评论下你自己发布的答案。
它不工作的原因是因为我命名的范围best_Grades
不是一个单元格引用,而是一个公式。 因此,当使用Range("best_Grades").Value
,它是错误的。 ( best_Grades = SumIf(A2:A10,"x", B2:B10, ...)
不知道为什么,因为我认为一个命名的范围是一个命名的范围,不pipe是什么让这个…但我想不是。
现在,我的解决scheme是根据实际的单元格值创build另一个命名范围,然后使用它。 ( theBest_Grades = A2
)。 然后,我可以简单地调用Range("theBest_Grades").Value
没有任何问题。
我会把这个开放几天,以防有人知道如何保留我的公式命名范围,并在VBA中使用。
编辑:这基本上是我最初有工作表/命名的范围:
命名范围如下:
但是,正如我所说的,你不能在VBA中使用这种types的命名范围(至less不是我发现的)。
所以,为了解决这个问题,我只是在单元格中使用了SumIf,并给了这个单元格命名的范围:
现在我可以使用Range("findWindow_Example").Value
没有问题。
编辑n + 1:我试着用Double
做一个简单的testing,尽pipe如此,它却出错了:
Sub t5() ' named range "Test" is `=Sum($A$1:$A$4)` Dim rng As Double rng = Range("Test") 'Run time error 1004 Debug.Print rng End Sub
有一件事我没有在这里提到过,UDF的基本规则在这里被打破恕我直言:
UDF需要的所有信息都应该通过它的parameter passing给UDF。
如果遵守该规则,则使用任何范围名称都会变得简单,因为范围名称的值将自动转移到参数中。
解决这个问题的正确方法已经被一个以上的答复者发现了,但是正如我在评论中所说(后来,其他人可能会感兴趣的思想),错误的原因还没有被确定。
您定义的命名范围不会返回范围对象。 这意味着这个代码:
Dim namedRng As Range Set namedRng = Range("best_Grade")
(主要是因为命名的范围返回一个数值,如果它返回了一个string地址表示,它可能会有一些语法改进)。
为了从编译器的angular度来说明这一点,请看这里的直接窗口中的打印输出(特别是第一行):
如果我们假设最初的代码是伪代码,那么编译器的要求是从公式中构造一个范围(而不是它的结果!)。
因此,如果我们为Set namedRng = Range(Names("namedRange"))
交换Set namedRng = Range("best_Grade")
,结果可能(但不一定 – 见末尾!)看起来像:
Set rng = Range("=SUMIF('Ark1'!$B$1:$B$5, "x", 'Ark1'!$A$1:$A$5)")
当然,这是行不通的。 但是像其他答案所显示的那样,将namedRange
放入一个Evaluate
将会完全合法!
有趣的是,如果我们这样做? Evaluate(Names("namedRange"))
? Evaluate(Names("namedRange"))
(省略.Value),我们得到一个错误2015,尽pipe能够问编译器? Names("namedRange")
? Names("namedRange")
并获取一个string作为回报!