【问题标题】:VBA Macro to subtract dates by duplicates IDVBA宏通过重复ID减去日期
【发布时间】:2014-06-02 12:31:12
【问题描述】:

我想在 VBA 中创建一个宏来通过 ID 识别第一个日期和最后一个日期,然后以小时为单位获取它们之间的减法结果。

这是我的表的一个例子:

 ID         DATE   
 001        11/11/2013 
 001        11/21/2013
 001        11/25/2013
 002        12/04/2013
 002        12/05/2013
 003        12/05/2013
 001        11/23/2013  

想要的结果:

 ID         DATE           RESULT IN HOURS (Last Date - First Date)
 001        11/11/2013     =(11/25/2013)-(11/11/2013)
 001        11/21/2013
 001        11/25/2013
 002        12/04/2013     =(12/05/2013)-(12/04/2013) 
 002        12/05/2013
 003        12/05/2013
 001        11/23/2005

在当前表中,有 2 个或更多具有不同日期的重复 ID,如 001 ID 示例中所示。

我的第一个解决方案是按 ID 和日期对表格进行排序,然后应用 Countif 公式来获取重复的 ID,但我只能通过 ID 识别第一个日期而错过了最后一个日期。

非常感谢您的帮助。谢谢!

【问题讨论】:

  • 您可以使用最大值 if 公式获取最后日期:blog.contextures.com/archives/2011/07/27/…
  • 您是在excel还是access中使用表格?在访问中,我将使用基于查询的解决方案,在 excel 中,您必须“走”过表格。两种截然不同的野兽

标签: ms-access excel vba


【解决方案1】:

很好的问题。我喜欢使用集合,因为它们非常快。解决这样的问题肯定有很多方法,下面是一个例子:

Sub jzz()
Dim cArray() As Variant
Dim lastRow As Long

Dim rw As Long
Dim i As Long

Dim firstDate As Date
Dim lastDate As Date
Dim id As Long
Dim idColl As Collection

Set idColl = New Collection

'determine last row:
lastRow = Cells.SpecialCells(xlLastCell).Row

'if you plan to loop the cells repeatedly,
'the use of an array to hold cell values pays off, performancewise
cArray = Range(Cells(1, 1), Cells(lastRow, 2)).Value

For rw = 1 To lastRow
    id = Cells(rw, 1)
    'determine if id is used or not:
    For i = 1 To idColl.Count
        If idColl(i) = id Then GoTo nextRow
    Next i
    'id is not in collection, add it:
    idColl.Add id
    firstDate = cArray(rw, 2)
    lastDate = 0
    'loop array to find first and last dates:
    For i = LBound(cArray) To UBound(cArray)
        If cArray(i, 1) = id Then
            If cArray(i, 2) < firstDate Then firstDate = cArray(i, 2)
            If cArray(i, 2) > lastDate Then lastDate = cArray(i, 2)
        End If
    Next i
    Debug.Print id, firstDate, lastDate
nextRow:
Next rw
End Sub

Private Function TimeDiffHours(T0 As Date, T1 As Date) As String
'function that returns the difference between T0 and T1 in hours:mins
TimeDiffHours = Int((T1 - T0) * 24) & ":" _
                & Format(Round(((T1 - T0) * 24 - Int((T1 - T0) * 24)) * 60, 0), "00")
End Function

请注意,这只会找到每个 id 的第一个和最后一个日期并将其打印出来,以及以小时:分钟为单位的时差。它什么都不做,甚至不保存结果。现在由您决定。

【讨论】:

  • 很好的解决方案。我将以下几行添加到您的代码中以获得结果: Cells(rw, 3).Value = id Cells(rw, 4).Value = firstDate Cells(rw, 5).Value = lastDate 但是我遇到了一些错误通过 ID 确定日期。它获取每个 ID 的第一个 ID 的第一个日期。我一直在疯狂地试图修复它,但我找不到解决方案。 ID 的最后一个日期非常完美。
  • 将 firstDate = cArray (1, 2) 更改为 firstDate = cArray (rw, 2)。我认为应该这样做。我稍后会检查,因为我现在正在使用手机。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
  • 2014-10-01
  • 2011-03-06
  • 1970-01-01
  • 2016-08-31
  • 2013-01-23
相关资源
最近更新 更多