0

有谁知道如何在 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
4

1 回答 1

2

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

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

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

例子。假设您的有效范围在 2000 年 1 月 1 日到 2100 年 12 月 31 日之间。那么您的有效“数字排名”是:

  • 2000 年 1 月 1 日相当于 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 theValue` 属性,它可能会返回一个可以被评估为“不是日期”的双精度值或浮点值。

于 2013-04-01T23:21:53.993 回答