Vba 如何在自己的类中复制Range.Cells的功能?

Vba 如何在自己的类中复制Range.Cells的功能?,vba,excel,Vba,Excel,我试图在我自己的类中模拟Range.Cells(row,col)属性。My.Cells属性未正确更新指定的单元格 然而,问题是,当我键入d.Cells(1,3)=时,在等号之后,intellisense将建议“单元格(行长,列长)为范围”。我不确定这是否会给我带来问题 Cells属性的定义如下: Property Get Cells(row As Long, col As Variant) As Range ' Get the column number for the request

我试图在我自己的类中模拟
Range.Cells(row,col)
属性。My.Cells属性未正确更新指定的单元格

然而,问题是,当我键入
d.Cells(1,3)=
时,在等号之后,intellisense将建议
“单元格(行长,列长)为范围”
。我不确定这是否会给我带来问题

Cells属性的定义如下:

Property Get Cells(row As Long, col As Variant) As Range

    ' Get the column number for the requested cell
        Dim c As Long
        If IsNumeric(col) Then
            ' ensure it is an int
                c = CInt(col)
        ElseIf VarType(col) = vbString Then
            ' Get column number from the header name
                c = Me.Column(CStr(col))
        Else
            ' Otherwise, variant type is not supported
                Exit Property
        End If

    ' Return the requested Cell if column number is valid
        If c > 0 And c <= pHeaderRange.Columns.Count Then
            Set Cells = pHeaderRange.CurrentRegion.Cells(1 + row, c)
            ' the row is +1 because pHeaderRange.CurrentRegion also returns 
            ' the header row
        End If

End Property
但我得到的信息是:“编译错误:同一属性的属性过程的定义不一致,或者属性过程有可选参数ParamArray,或者Set final参数无效。”

我想我得到编译错误是因为我在这一行
属性get Cells(行为Long,列为Variant)As Range中包含了参数。但是我需要这些参数来选择单元格

在用户定义的类中定义.Cells属性以使其与Range.Cells的工作方式相同的正确方法是什么

完整代码为:

Option Explicit

Private pHeaderRange As Range

'
' Sets the Range of the header row.
'
' -r   Range   The header row is expected to the in the CurrentRegion of r.
'
Property Let Header(location As Range)

    ' if range is empty, only the top, left cell will be selected
        Dim r As Range
        Set r = location.CurrentRegion

    ' if top row is blank, then remove top row from the range
        If WorksheetFunction.CountA(r.Rows(1)) = 0 Then
            ' dont (and cant) resize unless there are multiple rows in the range
                If r.Rows.Count > 1 Then
                    Set r = r.Resize(r.Rows.Count - 1, r.Columns.Count).Offset(1, 0) ' resizes and repositions range
                Else
                    ' the is no header, only a blank cell
                        Set pHeaderRange = r
                        Exit Property
                End If
        End If

    ' find the starting column of the header row
        Dim startCell As Range
        Dim endCell As Range
        Set startCell = r.Cells(1, 1)

        If IsEmpty(startCell) Then
            ' if startCell is empty, look for header to the right
                Set startCell = r.End(xlToRight)
        ElseIf IsEmpty(startCell.Offset(0, -1)) Then
            ' if cell to the left is empty, we have already found the start of the header
        Else
            ' otherwise move to left to find the start
                Set startCell = startCell.End(xlToLeft)
        End If

        ' find the last column of the header row
            If IsEmpty(startCell.Cells(1, 2)) Then
                ' if cell to the right is empty, header row only contains one cell
                    Set endCell = startCell
            Else
                ' otherwise move to right to find the end
                    Set endCell = startCell.End(xlToRight)
            End If

    ' store the header range
        Set pHeaderRange = Range(startCell, endCell)

    ' debug
        pHeaderRange.Select

End Property


'
'
Public Property Get Cells(row As Long, col As Variant) As Range

    ' Get the column number for the requested cell
        Dim c As Long
        If IsNumeric(col) Then
            ' change to int
                c = CInt(col)
        ElseIf VarType(col) = vbString Then
            ' Get column by header name
                c = Me.Column(CStr(col))
        Else
            ' Otherwise, variant type is not supported
                Exit Property
        End If

    ' Return the requested Cell if column number is valid
        If c > 0 And c <= pHeaderRange.Columns.Count Then
            Set Cells = pHeaderRange.CurrentRegion.Cells(1 + row, c) ' the row is +1 because CurrentRegion also returns the header row
        End If

End Property
Public Property Set Cells(v As Range)
    ' some code here
End Property

'
' Returns the entire column range of the header that matches the index.
'
' -name String  The header name to find
'
Public Property Get Column(name As String) As Long

    ' Find header
        On Error Resume Next ' continue even if name is not found (ie Find returns an error)
        Dim r As Range
        Set r = pHeaderRange.Find(name)

    ' return column number
        Column = r.Column - pHeaderRange.Column + 1

End Property
选项显式
专用范围作为范围
'
'设置标题行的范围。
'
'-r范围标题行应位于当前区域r中。
'
属性Let标头(位置作为范围)
'如果范围为空,则仅选择左上角的单元格
调光范围
设置r=location.CurrentRegion
'如果顶行为空,则从范围中删除顶行
如果工作表function.CountA(r.Rows(1))=0,则
'除非范围内有多行,否则不要(和不能)调整大小
如果r.Rows.Count>1,则
设置r=r.Resize(r.Rows.Count-1,r.Columns.Count)。偏移量(1,0)调整大小并重新定位范围
其他的
'没有标题,只有一个空白单元格
设置范围=r
退出属性
如果结束
如果结束
'查找标题行的起始列
暗淡的startCell As范围
暗端细胞
设置startCell=r.Cells(1,1)
如果我是空的(startCell),那么
'如果startCell为空,请查找右侧的标题
设置startCell=r.End(xlToRight)
ElseIf为空(startCell.Offset(0,-1)),则
'如果左侧的单元格为空,则我们已找到标题的开头
其他的
'否则向左移动以找到起点
设置startCell=startCell.End(xlToLeft)
如果结束
'查找标题行的最后一列
如果是空的(startCell.Cells(1,2)),那么
'如果右侧的单元格为空,则标题行仅包含一个单元格
设置endCell=startCell
其他的
'否则向右移动以找到终点
设置endCell=startCell.End(xlToRight)
如果结束
'存储标题范围
设置pHeaderRange=范围(起始单元格、结束单元格)
"调试",
pHeaderRange。选择
端属性
'
'
公共属性获取单元格(行为长,列为变量)作为范围
'获取请求单元格的列号
尺寸c与长度相同
如果是数字(col),则
'更改为int
c=辛特(col)
ElseIf VarType(col)=vbString Then
'按标题名称获取列
c=Me.柱(CStr(柱))
其他的
'否则,不支持变量类型
退出属性
如果结束
'如果列号有效,则返回请求的单元格

如果c>0和c如果我很理解你的问题,也许你可以试试:

Public Property Set Cells(row As Long, col As Variant) As Range
    'code to set the class
End Property

请参阅此主题的一些提示:

如果我很理解您的问题,也许您可以尝试:

Public Property Set Cells(row As Long, col As Variant) As Range
    'code to set the class
End Property
请参阅此线程的一些提示:

同一属性的属性Get、属性Let和属性集过程的参数必须完全匹配,但属性Let有一个额外的参数,其类型必须与相应属性Get的返回类型匹配

问题是Get中的参数不在集合中。所以这是可行的

Public Property Get Cells(lrow As Long, vcol As Variant) As Range


End Property
Public Property Set Cells(lrow As Long, vcol As Variant, v As Range)


End Property
但这毫无意义(你已经知道了)。单元格在Excel对象模型中工作的原因是它是只读属性(有Get,但没有Let或Set)。Cells属性返回一个范围对象,但不能设置单元格。我不确定你想用Set语句实现什么,但也许你不需要它。您似乎没有任何模块级变量来存储它。

同一属性的属性Get、属性Let和属性集过程的参数必须完全匹配,但属性Let有一个额外的参数,其类型必须与相应属性Get的返回类型匹配

问题是Get中的参数不在集合中。所以这是可行的

Public Property Get Cells(lrow As Long, vcol As Variant) As Range


End Property
Public Property Set Cells(lrow As Long, vcol As Variant, v As Range)


End Property

但这毫无意义(你已经知道了)。单元格在Excel对象模型中工作的原因是它是只读属性(有Get,但没有Let或Set)。Cells属性返回一个范围对象,但不能设置单元格。我不确定你想用Set语句实现什么,但也许你不需要它。您似乎没有任何模块级变量来存储它。

当我将其更改为属性集时,我无法再执行此操作:d.Cells(1,3)=“h3”。然后我添加了属性集(v作为变量)。但随后我收到一条编译错误消息,说“同一属性的属性过程的定义不一致,或者属性过程有一个可选参数a ParamArray,或者Set final参数无效。@Brent Jacobs:您不应该更改代码,而应该添加
(另请参阅)-也许它是一个
Let
而不是
Set
,但我不认为我可以再试一次:当我将其更改为属性集单元格(v作为变量)时,我再也做不到了