Range.Find在VBA Excel中1月到11月(2月和12月)没有区别

Vit*_*ata 5 excel datetime vba date excel-vba

假设我有以下琐碎的任务:

  • 写下2016年1月至2018年6月的第一个日期
  • 查找2016年1月1日,并将其涂成红色
  • 使用 Range.Find()

因此,我创建了一个代码,循环从1到30并写下每个月的第一个日期.然后我用Rows(1).Find(CDate("01.01.2016"))或者Rows(1).Find(DateSerial(2016,1,1))我认为我的任务几乎准备好了.

我运行代码,我在Excel 2010和Excel 2016中看到了这一点:

在此输入图像描述

问题: 背后有什么理由吗?或者Range.Find()记录的功能是这样的吗?

Public Sub TestMe()

    Cells.Clear

    Dim cnt             As Long
    For cnt = 1 To 30
        Cells(1, cnt) = DateAdd("M", cnt - 1, DateSerial(2016, 1, 1))
        Cells(1, cnt).NumberFormat = "MMM-YY"
    Next cnt

    Dim foundRange      As Range
    Set foundRange = Rows(1).Find(CDate("01.01.2016"))
    'Set foundRange = Rows(1).Find(DateSerial(2016, 1, 1))  'the same false result
    'Set foundRange = Rows(1).Find("01.01.2016")             'does not find anything
    If Not foundRange Is Nothing Then
        foundRange.Interior.Color = vbRed
    End If

End Sub
Run Code Online (Sandbox Code Playgroud)

通常,它Range.Find()有一个可选After参数,它是第一个单元格Range.在我们的例子中,After参数被省略,因此它被认为A1是最后检查的.如果在第一个循环后停止代码并Nov 16从Excel 手动删除,则继续执行代码,它将Jan 16以红色返回单元格.

至于11月被认为是发现的,它会让它回归,它不会更进一步.这个问题更像是-在什么逻辑是1 - 11月份-2016相同,1一月-2016,甚至部分?

Sco*_*ner 11

每当.Find(LookAt:=xlPart)在一系列日期上使用时,日期不会使用.Value2,而是默认将它们转换为String遵循美国日期格式 - MM/DD/YY并查看此字符串.只要将单元格格式化为日期,Excel中日期的显示格式就完全不相关了.

因此,1月的每一天都可以在11月找到,2月的每一天都可以作为子串在12月找到,在一个日历年内可能有58个(或闰年59个)不同的错误:

比较日期列表


为了避免这个错误,最好的解决方案是xlWhole明确地看待.如果未引用,则Range.Find()查找部分字符串.

另一个问题是从哪里Range.Find开始.根据该文件 它启动所提供的或默认的单元格,只有它循环返回后着眼于启动细胞.

您希望搜索开始的单元格.这对应于从用户界面进行搜索时活动单元的位置.请注意,After必须是范围内的单个单元格.请记住,搜索在此单元格之后开始; 在方法回绕到此单元格之前,不会搜索指定的单元格.如果未指定此参数,则搜索将在范围左上角的单元格后面开始.

因此,通过不定义XlWhole和开始单元格,搜索的第一个单元格B1不是A1,并且它在循环之前找到正确日期之前的部分日期.

因此,将起始单元格设置在范围的末尾将执行以下操作:

Set foundRange = Rows(1).Find(DateSerial(2016, 1, 1), [XFD1])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述