(VBA)何时使用.cell(1,1)或.cell(1,1).value引用

4

在我的宏中,当我引用单元格中的值时,我一直在不一致地使用.cell(r,c)或.cell(r,c).value。

dim c as variant 
c = sheet1.cell(1,1) 'or sheet1.cell(1,1).value

这两种引用方式都是正确的,但是否有一种更好的方式呢?

它们都是正确的,许多VBA程序员更喜欢sheet1.cell(1,1).value,因为它更明确。无论如何,我投票关闭此问题,因为它主要基于个人意见。 - John Coleman
3
@A.S.H 我对它是否基于观点没有很强的看法,有些模糊。你的回答非常好。 - John Coleman
1
@A.S.H "匿名"??!?! ("一致的"?) - YowE3K
2个回答

6

.Value是范围对象的默认属性。因此,当你像这样分配变量:

myVar = myRange

它等同于 myVar = myRange.Value,因为你正在赋值给一个变量而不是一个 对象

然而,如果你使用 Set,像这样:

Set myObj = myRange

您要分配一个对象引用。关键字Set告诉VBA您正在分配一个对象引用。缺少Set会使VBA推断出您隐含地想获取范围的.value,也就是默认属性。
使用.value有两个原因,这是一个好的编程实践:
1- 代码更易读,因为读者不必猜测隐含的情况
2- 随着VB.net的出现,关键字Set已经消失;分配对象或普通变量的语法变得相同。因此,VB.net中已经消失了默认属性习语。因此,良好的实践是在VBA中也使用.value,因为这使得将您的代码移植到VB.net更加容易。

谢谢解释。当你执行Set c = sheet1.cells(1,1)时,你是在引用实际的范围吗? - lostinOracle
1
@excelmonkey93,是的,当然可以。如果您将c的“dimmed”设置为除As RangeAs ObjectAs Variant之外的其他内容,则自然会导致编译器错误。这个特殊情况是Variant,因为在这里两个赋值(对.value或对象本身)都是可能的,并且Set关键字打破了平局。 - A.S.H
建议使用.Value2而不是.Value - John Alexiou
@ja72 我同意,但在我看来那是另一回事,我不想混淆两个问题。 - A.S.H

0

我总是使用.Value2来获取单元格的值(或从范围中获取变量数组)。如果我不使用.Value2,那么意味着我想要一个对Range对象的引用而不是值。例如:

Dim r as Range
Set r = Range("A1")

Dim x as Double, i as Integer
x = r.Offset(1,0).Value2

Dim vals() as Variant
vals = r.Offset(1,0).Resize(10,1).Value2

For i=1 to 10
    vals(i,1) = CDbl(i)/10
Next i

r.Offset(1,0).Resize(10,1).Value2 = vals

此外,我不使用Cell()方法,因为单元格的位置可能会在未来更改。我使用命名区域.Offset()以及.Resize()方法来设置我想要读取或写入值的单元格范围。因此,在上面的代码中,我永远不会使用Range("A1"),而是像Range("my_table")这样使用一个名为"my_table"的命名区域,该区域定义在我与之交互的左上角单元格上。

有一个鲜为人知的快捷方式可以使用[]符号获取单元格的值。

Dim x as Double
x = [A2]
// This is the same as x = Range("A2").Value2

谢谢您的见解。为什么要使用.value2而不是.value? - lostinOracle
此属性与Value属性之间唯一的区别是Value2属性不使用Currency和Date数据类型。您可以通过使用Double数据类型将格式为这些数据类型的值作为浮点数返回。 - John Alexiou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接