【问题标题】:Retrieve Cell Value in Excel with largest date between duplicates在Excel中检索重复项之间最大日期的单元格值
【发布时间】:2013-03-21 21:28:15
【问题描述】:

我在 Excel 2010 的 Excel 工作表中有以下列:

Batch Number        BatchID            END TIME
120319-0001     120319-0001_TEST1   3/20/12 13:44
120319-0001     120319-0001_TEST2   3/20/12 10:05
120319-0002     120319-0002_TEST1   3/20/12 14:40
120319-0002     120319-0002_TEST2   3/20/12 12:46
120319-0003     120319-0003_TEST1   3/20/12 14:01
120319-0003     120319-0003_TEST2   3/20/12 12:11
120319-0004     120319-0004_TEST1   3/20/12 15:37
120319-0004     120319-0004_TEST2   3/20/12 11:59
120319-0005     120319-0005_TEST1   3/20/12 19:06
120319-0005     120319-0005_TEST2   3/20/12 11:47

我需要一个可以填写在第 4 列中的公式,该公式将执行以下操作:

  • 选择“批号”列中的所有重复项
  • 在“END TIME”列中查找重复项的最大值
  • 在所有重复项的“END TIME”中,使用“BatchID”列中的单元格值填充第 4 列

第 4 列的预期输出:

120319-0001_TEST1
120319-0001_TEST1
120319-0002_TEST1
120319-0002_TEST1
120319-0003_TEST1
120319-0003_TEST1
120319-0004_TEST1
120319-0004_TEST1
120319-0005_TEST1
120319-0005_TEST1

我尝试过使用INDEXMATCHIF 语句的组合,但还没有使用。

我也愿意使用 VBA/宏解决方案。

【问题讨论】:

  • 输出,我猜你是从更大的数据集中得到的?如果是这样,您可以删除示例数据集中没有的那些吗? (可能有误,重读后)
  • @NickSlash 是的,这些是对具有 > 50,000 行和更多列的原始数据集的伪修改
  • 先做一个排序来协助一次fx是否可行?或者这是否需要成为一个持续的实时公式?
  • @Kevin 我对 BatchID 进行了排序,以将“批号”中的所有重复项放在一起以供我尝试,但可以在填写列之前对任何列进行排序。它不需要是一个实时公式
  • @jordanhill123 嘿朋友!!!!!!!!!

标签: excel excel-formula vba


【解决方案1】:

我快速尝试使用公式,但我认为您可能需要使用数组公式,它们对我来说毫无意义!

下面的宏应该可以做到这一点。 (不过比较时间戳可能是个问题)

Sub Main()
Dim Sheet As Worksheet
Dim Data As Range

Set Sheet = ThisWorkbook.Worksheets("Sheet1")
Set Data = Sheet.Range("A2:A" & Range("A" & Range("A" & Sheet.UsedRange.Rows.Count).Row)

Dim BatchNumber As Variant
Dim EndTime As Variant
Dim Result As Variant

BatchNumber = Data.Value2
BatchID = Data.Offset(ColumnOffset:=1).Value2
EndTime = Data.Offset(ColumnOffset:=2).Value2
Result = Data.Offset(ColumnOffset:=3).Value2

Dim Index As Integer
Dim Lookup As Integer
Dim Max As Integer

For Index = LBound(BatchNumber, 1) To UBound(BatchNumber, 1)
    Max = Index
    For Lookup = LBound(BatchNumber, 1) To UBound(BatchNumber, 1)
        If BatchNumber(Lookup, 1) = BatchNumber(Index, 1) Then
            If Not Lookup = Index Then
' NOTE: you might to do stuff to the date/time comparison below to get it to work correctly
                If EndTime(Lookup, 1) > EndTime(Index, 1) Then
                    Max = Lookup
                Else
                    Max = Index
                End If
            End If
        End If
    Next Lookup
    Result(Index, 1) = BatchID(Max, 1)
Next Index

Data.Offset(ColumnOffset:=3).Value2 = Result

End Sub

更新

下面的应该会快一点,因为它只迭代数据集 once 两次。而不是第一个 Rows*Rows 迭代(我认为)。

Sub Main2()
Dim Sheet As Worksheet
Dim Data As Range
Dim vData As Variant
Dim vResult As Variant
Set Sheet = ThisWorkbook.Worksheets("Sheet1")
Set Data = Sheet.Range("A2:A" & Range("A" & Sheet.UsedRange.Rows.Count).Row)

vData = Data.Resize(ColumnSize:=3).Value2
vResult = Data.Value2
Dim List As Object

Set List = CreateObject("Scripting.Dictionary")

Dim Index As Integer
Dim Key As String

For Index = LBound(vData, 1) To UBound(vData, 1)
    Key = vData(Index, 1)
    If List.exists(Key) Then
        If vData(Index, 3) > vData(List(Key)(1), 3) Then
            List(Key)(1) = Index
        End If
    Else
        List.Add vData(Index, 1), Array(Index, Index)
    End If
Next Index

For Index = LBound(vData, 1) To UBound(vData, 1)
    Key = vData(Index, 1)
    vResult(Index, 1) = vData(List(Key)(1), 2)
Next Index

Data.Offset(ColumnOffset:=3).Value2 = vResult

Set List = Nothing

End Sub

【讨论】:

  • 您可以通过检查集合中是否有多个批次号来加快子例程(根据问题的第一步)。可能Filter 函数会很有用。
  • “选择重复项”(我相信)只是为了比较 end time 的值并为结果选择最大的值
  • 我觉得有些批号不能在单子上重复。无论如何,我认为使用dictionary 要好得多。
  • @NickSlash 我只在第 4 列中填充第一行。有任何想法吗? MainMain2 例程的结果相同
  • 列引用是否正确?如果您的数据不在列 A:C + D 中,则它们可能无法按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
相关资源
最近更新 更多