在Excel/VBA中使用日期早于1900年3月1日的CountIF

在Excel/VBA中使用日期早于1900年3月1日的CountIF,excel,vba,date,Excel,Vba,Date,我对Execl有一个奇怪的问题。特定单元格的值为01.01.1900,单元格的格式为date-format。当我试图通过CountIf计算01.01.1900的实例数时,如果结果为0,则通过CDate()-转换创建搜索词。以下是完整的代码: Dim searchterm as Date Dim someRange as Range searchTerm = CDate("01.01.1900") Application.WorksheetFunction.CountIf(someRange, s

我对Execl有一个奇怪的问题。特定单元格的值为
01.01.1900
,单元格的格式为
date
-format。当我试图通过
CountIf
计算
01.01.1900
的实例数时,如果结果为
0
,则通过
CDate()
-转换创建搜索词。以下是完整的代码:

Dim searchterm as Date
Dim someRange as Range
searchTerm = CDate("01.01.1900")
Application.WorksheetFunction.CountIf(someRange, searchTerm)
当日期在1900年3月1日之前开始时,整个过程按预期进行。根据日期
01.01.1900
我得到以下结果:

VarType(singleCellRange)
返回
7
(即

singleCellRange.Value
返回
31.12.1899
(另请参见)


因此,问题是:如何为有问题的日期获取正确的格式,以便使
CountIf
再次工作?

VBA日期数据类型和Excel日期不相同

它们都存储为序列号,但使用Excel(使用1900系统):

  • Excel(使用1900系统):
    1
    -->
    1 1900年1月
  • VBA:
    1
    -->
    1899年12月31日
由于Excel(错误地)将1900年2月29日<代码>识别为有效日期,因此基础值在1900年3月1日<代码>及之后变得一致

根据在此范围内计算日期的重要性,有多种变通方法

如果日期早于1900年3月1日,最简单的方法可能是从vba日期比较器中减去
1


编辑:据一些人说,对这个错误的解释是为了与引入Excel时的premier工作表兼容:Lotus123,它有相同的错误。因此,它和Excel一样存在了很长时间,而且它不太可能被更改,因为担心破坏考虑到它的程序。

VBA日期数据类型和Excel日期不一样

Sub CountDate()
  Dim searchterm As Date, sh As Worksheet, someRange As Range
  Set sh = ActiveSheet ' use here your worksheet
  Set someRange = sh.Range("A2:A13")
  searchterm = CDate("01.01.1900")
  If CLng(searchterm) < 61 Then
      Debug.Print Application.WorksheetFunction.CountIf(someRange, CLng(searchterm) - 1)
  Else
      Debug.Print Application.WorksheetFunction.CountIf(someRange, CLng(searchterm))
  End If
End Sub
它们都存储为序列号,但使用Excel(使用1900系统):

  • Excel(使用1900系统):
    1
    -->
    1 1900年1月
  • VBA:
    1
    -->
    1899年12月31日
由于Excel(错误地)将1900年2月29日<代码>识别为有效日期,因此基础值在1900年3月1日<代码>及之后变得一致

根据在此范围内计算日期的重要性,有多种变通方法

如果日期早于1900年3月1日,最简单的方法可能是从vba日期比较器中减去
1

编辑:据一些人说,对这个错误的解释是为了与引入Excel时的premier工作表兼容:Lotus123,它有相同的错误。因此,它和Excel一样存在了很长一段时间,而且它不太可能被更改,因为担心破坏考虑到它的程序。

Sub CountDate()
Sub CountDate()
  Dim searchterm As Date, sh As Worksheet, someRange As Range
  Set sh = ActiveSheet ' use here your worksheet
  Set someRange = sh.Range("A2:A13")
  searchterm = CDate("01.01.1900")
  If CLng(searchterm) < 61 Then
      Debug.Print Application.WorksheetFunction.CountIf(someRange, CLng(searchterm) - 1)
  Else
      Debug.Print Application.WorksheetFunction.CountIf(someRange, CLng(searchterm))
  End If
End Sub
Dim searchterm作为日期,sh作为工作表,someRange作为范围 设置sh=ActiveSheet'在此处使用您的工作表 设置someRange=sh.Range(“A2:A13”) searchterm=CDate(“01.01.1900”) 如果CLng(搜索术语)<61,则 Debug.Print Application.WorksheetFunction.CountIf(someRange,CLng(searchterm)-1) 其他的 Debug.Print Application.WorksheetFunction.CountIf(someRange,CLng(searchterm)) 如果结束 端接头
所有的功劳都要归功于@Ron Rosenfeld,他解释了为什么

由于Excel和VBA仅在1900年3月1日之后才开始匹配同一日期,且该日期的序列号为61,因此以这种方式调整搜索条件,您将始终获得正确的匹配。

Sub CountDate()
Dim searchterm作为日期,sh作为工作表,someRange作为范围
设置sh=ActiveSheet'在此处使用您的工作表
设置someRange=sh.Range(“A2:A13”)
searchterm=CDate(“01.01.1900”)
如果CLng(搜索术语)<61,则
Debug.Print Application.WorksheetFunction.CountIf(someRange,CLng(searchterm)-1)
其他的
Debug.Print Application.WorksheetFunction.CountIf(someRange,CLng(searchterm))
如果结束
端接头
所有的功劳都要归功于@Ron Rosenfeld,他解释了为什么


由于Excel和VBA仅在1900年3月1日之后才开始匹配同一日期,且该日期的序列号为61,因此以这种方式调整搜索,您将始终获得正确的匹配。

在这个主题上,有一篇文章提到了Lotus 1-2-3兼容性问题,以及为什么Excel中不会出现此错误fixed@barrowc2019年的那篇文章呼应了其他已经写了20多年的文章。但这是一个很好的总结。有趣的是,为了正确读取单元格中的日期,我总是需要检查它的值是否在1.3.1990之前,并减去1,否则我会得到错误的日期。可能会添加另一个检查,以防MS决定在将来修复该错误。在这个主题上有一个问题提到了Lotus1-2-3兼容性问题,以及为什么Excel中不会出现该错误fixed@barrowc2019年的那篇文章呼应了其他已经写了20多年的文章。但这是一个很好的总结。有趣的是,为了正确读取单元格中的日期,我总是需要检查它的值是否在1.3.1990之前,并减去1,否则我会得到错误的日期。可能会添加另一个检查,以防MS决定在将来修复该错误。代码中的一些进一步解释和/或注释可能对其他方面有所帮助users@Albin当前位置我不认为这是显而易见的。。。但是,好的,我将添加一些注释…代码中的一些进一步解释和/或注释可能对其他方面有所帮助users@Albin当前位置我不认为这是显而易见的。。。但是,好的,我会添加一些评论。。。