范围和variables之间的差异如范围那样变暗

我build立了一个类,需要将数据logging到单元格中。 所以我写了一个这样的函数。 代码如下:

Option Explicit Private sName As String Public Property Let Name(ByVal strValue As String) sName = strValue End Property Public Property Get Name() As String Name = sName End Property Public Function ItemToCell(ByRef tgtCell As Range) tgtCell = sName End Function 

我还设置了一个button来触发这个过程:

 Private Sub CommandButton1_Click() Dim tmpData As New MyClass tmpData.Name = "Tom" Dim tgtCell As Range Set tgtCell = Worksheets("Sheet1").Range("A1") 'Method 1, this failed with error 424 tmpData.ItemToCell (tgtCell) 'Method 2, it works tmpData.ItemToCell (Worksheets("Sheet1").Range("B1")) End Sub 

我认为这两种方法是一样的,但显然他们不是。 为什么? 是不是variablestgtCell一个对象?

请注意,下面的方法1A,删除括号,是否按预期工作:

 Public Sub CommandButton1_Click() On Error GoTo EH Dim tmpData As New MyClass tmpData.Name = "Tom" Dim tgtCell As Range Set tgtCell = Worksheets("Sheet1").Range("A1") 'Method 1, this failed with error 424 tmpData.ItemToCell (tgtCell) 'Method 1A, this works tmpData.ItemToCell tgtCell 'Method 2, it works tmpData.ItemToCell (Worksheets("Sheet1").Range("B1")) XT: Exit Sub EH: MsgBox Err.Description, vbOKOnly, Err.Source Resume Next End Sub 

由于对tmpData.ItemToCell调用需要一个l值(即它是一个ByRef参数),但是调用语句IS不是一个函数调用,因此困难就出现了,所以括号不是调用括号 ,而是分组圆括号 。 这在VBA中可能是一个令人困惑的问题。

分组圆括号的作用是返回variablestgtCell而不是其存储位置 ,并隐式评估Range对象默认成员 。 然而,正如你偶然发现的方法2,有些情况下,VBA 隐式评估默认成员。 是的,这让每个人都感到困惑。 不要感到孤单。

一种最小化这种烦恼发生的方法是显式指定函数和子参数(和设置/让属性)作为ByVal,除非你真的想要传回一个改变的值给调用者。 这赢得了:

  • 消除了这个烦人的function的许多例子;
  • 将参数作为局部variables处理时,会消除许多细微的错误,并且在实际上不是局部的情况下,将其值更改为期望这些更改为局部范围。

但是,你的情况是罕见的,这不起作用。 在这种情况下,最好不要在方法调用中添加括号,直到VBA声明不存在为止,这通常只是用于函数而不是Subs和Property Setters / Letters。

在这里输入图像说明

综上所述:
– 除非你确实传递了一个计算值(在这种情况下,函数是一个更好的实现并且通常是足够的),或者当语言要求你传递一个ByRef参数时,参数应该明确地指定为ByVal(而不是ByRef的默认值) 。
– 当VBA抱怨缺less时,只能在方法调用中使用括号。