excel 返回最大日期的第一个行号

fzwojiic  于 2023-08-08  发布在  其他
关注(0)|答案(4)|浏览(134)

如何编写VBA来返回列L中最大日期的第一个行号?
我正在尝试这个代码并得到
“未设置对象变量或With块变量”

Sub FindMaxValRow()
Dim Rng As Range
Dim MaxCell As Range
Dim MaxVal As Long

Set Rng = Range("L1:L500")
MaxVal = WorksheetFunction.Max(Rng)
Set MaxCell = Rng.find(what:=MaxVal, LookIn:=xlValues)
MsgBox "Maximum value found at row " & MaxCell.Row
End Sub

字符串

68bkxrlz

68bkxrlz1#

确定日期第一次出现的行

  • L有日期(和空单元格)
  • M在第2行中具有向下复制的公式=L2(为测试添加)
  • N在第2行中具有溢出公式=L2:L10(为测试添加)


的数据

应用vs工作表函数

Max(例如Sum ...)函数将失败,如果在该范围内存在错误值。Match(或例如VLookup)函数。如果您使用其早期绑定(WorksheetFunction)版本,则会发生运行时错误。为了避免这种情况,您应该使用其后期绑定(Application)版本,以便能够使用IsNumericIsError函数测试其结果。

匹配

  • 当您在单列范围中查找第一个(在本例中是最顶部)值时,应该使用更高效的Application.Match函数,而不是Find方法。
  • 如果(因为)值是日期,Match将其转换为整数(整数)。使用 CLng 函数只是为了强调这一点。
  • 这适用于值、公式和溢出公式。
Sub IdentifyRowOfMaxDateMATCH()
    Const PROC_TITLE As String = "Identify Row of Max Date Using 'Match'"
    
    Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
    Dim rg As Range: Set rg = ws.Range("L2:L500")
    
    Dim MaxValue As Variant: MaxValue = Application.Max(rg)
    
    If IsError(MaxValue) Then
        MsgBox "Found error values in range """ & rg.Address(0, 0) & """.", _
            vbCritical, PROC_TITLE
        Exit Sub
    End If
    
    Dim RowIndex: RowIndex = Application.Match(CLng(MaxValue), rg, 0)
    
    Dim maxCell As Range:
    If IsNumeric(RowIndex) Then
        Set maxCell = rg.Cells(RowIndex)
    End If
    
    If maxCell Is Nothing Then
        MsgBox "Maximum date """ & CDate(MaxValue) & """ not found.", _
            vbCritical, PROC_TITLE
    Else
        MsgBox "Maximum date """ & CDate(MaxValue) _
            & """ found in (worksheet) row " & maxCell.Row & ".", _
            vbInformation, PROC_TITLE
    End If

End Sub

字符串

查找

  • 如果坚持使用Find方法,则需要使用以下模式将值转换为字符串:
"mm\/dd\/yyyy"


使用\/分隔符,使其独立于区域设置。

  • 这适用于值、公式和溢出公式。
Sub IdentifyRowOfMaxDateFIND()
    Const PROC_TITLE As String = "Identify Row of Max Date Using 'Find'"
    
    Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
    Dim rg As Range: Set rg = ws.Range("L2:L500")
    
    Dim MaxValue As Variant: MaxValue = Application.Max(rg)
    
    If IsError(MaxValue) Then
        MsgBox "Found error values in range """ & rg.Address(0, 0) & """.", _
            vbCritical, PROC_TITLE
        Exit Sub
    End If
    
    Dim MaxDateString As String:
    MaxDateString = Format(MaxValue, "mm\/dd\/yyyy")
    
    Dim maxCell As Range:
    Set maxCell = rg.Find(What:=MaxDateString, _
        After:=rg.Cells(rg.Cells.Count), LookIn:=xlValues, LookAt:=xlWhole)

    If maxCell Is Nothing Then
        MsgBox "Maximum date """ & CDate(MaxDate) & """ not found.", _
           vbCritical, PROC_TITLE
    Else
        MsgBox "Maximum date """ & CDate(MaxDate) _
            & """ found in (worksheet) row " & maxCell.Row & ".", _
            vbInformation, PROC_TITLE
    End If

End Sub

匹配vs查找

  • MatchFind更高效(更快)。
  • 查看屏幕截图,Match将识别第6行,无论如何,即即使行6被隐藏或使用AutoFilter隐藏。如果您使用Find和日期以及xlFormulasxlFormulas2(请参阅下面的测试),也会发生同样的情况,但您只能在单元格包含值时使用此方法。
  • 另一方面,如果第6行被AutoFilter隐藏或隐藏,则值被格式化为字符串(MaxDateString)和xlValuesFind将标识第8行(参见上文和下文)。
    测试
Sub FindDateTest()
    
    Dim Ins(): Ins = VBA.Array(xlValues, xlFormulas, xlFormulas2)
    Dim Ats(): Ats = VBA.Array(xlWhole, xlPart)
    Dim Offsets(): Offsets = VBA.Array(0, 1, 2)
    Dim Contents():
    Contents = VBA.Array("Values", "Formulas", "A formula spilling")
    
    Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
    
    Dim rg As Range, maxCell As Range, MaxValue, DateString As String

    Dim FindValues(), FindValue, i As Long, a As Long, o As Long, f As Long

    For o = 0 To UBound(Offsets)
        
        Set rg = ws.Range("L2:L10").Offset(, Offsets(o))
        MaxValue = Application.Max(rg)
        FindValues = VBA.Array( _
            CDate(MaxValue), _
            CLng(MaxValue), _
            Format(MaxValue, "mm\/dd\/yyyy") _
            )
        
        Debug.Print String(80, "-")
        Debug.Print Contents(o) & " in range """ & rg.Address(0, 0) & """"
        Debug.Print String(80, "-")
        Debug.Print "Value (TypeName, Vartype)", "Found ", _
            "Lookin", "LookAt", "Cell"
        
        For f = 0 To UBound(FindValues)
            
            FindValue = FindValues(f)
            DateString = FindValue & " (" _
                & TypeName(FindValue) & ", " & VarType(FindValue) & ")"
        
            For i = 0 To UBound(Ins)
                For a = 0 To UBound(Ats)
                    On Error Resume Next
                        Set maxCell = rg.Find(What:=FindValue, _
                            After:=rg.Cells(rg.Cells.Count), _
                            LookIn:=Ins(i), LookAt:=Ats(a))
                    On Error GoTo 0
                    
                    If maxCell Is Nothing Then
                        Debug.Print DateString, "No    ", _
                            Ins(i), Ats(a)
                    Else
                        Debug.Print DateString, "Yes   ", _
                            Ins(i), Ats(a), maxCell.Address(0, 0)
                        Set maxCell = Nothing
                    End If
                Next a
            Next i
            
        Next f
    
    Next o

End Sub

测试结果

--------------------------------------------------------------------------------
Values in range "L2:L500"
--------------------------------------------------------------------------------
Value (TypeName, Vartype)   Found         Lookin        LookAt        Cell
6.8.2023. (Date, 7)         No            -4163          1 
6.8.2023. (Date, 7)         No            -4163          2 
6.8.2023. (Date, 7)         Yes           -4123          1            L6
6.8.2023. (Date, 7)         Yes           -4123          2            L6
6.8.2023. (Date, 7)         Yes           -4185          1            L6
6.8.2023. (Date, 7)         Yes           -4185          2            L6
45144 (Long, 3)             No            -4163          1 
45144 (Long, 3)             No            -4163          2 
45144 (Long, 3)             No            -4123          1 
45144 (Long, 3)             No            -4123          2 
45144 (Long, 3)             No            -4185          1 
45144 (Long, 3)             No            -4185          2 
08/06/2023 (String, 8)      Yes           -4163          1            L6
08/06/2023 (String, 8)      Yes           -4163          2            L6
08/06/2023 (String, 8)      No            -4123          1 
08/06/2023 (String, 8)      No            -4123          2 
08/06/2023 (String, 8)      No            -4185          1 
08/06/2023 (String, 8)      No            -4185          2 
--------------------------------------------------------------------------------
Formulas in range "M2:M500"
--------------------------------------------------------------------------------
Value (TypeName, Vartype)   Found         Lookin        LookAt        Cell
6.8.2023. (Date, 7)         No            -4163          1 
6.8.2023. (Date, 7)         No            -4163          2 
6.8.2023. (Date, 7)         No            -4123          1 
6.8.2023. (Date, 7)         No            -4123          2 
6.8.2023. (Date, 7)         No            -4185          1 
6.8.2023. (Date, 7)         No            -4185          2 
45144 (Long, 3)             No            -4163          1 
45144 (Long, 3)             No            -4163          2 
45144 (Long, 3)             No            -4123          1 
45144 (Long, 3)             No            -4123          2 
45144 (Long, 3)             No            -4185          1 
45144 (Long, 3)             No            -4185          2 
08/06/2023 (String, 8)      Yes           -4163          1            M6
08/06/2023 (String, 8)      Yes           -4163          2            M6
08/06/2023 (String, 8)      No            -4123          1 
08/06/2023 (String, 8)      No            -4123          2 
08/06/2023 (String, 8)      No            -4185          1 
08/06/2023 (String, 8)      No            -4185          2 
--------------------------------------------------------------------------------
A formula spilling in range "N2:N500"
--------------------------------------------------------------------------------
Value (TypeName, Vartype)   Found         Lookin        LookAt        Cell
6.8.2023. (Date, 7)         No            -4163          1 
6.8.2023. (Date, 7)         No            -4163          2 
6.8.2023. (Date, 7)         No            -4123          1 
6.8.2023. (Date, 7)         No            -4123          2 
6.8.2023. (Date, 7)         No            -4185          1 
6.8.2023. (Date, 7)         No            -4185          2 
45144 (Long, 3)             No            -4163          1 
45144 (Long, 3)             No            -4163          2 
45144 (Long, 3)             No            -4123          1 
45144 (Long, 3)             No            -4123          2 
45144 (Long, 3)             No            -4185          1 
45144 (Long, 3)             No            -4185          2 
08/06/2023 (String, 8)      Yes           -4163          1            N6
08/06/2023 (String, 8)      Yes           -4163          2            N6
08/06/2023 (String, 8)      No            -4123          1 
08/06/2023 (String, 8)      No            -4123          2 
08/06/2023 (String, 8)      No            -4185          1 
08/06/2023 (String, 8)      No            -4185          2

8ulbf1ek

8ulbf1ek2#

VBA的日期格式、本地数字格式和find方法有一个古老的问题,当你在一个单元格中看到其他东西时,会比较实际存储的值。不要问为什么,但这个代码是有效的

Set MaxCell = Rng.find(what:=CDate(MaxVal), LookIn:=xlFormulas)

字符串
在这种情况下,显示日期的示例化并不重要。

smtd7mpg

smtd7mpg3#

你知不知道你可以用这个公式得到这些信息?

=ROW(INDEX(B$3:B$11,MATCH(MAX(B$3:B$11),B$3:B$11,0)))

字符串
让我来解释一下它是如何工作的:

  • MAX(B$3:B$11)计算最大值。
  • MATCH(MAX(B$3:B$11),B$3:B$11,0)查找该列表中的最大值(使用“0”表示“完全匹配”)。
  • INDEX(...)查找在同一数组中找到的最大值的索引。
  • ROW(...).好吧,这是显而易见的:-)

玩得开心点

41zrol4v

41zrol4v4#

如果用公式计算的话

=MATCH(MAX(L:L),L:L,0)

字符串
如果要在VBA中计算,则可以使用Evaluate方法:

evaluate("=MATCH(MAX(L:L),L:L,0)")

相关问题