范围和ActiveCell.Offset运行时错误' 1004'

时间:2014-07-12 17:33:26

标签: excel-vba vba excel

我正在尝试确定工作表中所有非空行的5个单元格范围(C:G)的最小值和最大值,并将相应的结果放在列L和M中。

我收到运行时错误'1004'应用程序定义或对象定义错误。

Sub test()
    ActiveSheet.Range("A1").Select
    ActiveCell.Offset(1, 0).Select
    Do While ActiveCell.Value <> Empty
        ActiveCell.Offset(0, 11) = WorksheetFunction.Min(Range(ActiveCell.Offset(0, 2), ActiveCell.Offset(0, 6)))
        ActiveCell.Offset(0, 12) = WorksheetFunction.Max(Range(ActiveCell.Offset(0, 2), ActiveCell.Offset(0, 6)))
        ActiveCell.Offset(1, 0).Select
    Loop
    ActiveSheet.Range("A1").Select
End Sub

我很确定我的问题在于范围的规范,但不确定它是什么。

第一个和最后一个选择只是我使用的约定。

第二个选择是跳过标题行。

第三个选择是增加行。

如果有更简单的方法,请告诉我。

2 个答案:

答案 0 :(得分:1)

我无法重现您提到的错误,您的代码似乎按原样运行。

那说有很多方法可以改进这段代码

  1. 避免Select(如评论中所述)
  2. Application对象提供MinMax个功能,无需使用WorksheetFunction s
  3. range引用的更好方法是OffsetResize
  4. 的组合

    您的代码,重构使用这些技术

    Sub Demo()
        Dim ws As Worksheet
        Dim rng As Range
        Dim rw As Range
    
        ' Get a reference to the source data range
        Set ws = ActiveSheet
        With ws
            Set rng = .Cells(2, 1)
            ' Just in case there is only one data row
            If Not IsEmpty(rng.Offset(1, 0)) Then
                Set rng = .Range(rng, rng.End(xlDown))
            End If
        End With
    
        ' Loop the range
        For Each rw In rng.Rows
            rw.Offset(0, 11) = Application.Min(rw.Offset(0, 1).Resize(, 5))
            rw.Offset(0, 12) = Application.Max(rw.Offset(0, 1).Resize(, 5))
        Next
    End Sub
    

    也就是说,您可以采用Variant Array方法。这比循环范围运行得快得多(影响因数据行数而异)

    Sub Demo2()
        Dim ws As Worksheet
        Dim rng As Range
        Dim dat As Variant
        Dim res As Variant
        Dim i As Long
    
        ' Get a reference to the source data range
        Set ws = ActiveSheet
        With ws
            Set rng = .Cells(2, 1)
            ' Just in case there is only one data row
            If Not IsEmpty(rng.Offset(1, 0)) Then
                Set rng = .Range(rng, rng.End(xlDown))
            End If
        End With
    
        ' Set up source and result arrays
        dat = rng.Offset(, 2).Resize(, 5).Value
        ReDim res(1 To UBound(dat, 1), 1 To 2)
    
        With Application
            ' Loop the array
            For i = 1 To UBound(dat, 1)
                res(i, 1) = .Min(.Index(dat, i))
                res(i, 2) = .Max(.Index(dat, i))
            Next
        End With
    
        ' Return results to sheet
        rng.Offset(0, 11).Resize(, 2) = res
    End Sub
    

    另一种技术是通过(暂时)将公式一次性放入纸张中来完全避免循环。这仍然会更快(对于多个数据行)

    Sub Demo3()
        Dim ws As Worksheet
        Dim rng As Range
        Dim rw As Range
    
        ' Get a reference to the source data range
        Set ws = ActiveSheet
        With ws
            Set rng = .Cells(2, 1)
            If Not IsEmpty(rng.Offset(1, 0)) Then
                Set rng = .Range(rng, rng.End(xlDown))
            End If
        End With
    
        ' Place formulas into sheet
        rng.Offset(0, 11).FormulaR1C1 = "=Min(RC[-9]:RC[-5])"
        rng.Offset(0, 12).FormulaR1C1 = "=Max(RC[-9]:RC[-5])"
    
        ' replace formulas with values (optional)
        rng.Value = rng.Value
    End Sub
    

答案 1 :(得分:0)

这个怎么样?

Sub MinAndMax()
    Dim rng As Range
    Set rng = Range("A2:A" & Range("A2").End(xlDown).Row)

    Range("L1") = WorksheetFunction.Min(rng)
    Range("M1") = WorksheetFunction.Max(rng)
End Sub
  • 预先定义范围
  • 直接将minmax写入单元格