引用由Range.Row()设置的Range对象会生成错误1004“应用程序定义的错误或对象定义的错误”

时间:2019-06-14 15:53:00

标签: excel vba

我通过从另一个范围对象的Rows()设置它来创建了一个范围对象。当我按行和列引用新创建的范围时,它会产生错误1004。

我可以按行和列引用原始范围。我已经进行了检查,以确保rng对象指向与数据集对象相同的范围。当我检查rng对象时,Value2仅显​​示一行数据。

下面是我正在使用的生成错误的最小代码。

Private Sub TestRangeObject()

Dim i As Long
Dim dataset As Range
Dim rng As Range

    Set dataset = sRoster.Range("B18:E37")

    For i = 1 To dataset.Rows.Count

        Set rng = dataset.Rows(i)

        Debug.Print "Rng is Range Obj: " & (TypeOf rng Is Range)
        Debug.Print "Same worksheet: " & (rng.Parent.CodeName = dataset.Parent.CodeName)
        Debug.Print "Same address: " & (dataset.Rows(i).Address = rng.Address)

        'can reference dataset object by row and column
        Debug.Print "First column (dataset): " & dataset(i, 1).Address

        'error when referencing rng object by row and column
        Debug.Print "First column (rng): " & rng(1, 1).Address

    Next i

End Sub

2 个答案:

答案 0 :(得分:3)

更多细节:使用Rows(somerow)Range(somerange)之间是有区别的。

这可以用一个简单的例子来验证:

Sub Test()
    Dim rng As Range
    Set rng = Sheet1.Range("1:1")
    Debug.Print rng(1, 1).Address ' returns $A$1

    Dim rng2 As Range
    Set rng2 = Sheet1.Rows(1)
    Debug.Print rng2(1).Address ' succeeds, returns $1:$1
    Debug.Print rng2(1, 1).Address ' fails
End Sub

已经提出了使用Rows(myRow).Cells的解决方案。

编辑:

为了捕获和总结注释中的某些内容,Row(无论是Range.Rows(somerow)还是Sheet.Rows(somerow))都将单元称为行,而不是作为单个单元格。

例如,Range("A1:E10").Rows指的是 10行,而不是 50个单元格。 同样,Sheet1.Rows(1)指的是 1行,而不是 16384个单元格。由于缺少更好的术语,该行是“最小的考虑单位”。一行不能具有列索引-只能是一行,而不是组成该行的所有单元格的集合,每个单元格都有自己的列索引。

因此,如果您特别想索引特定行中的单元格,则需要使用Cells

答案 1 :(得分:2)

您不能使用:

rng(1, 1)

如果rng是单个行范围:

Sub jksfhsa()
    Dim sRoster As Worksheet, dataset As Range, rng As Range
    Set sRoster = Sheets("Sheet1")
    Set dataset = sRoster.Range("B18:E37")
    Set rng = dataset.Rows(1)

    MsgBox dataset.Address
    MsgBox dataset(1, 1).Address

    MsgBox rng.Address
    MsgBox rng(1, 1).Address

    End Sub

最后一个MsgBox将失败。

但是:

Sub jksfhsa()
    Dim sRoster As Worksheet, dataset As Range, rng As Range
    Set sRoster = Sheets("Sheet1")
    Set dataset = sRoster.Range("B18:E37")
    Set rng = dataset.Rows(1).Cells

    MsgBox dataset.Address
    MsgBox dataset(1, 1).Address

    MsgBox rng.Address
    MsgBox rng(1, 1).Address

    End Sub

就可以了。因此,在您的代码中替换:

Set rng = dataset.Rows(i)

具有:

Set rng = dataset.Rows(i).Cells