我试图创建一个使用命名范围的UDF。我的命名范围(" best_Grade")是一个单元格,带有一个值。 (命名范围的范围限定为工作簿)。
在工作簿模块中,当我尝试使用命名范围创建变量时,我得到
运行时错误' 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
怎么会出错呢? This page说应该有效,不是吗?我是否必须将此UDF放在实际的工作表对象上,而不是在工作簿模块中?
编辑:注意:命名范围不是设置为单元格,而是设置为SumIf公式(best_Grade = SumIf(A2:A10," x",...)`可能导致错误?
编辑2:是的,这就是我想的原因。我为随机单元格创建了一个命名范围,并且能够使用Range("a_grade").Value
并返回了预期值。由于我的best_Grade
范围是一个公式,我认为这就是它出错的原因。但是,我不知道为什么,因为我认为命名范围是命名范围,无论它由什么组成...
编辑n + 1:注意有两个"答案"对此。如果我想继续使用命名范围作为Range
变量,请参阅下面的答案。然而,我真正想要做的是@MacroMarc发布的内容,所以我选择了它作为"答案"。
答案 0 :(得分:3)
您需要改为使用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对象必须返回字符串表示的各种属性。
答案 1 :(得分:2)
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
经过一些测试后,我发现上面的工作......并且很有趣。我在Chip Pearson帖子中也得到了Macro Man的评论。
键是定义的名称返回一个字符串=“你的结果”所以你可以评估它以获得答案,或者你可以做一些字符串操作来拉出引号和等号。你真的很接近你的RefersToRange选择。
根据您自己发布的答案查看Vegard的评论。
答案 2 :(得分:1)
它无效的原因是因为我的命名范围best_Grades
不是单元格引用,而是公式。因此,在使用Range("best_Grades").Value
时,它出错了。 (best_Grades = SumIf(A2:A10,"x", B2:B10, ...)
不知道为什么,因为我认为命名范围是一个命名范围,无论是什么原因......但我想不是。
目前,我的解决方案是根据实际的单元格值创建另一个命名范围,然后使用它。 (theBest_Grades = A2
)。然后,我可以毫无问题地简单地调用Range("theBest_Grades").Value
。
我会把这个开放几天,以防有人知道我如何保持我的公式命名范围,并在VBA中使用它。
命名范围为:
但是,正如我所说,你不能在VBA中使用那种类型的命名范围(至少不是我找到的)。
所以,为了解决它,我只是在单元格中使用了SumIf,并为该单元格指定了范围:
现在我可以毫无问题地使用Range("findWindow_Example").Value
。
编辑n + 1:
我尝试使用Double
进行简单的测试,但同样的事情,它出错:
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
答案 3 :(得分:1)
我在这里没有提到的一件事是UDF的基本规则在这里打破了恕我直言:
UDF需要的所有信息都应通过其参数传递给UDF。
如果您遵守该规则,则使用任何范围名称变得简单,因为范围名称的值将自动转移到参数。
答案 4 :(得分:0)
多个回答者已经找到了解决问题的正确方法,但正如我在评论中所说的那样(其后,其他人可能会感兴趣),错误的原因尚未明确。
您定义的命名范围不返回范围对象。这意味着这段代码:
Dim namedRng As Range
Set namedRng = Range("best_Grade")
无法工作(主要是因为命名范围返回一个数值。如果它返回一个字符串地址表示,它可能有一些语法改进)。
要从编译器的角度说明这一点,请在此处查看即时窗口中的打印输出(特别是第一行):
如果我们假设初始代码是伪代码,那么编译器的要求就是在公式之外构造一个范围(而不是它的'结果!)。
因此,如果我们将Set namedRng = Range("best_Grade")
换成Set namedRng = Range(Names("namedRange"))
,结果可能(但不一定 - 请参阅帖子的结尾!)看起来像:
Set rng = Range("=SUMIF('Ark1'!$B$1:$B$5, "x", 'Ark1'!$A$1:$A$5)")
当然,这不起作用。但是,正如其他答案所示,将namedRange
投入Evaluate
将是完全合法的!
有趣的是,如果我们? Evaluate(Names("namedRange"))
(省略.Value),我们会得到一个错误2015,尽管能够询问编译器? Names("namedRange")
并获得一个字符串作为回报!