MS Excel:查找一行混合内容的最早日期

时间:2013-04-01 23:03:38

标签: excel vba excel-vba excel-formula

有没有人知道如何在Microsoft Excel中连续获得最早的日期。每行上没有可预测的列数,并且除了日期之外还有其他值需要忽略。可以使用Excel公式或VBA来完成。

有人有任何建议吗?

现在我正在使用这个快速而又脏的VBA功能,但是当我加载新的输入数据(大约200行乘100列)时,出现了一个消息框,说Excel没有足够的资源来处理我的更改。

' returns smallest date on row
Public Function getSmallestDateFromRow(r As Integer, sheetName As String) As Date
    Dim toReturn As Date
    Dim rng As Range
    Dim scanToColumn As Integer
    Dim c As Integer
    Dim tmp As Variant

    Set rng = Sheets(sheetName).Cells.Find("*", [a1], , , xlByColumns, xlPrevious) 'is this inefficient?
    scanToColumn = rng.Column
    toReturn = #12/12/2100#

    For c = 1 To scanToColumn
        tmp = Sheets(sheetName).Cells(r, c).Value
        If (IsDate(tmp)) Then
            If (toReturn = Null) Then
                toReturn = tmp
            ElseIf (toReturn > tmp) Then
                toReturn = tmp
            End If
        End If
    Next c

    If (toReturn = #12/12/2100#) Then
       toReturn = 0
    End If

    getSmallestDateFromRow = toReturn
End Function

1 个答案:

答案 0 :(得分:2)

您必须记住Excel(以及许多其他Microsoft产品)将日期存储为浮点数:

  • 整数部分是自1900年1月1日以来经过的天数(例如:1相当于1/1/1900)
  • 小数部分是过去一天的“分数”(例如:0.5相当于中午12点)

关于如何找到最小或最大日期值的问题然后被您的行中可能有许多其他数字的事实混淆。因此,您必须首先定义日期的“有效排名”。在那之后,一个简单的“数组公式”可以做到这一点:

示例。假设您的有效范围介于2000年1月1日至2100年12月31日之间。那么您的有效“数字排名”为:

  • 1/1/2000相当于36526
  • 12/31/2100相当于73415

现在您可以编写函数来跟踪此范围内的最小日期值:

function trackMinimum(rowRange as range) as date
    on error resume next
    dim j as integer, minValue as date
    dim t0 as double, t1 as double
    dim ans as date

    t0 = cdbl(dateserial(2000,1,1))
    t1 = cdbl(dateserial(2100,12,31))
    ans = 0
    for j = 1 to rowRange.columns.count
        if ans = 0 then ' You need to store the first valid value
            if rowRange.cells(1,j).value >= t0 and rowRange.cells(1,j) <= t1 then
                ans = rowRange.cells(1,j).value
            end if
        else
            if (rowRange.cells(1,j).value >= t0 and rowRange.cells(1,j) <= t1) _ 
               and rowRange.cells.value < ans then
                ans = rowRange.cells(1,j).value
            end if
        end if
    next j
    trackMinimum = ans
end function

当然我假设rowRange参数是单行范围。

希望这有助于你


顺便说一句,isDate()函数不是“故障安全”:它必须采用有效的表达式(文本)来检测它是否是日期,这可能取决于格式。也就是说,您可能更喜欢使用isDate(.cells(r,c).Text)' instead of。value , since the Value`属性可能返回一个双值或浮点值,可以将其评估为“非日期”。