简体   繁体   English

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

[英]Range and ActiveCell.Offset Run-time error '1004'

I'm trying to determine the minimum and maximum values of a 5 cell range (C:G) for all non-blank rows in a worksheet and place the respective results in columns L and M. 我正在尝试确定工作表中所有非空白行的5个单元格范围(C:G)的最小值和最大值,并将各自的结果放置在L和M列中。

I'm getting a Run-time error '1004' Application-defined or object-defined error. 我收到运行时错误'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

I'm pretty sure my problem is in the specification of the range but not sure what it is. 我很确定我的问题出在范围的说明中,但不确定是什么。

The first and last selects are just a convention I use. 第一个和最后一个选择只是我使用的约定。

The second select is to step past a header row. 第二个选择是跨过标题行。

The third select is to increment the row. 第三个选择是增加行数。

If there is a simpler way to do this, please let me know. 如果有更简单的方法,请告诉我。

I can't reproduce the error you mention, your code seems to run as is. 我无法重现您提到的错误,您的代码似乎按原样运行。

That said there a many ways to improve this code 也就是说,有很多方法可以改善此代码

  1. Avoid Select (as mentioned in comments) 避免Select (如评论中所述)
  2. The Application object offers Min and Max functions, no need to use WorksheetFunction s for these Application对象提供MinMax函数,无需为此使用WorksheetFunction
  3. Better approach to range references is a combination of Offset and Resize range参考的更好方法是“ Offset和“ Resize的组合

Your code, refactored to used these techniques 您的代码已重构为使用了这些技术

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

That said, you can go further and use a Variant Array approach. 也就是说,您可以走得更远并使用Variant Array方法。 This runs much faster than looping a range (impact will vary depending on number of data rows) 这比循环范围快得多(影响会因数据行数而异)

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

Another technique is to avoid a loop entirely by (temporarily) placing formula into the sheet in one go. 另一种技术是通过(暂时)一次性将公式放入表中来完全避免循环。 This will be much faster still (for more than a few data rows) 这将是更快仍然(以上几个数据行)

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

How about this? 这个怎么样?

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
  • Define the range upfront 预先定义范围
  • Write the min and max to the cells directly minmax直接写入单元格

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM