Excel 基于两个日期序列中的常用日期生成新的日期序列

Excel 基于两个日期序列中的常用日期生成新的日期序列,excel,excel-2010,vba,Excel,Excel 2010,Vba,我试图比较两个数据系列的日期,在第三列中只显示两个数据系列中常见的日期(按降序排列)。我的一位朋友帮我整理了一些代码,这些代码似乎很有效,但当我有相当长的一系列数据时,生成结果似乎需要很长时间。有没有一种方法可以以不同的方式编写此代码,从而加快计算速度?(我目前正在使用excel 2010 我在D2上输入并复制的函数是:=next_duplicate(A2:$A$535,B2:$B$535,D1:$D$1) 您可以在没有VBA的情况下执行此操作 在C列中,使用COUNTIF提取只出现在A列和B

我试图比较两个数据系列的日期,在第三列中只显示两个数据系列中常见的日期(按降序排列)。我的一位朋友帮我整理了一些代码,这些代码似乎很有效,但当我有相当长的一系列数据时,生成结果似乎需要很长时间。有没有一种方法可以以不同的方式编写此代码,从而加快计算速度?(我目前正在使用excel 2010

我在D2上输入并复制的函数是:
=next_duplicate(A2:$A$535,B2:$B$535,D1:$D$1)


您可以在没有VBA的情况下执行此操作

在C列中,使用COUNTIF提取只出现在A列和B列中的日期

=IF(COUNTIF($B$2:$B$7,"="&A2) > 0, A2, 0)
然后在D列中使用数组公式(从)排序并删除空格。不要忘记选择范围,然后按control、shift和enter键

=INDEX(C2:C7, MATCH(LARGE(IF(ISBLANK(C2:C7), "", IF(ISNUMBER(C2:C7), COUNTIF(C2:C7, "<"&C2:C7), COUNTIF(C2:C7, "<"&C2:C7)+SUM(IF(ISNUMBER(C2:C7), 1, 0))+1)), ROW()-ROW($D$2)+1), IF(ISBLANK(C2:C7), "", IF(ISNUMBER(C2:C7), COUNTIF(C2:C7, "<"&C2:C7), COUNTIF(C2:C7, "<"&C2:C7)+SUM(IF(ISNUMBER(C2:C7), 1, 0))+1)), 0))

=INDEX(C2:C7,MATCH(大)(IF)(ISBLANK(C2:C7),“”),IF(ISNUMBER)(C2:C7),COUNTIF(C2:C7),您可以在没有VBA的情况下执行此操作

在C列中,使用COUNTIF提取只出现在A列和B列中的日期

=IF(COUNTIF($B$2:$B$7,"="&A2) > 0, A2, 0)
然后在D列中使用数组公式(从)排序并删除空格。不要忘记选择范围,然后按control、shift和enter键

=INDEX(C2:C7, MATCH(LARGE(IF(ISBLANK(C2:C7), "", IF(ISNUMBER(C2:C7), COUNTIF(C2:C7, "<"&C2:C7), COUNTIF(C2:C7, "<"&C2:C7)+SUM(IF(ISNUMBER(C2:C7), 1, 0))+1)), ROW()-ROW($D$2)+1), IF(ISBLANK(C2:C7), "", IF(ISNUMBER(C2:C7), COUNTIF(C2:C7, "<"&C2:C7), COUNTIF(C2:C7, "<"&C2:C7)+SUM(IF(ISNUMBER(C2:C7), 1, 0))+1)), 0))

=索引(C2:C7,匹配(大的)(如果是空白的(C2:C7),”,如果是数字的(C2:C7),计数的(C2:C7),如果@Dan的解决方案有效,那么就这样做,因为公式解通常比较凉:)如果你需要使用VBA,你可以尝试以下方法:

Sub Common()

Dim Date1 As Range
Dim Date2 As Range
Dim CommonDates() As Variant
Dim UniqueDates As New Collection

Set Date1 = Range("A2:A6")
Set Date2 = Range("B2:B6")

' Change the max array size to equal the length of Date1
' This is arbitrary and could be more efficient, for sure :)
ReDim CommonDates(Date1.Count)

' Set a counter that will increment with matches
i = 0

' Since a match needs to be in both, iterate through Date1 and check
' if the Match function returns a True value when checking Date2.
' If so, add that value to the CommonDates array and increment the counter.
For Each DateVal In Date1
  If IsError(Application.Match(DateVal, Date2, 0)) = False Then
    CommonDates(i) = DateVal.Value
    i = i + 1
  End If
Next

' Filter out dupes (in case that is possible - if not, this can be removed
' and the bottom part reworked
On Error Resume Next
For Each Value In CommonDates
  UniqueDates.Add Value, CStr(Value)
Next Value

' Now go to the first cell in your Common Dates range (I'm using C2) and
' print out all of the results
Range("C2").Activate
For j = 1 To UniqueDates.Count
  ActiveCell.Value = UniqueDates(j)
  ActiveCell.Offset(1).Activate
Next j

' Back to the beginning
Range("C2").Activate

' Use this if you don't need to filter dupes
'For Each r In CommonDates
'  ActiveCell.Value = r
'  ActiveCell.Offset(1).Activate
'Next

End Sub

它基本上会在Date1上迭代,并检查匹配公式在Date2中是否成功/失败。A success=Match,这意味着一个普通的日期。然后将它们打印到另一列中。希望这有帮助!

如果@Dan的解决方案有效,那么就这样做吧,因为公式解决方案通常更酷:)如果需要使用VBA,您可以尝试以下方法:

Sub Common()

Dim Date1 As Range
Dim Date2 As Range
Dim CommonDates() As Variant
Dim UniqueDates As New Collection

Set Date1 = Range("A2:A6")
Set Date2 = Range("B2:B6")

' Change the max array size to equal the length of Date1
' This is arbitrary and could be more efficient, for sure :)
ReDim CommonDates(Date1.Count)

' Set a counter that will increment with matches
i = 0

' Since a match needs to be in both, iterate through Date1 and check
' if the Match function returns a True value when checking Date2.
' If so, add that value to the CommonDates array and increment the counter.
For Each DateVal In Date1
  If IsError(Application.Match(DateVal, Date2, 0)) = False Then
    CommonDates(i) = DateVal.Value
    i = i + 1
  End If
Next

' Filter out dupes (in case that is possible - if not, this can be removed
' and the bottom part reworked
On Error Resume Next
For Each Value In CommonDates
  UniqueDates.Add Value, CStr(Value)
Next Value

' Now go to the first cell in your Common Dates range (I'm using C2) and
' print out all of the results
Range("C2").Activate
For j = 1 To UniqueDates.Count
  ActiveCell.Value = UniqueDates(j)
  ActiveCell.Offset(1).Activate
Next j

' Back to the beginning
Range("C2").Activate

' Use this if you don't need to filter dupes
'For Each r In CommonDates
'  ActiveCell.Value = r
'  ActiveCell.Offset(1).Activate
'Next

End Sub


它基本上在Date1上迭代,并检查匹配公式在Date2中是否成功/失败。A success=Match,这意味着一个公共日期。然后将它们打印到另一列。希望这有帮助!

一列中是否存在重复值?例如,A列是否可以包含多个相同日期?或者非VBA解决方案如何。运行此表单ula针对日期更多的列(在您的示例中,现在针对列A运行)
=IF(iError(VLOOKUP(A2,$C$2:$C$6,1,FALSE)),“”和“Common”)
。它将为您提供另一列中存在的日期,您可以进行筛选或排序或其他任何操作来获取常见的日期。嗨,斯科特,不,dates_1或dates_2上没有重复的日期。问题是,我希望以某种自动方式(即函数)获取最终列表这样就不会有太多额外的排序/步骤来获取列表…只需3个步骤!1)编写公式2)自动填充3)排序(或筛选)!一列中是否存在重复值?例如,a列是否可以包含多个相同日期?或者非VBA解决方案如何。针对具有更多日期的列运行此公式(现在在您的示例中针对列A运行)
=IF(iError(VLOOKUP(A2,$C$2:$C$6,1,FALSE)),“”和“Common”)
。它将为您提供另一列中存在的日期,您可以进行筛选或排序或其他任何操作来获取常见的日期。嗨,斯科特,不,dates_1或dates_2上没有重复的日期。问题是,我希望以某种自动方式(即函数)获取最终列表这样就不会有太多额外的排序/步骤来获取列表…只需3个步骤!1)编写公式2)自动填充3)排序(或筛选)!谢谢RocketDonkey,因为即将到来的数据是动态的,理想情况下,我正在寻找一个函数而不是宏来处理数据…我目前拥有的函数似乎花费了太长的时间来计算和创建最终列表,所以我很好奇是否有更快的方法。啊,明白了,开始吧@Dan的解决方案。该解决方案(希望)可以避免每次更新工作表时重新计算公式的开销(这会降低性能,尤其是使用COUNTIFs)。我相信您的原始代码有点慢的原因是它在所有东西上都运行COUNTIF WorksheetFunction。我还没有尝试Dan的,但如果它工作相同,我将始终支持公式优于VBA方法:)谢谢RocketDonkey,因为即将到来的数据是动态的,理想情况下,我正在寻找一个函数而不是宏来处理数据……我目前拥有的函数似乎花费了太长的时间来计算和创建最终列表,所以我很好奇是否有更快的方法。啊,明白了-去@D然后,an的解决方案。此解决方案(希望)可以避免每次更新工作表时重新计算公式的开销(这可能会降低性能,尤其是使用COUNTIFs)。我相信你的原始代码有点慢的原因是它在所有东西上都运行COUNTIF WorksheetFunction。我还没有尝试Dan的,但如果它工作相同,我将始终支持VBA方法上的公式:)谢谢Dan,我注意到这将对最终的“常用日期”进行排序列表升序。有没有一种方法可以让它降序?(我试着从小到大地改变,但我把空格放在上面(我不喜欢它们)。我现在找不到,但我确实有一次指向了同一个链接,我相信他们说他们只是翻了所有的,以更改顺序。试试看。虽然这篇文章删除了空格,但我不确定这种行为会受到什么影响。实际上,如果你看一下我发送的链接,本系列的下一篇文章会这样做:是的,我昨天看到了那个链接,但由于列“C”中的单元格中有“”数据(而不是空白或空单元格),它们显示在顶部(如果你明白我的意思)我明白了,所以我将其更改为0而不是“”,这正确地进行了排序,但将00 Jan放在底部应该为空的单元格中。你可以用if进行排序(整个数组公式)