是个 .在.Cells定义时.Range是否必要?

16 excel vba range

人们普遍认为这不是"最佳实践".

dim rng as range
with thisworkbook    '<~~ possibly set an external workbook 
    with .worksheets("sheet1")
        set rng = .range(cells(2, 1), cells(rows.count, 1).end(xlup))
    end with
end with
Run Code Online (Sandbox Code Playgroud)

定义Range对象范围的两个Range.Cells属性将默认为ActiveSheet属性.如果这不是Sheet1(在With ... End With语句中定义为.Parent),则赋值将失败,

Run-tim error '1004': Application-defined or object-defined error
Run Code Online (Sandbox Code Playgroud)

解决方案:.Cells不要使用Cells.案件结案.

但...

Range.Cells属性都继承在With ... End With语句中定义的.Parent工作表属性时,是否.在此Range对象定义中是必需的?

怎么会这样,

dim rng as range
with thisworkbook    '<~~ possibly set an external workbook 
    with .worksheets("sheet1")
        ' define rng as Sheet1!A2 to the last populated cell in Sheet1!A:A
        set rng = .range(.cells(2, 1), .cells(rows.count, 1).end(xlup))  '<~~ .range
    end with
end with
debug.print rng.address(0, 0, external:=true)
Run Code Online (Sandbox Code Playgroud)

......与此不同,

dim rng as range
with thisworkbook    '<~~ possibly set an external workbook 
    with .worksheets("sheet1")
        ' define rng as Sheet1!A2 to the last populated cell in Sheet1!A:A
        set rng = range(.cells(2, 1), .cells(rows.count, 1).end(xlup))  '<~~ range not .range
    end with
end with
debug.print rng.address(0, 0, external:=true)
Run Code Online (Sandbox Code Playgroud)

我们使用.range定义范围范围的参数是不明确的; 例如.range([A1]),A1单元格可以来自任何工作表,并且默认为ActiveSheet属性而不使用..但是,当定义范围对象的范围正确引用其父工作表时,为什么我们需要引用范围对象的父级?

Sid*_*out 20

我的意见在这里略有不同.

是的,这是必需的.您无法始终控制用户可以从中运行代码的位置.

请考虑这几个测试用例

情景

工作簿有2个工作表.Sheet1和Sheet2


测试1(从模块运行)

两个代码给出相同的结果

TEST 2(从Sheet1的Sheet代码区域运行)

两个代码给出相同的结果

TEST 3(从Sheet2的Sheet代码区域运行)

'~~> This code fails
set rng = range(.cells(2, 1), .cells(rows.count, 1).end(xlup))
Run Code Online (Sandbox Code Playgroud)

你会收到Application Defined or Object defined错误

在此输入图像描述

因此,始终建议对对象进行适当的限定,以便代码可以在任何地方运行

  • 我和Siddharth在一起.这真的取决于什么是"ActiveSheet",如果activesheet是图表工作表,底部组的肯定的代码中的错误了,除非.Range(...)``使用. (2认同)

chr*_*sen 9

不,.除非代码在Worksheet模块中,否则不需要括号内的单元格引用是合格的.这就是说它是运行更快set rng = .range(.cells(...), .cells(...))比它运行set rng = range(.cells(...), .cells(...))如此,包括.做一些很好的.

对于Worksheet模块,这.是必需的.


Com*_*ern 7

答案似乎是:只有代码位于Worksheet对象中.我强烈怀疑这是因为Worksheet对象是唯一既可扩展又具有Range功能的对象.当Range从工作表中调用该对象的Range函数范围.当代码位于ThisWorkbook或用户模块或类中时,Range具有最接近可用范围的函数是全局Range对象(当然假设没有用户定义的Range函数).那一个绑定到Application,必须根据传递的参数解析它并将调用转发到正确的工作表.

  • @BrakNicku不,这是COM意大利面的问题.一个不合格的`Range`并不神奇地定义为`Application`,它的作用域是隐藏的`_Global`模块,最终解析为`ActiveSheet`.如果你正在看实际的内部结构,MSDN正在告诉那些令人愚蠢的半真半假的事情.在工作表的代码隐藏中使用的不合格的"Range"只解析为该表,因为这是在VBA中作用域的方式; `我'有一个`Range`属性,所以不合格的`Range`就像`Me.Range`,就像`Me.TextBox1`和表单的代码隐藏中的`TextBox1`一样. (2认同)