【问题标题】:Sort/lookup data by multiple criteria AND from latest date in column按多个条件和从列中的最新日期排序/查找数据
【发布时间】:2016-04-19 03:39:31
【问题描述】:

我有数千条记录,其中显示了四列数据(下面列出的粗体记录):


AccountNo......产品类型......AmountPaid......订阅日期
1001......Wood...... .............912.34............03/01/2016
1002......木材............987.21...... 2015 年 6 月 1 日
1003......钻石............500.24............04/01/2015
1001......................煤炭............125.32...... ......04/01/2014
1003......木材............789.25...... 09/01/2015
1543………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………147.25 ..07/01/2015
1001......................木材...... .958.25...........03/01/2016
1003......................钢............658.51...... .03/01/2016
1008......................木材............587.95...... 2015 年 2 月 1 日
1001......................钢...... 458.58...........2015 年 6 月 1 日
1232......................木材............951.21...... 2015 年 6 月 1 日


我要做的是找出属于最新“订阅日期”的“AccountNo”的所有类型产品的总支付金额是多少

例如,我可以确认帐号。 '1001'在 2016 年 3 月 1 日的最新订阅日期支付了 1870.59。

我想知道每个帐号的这一点。我已经尝试了多个条件的索引/匹配,但我无法弄清楚如何在订阅日期字段中提取 only 的最新日期。然后我制作了一个数据透视表并按最大日期排序,但由于产品类型和支付金额不同,我无法弄清楚如何提取其余数据。

谁能帮助我?我认为这是一件非常简单的事情,但我完全被难住了。

【问题讨论】:

  • 前几天遇到了一个与此非常相似的问题,VBA 是否可以接受,有人想按照这条路线给你一个答案吗?辅助单元格或其他列是否可接受?
  • VBA 就可以了!我只需要一个解决方案:(大声笑。谢谢你的回复。我现在就去看看

标签: excel vba


【解决方案1】:

好的,我从另一个 here 中提取了此代码。它不适用于日期,所以我不得不稍微调整一下。与 Excel 内置的 SUMIF 类似,此用户定义函数将 MAXIMUM 拉出必须满足条件的范围。

Public Function MAXIF(ByVal rgeCriteria As Range, _
                      ByVal sCriteria As String, _
                      ByVal rgeMaxRange As Range) As Single
                      
Dim iconditioncolno As Integer
Dim inumberscolno As Integer
Dim lrowno As Long
Dim sngmax As Variant
Dim vcellvalue As Variant

        
   iconditioncolno = rgeCriteria.Column
   inumberscolno = rgeMaxRange.Column
   For lrowno = 1 To rgeCriteria.Rows.Count
      vcellvalue = rgeCriteria.Parent.Cells(rgeCriteria.Row + lrowno - 1, inumberscolno).Value
      If rgeCriteria.Parent.Cells(rgeCriteria.Row + lrowno - 1, iconditioncolno).Value = sCriteria And (IsNumeric(vcellvalue) = True Or IsDate(vcellvalue) = True) Then

      'I had to add the IsDate and OR to the above check to make it work with dates

         If sngmax = 0 Then sngmax = vcellvalue
         If vcellvalue > sngmax Then sngmax = vcellvalue
      End If
      
      If sngmax <> 0 And IsEmpty(vcellvalue) = True Then Exit For
   Next lrowno
    
   For lrowno = 1 To rgeCriteria.Rows.Count
      vcellvalue = rgeCriteria.Parent.Cells(rgeCriteria.Row + lrowno - 1, inumberscolno).Value
      If rgeCriteria.Parent.Cells(rgeCriteria.Row + lrowno - 1, iconditioncolno).Value = sCriteria And _
         IsNumeric(vcellvalue) = True Then
         If rgeCriteria.Parent.Cells(rgeCriteria.Row + lrowno - 1, inumberscolno).Value > sngmax Then
            sngmax = rgeCriteria.Parent.Cells(rgeCriteria.Row + lrowno - 1, inumberscolno).Value
         End If
      End If
      
      If sngmax <> 0 And IsEmpty(vcellvalue) = True Then Exit For
   Next lrowno
    
   MAXIF = sngmax
End Function

我将代码放在模块部分。然后我将新的 UDF 与内置的 SUMIFS 结合起来生成这个公式:

=SUMIFS(C2:C12,A2:A12,F2,D2:D12,MAXIF(A2:A12,F2,D2:D12))

现在,由于您有大约一千行数据,您可能不期待定义所有这些范围。如果您可以查看整个列(所有 1048576 行),那么您可以执行以下操作:

=SUMIFS(C:C,A:A,F2,D:D,MAXIF(A:A,F2,D:D))

或者您可以使用 OFFSET 和 COUNT 来实现,但它会变得丑陋且难以快速阅读。

更新

如果您也想知道与您查询的帐号相邻的最新日期是什么,您可以单独使用 MAXIF() 公式:

MAXIF(A2:A12,F2,D2:D12)

然后在它旁边的列中,您可以使用 sumproduct 而不是 sumifs。

=sumproduct(($A$2:$A$12=F2)*($D$2:$D$12=G2)*($C$2:$C$12))

不确定它是否比使用 sumifs 更好,但它是您的另一种选择。这种方法的好处之一是,如果您有一个想要搜索的特定日期,您只需输入它并将 MAXIF 公式替换为特定日期。

【讨论】:

  • 是的......是间距。这些在传统的 excel 单元格中。日期字段也是数字。
  • @MiguelM 以前的答案对您不起作用,因为它仅适用于每个客户帐户的唯一日期。因此,我删除了该代码并从另一个站点引入了该代码,对其进行了细微调整,然后瞧瞧了一个希望对您有用的解决方案。我为您提供了一个屏幕截图,以显示它与您的示例数据相加。
  • 转发。这完美地工作。不过有一个缺点。我不想逐一查找。我想为第一列中的每个“AccountNo”执行此操作。在我的原始文件中,我可能有 75k 条记录。有没有办法我可以使用这个(出色的)脚本来快速运行所有 AccountNo,以根据他们最新的“订阅日期”提取他们所有的“AmountPaid”?所以我所做的是将唯一的“AccountNo's”拉入F列,然后将公式向下拖动。但是,对于 75k,这将在计时 10 行处理后大约需要 29 小时。有更快的方法吗?
  • 那将是一个稍微不同的问题。您想生成一个新的唯一编号列表,或者更通常称为“从列中删除重复项”。看看这个问题,因为它已经被问过很多次了。如果您能找到答案,只需将此公式复制到您的列表旁边即可。
  • 是的,我已经过滤掉了重复项,并将唯一的 Accountno 放在 F 列中。但是,当我向下拖动第二列时,需要一段时间才能呈现信息(没关系)只是想知道是否有更快的方法。
【解决方案2】:

使用下面的公式得到你的结果。

=SUMIFS(C:C,A:A,"1001",D:D,"03/01/2016")

如果您想一次性获取所有数据。你可以去VBA

【讨论】:

  • 你怎么知道 03/01/2016 是超过 1k 条记录的最近日期?
  • @ForwardEd。好问题。但是我们需要将日期和账号解析为参数
猜你喜欢
  • 2019-10-04
  • 1970-01-01
  • 2018-03-31
  • 2020-08-29
  • 1970-01-01
  • 2019-09-25
  • 2019-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多