Range.Find 在作为公式的日期上
Posted
技术标签:
【中文标题】Range.Find 在作为公式的日期上【英文标题】:Range.Find on a Date That is a Formula 【发布时间】:2018-01-20 05:37:54 【问题描述】:我收到一份工作簿,其中包含有关呼叫中心团队处理量的信息。我无法修改上游工作簿的格式或布局。
一张表包含有关处理错误的信息。 (团队成员的用户 ID 已编辑)
每个日期由合并的 1x3 范围表示,相关日期格式为“dd-mmm”,例如“01-6月”
该日期是通过公式从具有相同布局的另一张表中提取的。此类范围的公式为:='QA Scores'!K2:M2
我尝试使用Range.Find
来定位给定月份的第一天和同月的结束日期(基于用户输入) - 例如6 月 1 日至 6 月 15 日。
Set rngMin = .Find(What:=DateValue(minDate), _
LookIn:=xlFormulas, _
LookAt:=xlWhole)
在其他用途中,我以这种方式定位日期,但来自公式的值的附加复杂性似乎是这里的问题。
更新: 我根据 Ron Rosenfeld 的回答写了以下内容:
Dim UsedArr As Variant: UsedArr = SrcWS.UsedRange
blFound = False
For i = LBound(UsedArr, 1) To UBound(UsedArr, 1)
For j = LBound(UsedArr, 2) To UBound(UsedArr, 2)
If UsedArr(i, j) = MinDate Then
blFound = True
Exit For
End If
Next
If blFound = True Then Exit For
Next
【问题讨论】:
Range.Find
在调用之间保持其可选参数 - 一个讨厌的容易出错的行为;确保每次都指定所有参数以避免它咬你。
如果你想找到一个公式的表达式,xlValues
不正确吗?
@Mat'sMug 感谢您提供这些信息。在这种情况下,这不是问题,但很高兴知道未来。 @DirkReichel 可悲的是,没有。 xlValues
仅检查工作表上显示内容的 .Text
属性。
用xlValues
搜索Format(DateValue(minDate),"[$-en-US]dd-mmm")
也不起作用?
奇怪的是,不,这不起作用。这实际上表明xlValues
不仅仅关注.Text
属性...
【参考方案1】:
使用Range.Find
方法很难找到日期。问题之一是在 VBA 中,日期属于 Date
数据类型,但工作表没有该数据类型。相反,数据类型是一个数字,其格式看起来像一个日期。
如果您可以确定工作表上日期的格式,一个解决方案是搜索等效的字符串。鉴于你的例子,这样的事情会起作用:
Option Explicit
Sub GetDates()
Const findDate As Date = #5/11/2017#
Dim findStr As String
Dim R As Range, WS As Worksheet
Set WS = Worksheets("Sheet1")
findStr = Format(findDate, "dd-mmm")
With WS
Set R = .Cells.Find(what:=findStr, LookIn:=xlValues, lookat:=xlWhole)
If Not R Is Nothing Then MsgBox findDate & " found in " & R.Address
End With
End Sub
但它不是很健壮,因为在许多情况下,用户可以更改格式。
另一种更稳健的方法是遍历现有单元格,查找日期的数字表示(使用Value2
属性):
Sub GetDates2()
Const findDate As Date = #5/11/2017#
Dim R As Range, C As Range, WS As Worksheet
Set WS = Worksheets("sheet1")
Set R = WS.UsedRange
For Each C In R
If C.Value2 = CDbl(findDate) Then MsgBox findDate & " found in " & C.Address
Next C
End Sub
如果您要搜索的范围很大,可以通过将范围读入 VBA 数组并循环遍历该数组,将搜索速度提高 10 倍。
【讨论】:
是的,第二种方法几乎是防弹的,尤其是在你的情况下。 我不明白为什么,但第一种方法不起作用。但是,第二种方法可以。我已将为此编写的代码添加到我的原始帖子中。谢谢!【参考方案2】:@KOstvall,我想建议这种简单的查找方法,因为您正在尝试获取日期。
设置 rng = Sheet1.Range("A:A").Find("1/1/2017", LookIn:=xlValue, LookAt:=xlWhole)
【讨论】:
不,这不起作用,因为在这种情况下,xlFormulas
值是公式而不是日期。
这可以帮助您找到日期。 Private Sub Finddate () Dim dateval , Dim Date row, Dim DateCol dateval = Range("A8").Value Cells.Find(What:=dateval, After:=ActiveCell, LookIn:=xlValues, LookAt:= _ xlPart,SearchOrder :=xlByRows, SearchDirection:=xlNext, MatchCase:=False _, SearchFormat:=False).Activate DateRow = ActiveCell.Row DateCol = ActiveCell.Column MsgBox (DateRow & " " & DateCol) End Sub【参考方案3】:
在使用 .find
作为日期时遇到了同样的问题。即使搜索的目标日期格式是 dd-mmm
使用 .find 和 d-mmm
格式。
Date_Value = Application.Text(Date_Value, "d-mmm-yy") 'Use Format for your case
Set r_gt= .Range(EODate_Range).Find(Date_Value, LookIn:=xlValues)
PS:如果目标日期格式为dd-mm-yy
,则必须循环遍历单元格。
在将搜索格式更改为d-mm-yy
/ d-m-yy
后尝试了01-01-20
的上述代码,但找不到日期,但如果将单元格格式更改为01-Jan-20
,它会找到日期。
【讨论】:
【参考方案4】:更新:我修改了下面的代码以在查找之前设置活动单元格。第二个动画 gif 显示正在运行的代码
一种方法是根据特定日期格式进行查找,在您的情况下似乎是"[$-en-US]dd-mmm;@"
。以下是一个简单的示例,您可以根据需要进行调整。为了使这个示例工作,将 3 个日期放入“A1:A3”,其中只有一个具有所需的格式,然后运行宏。动画 gif 显示了如何设置格式。
Sub dateFormatFind()
Dim sh As Worksheet, searchR As Range
Dim cell As Range, resultR As Range
Set sh = Worksheets("Sheet5")
Set searchR = sh.Range("A1:A3")
Set resultR = sh.Range("C1")
sh.Range("A1").Activate
Application.FindFormat.NumberFormat = "[$-en-US]dd-mmm;@"
resultR = searchR.Find(What:="", After:=ActiveCell, _
LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=True)
End Sub
【讨论】:
当我尝试完全按照您上面概述的方式设置 FindFormat 时,出现一般错误 1004。 感谢您指出这一点。也许是因为我在运行代码时激活了单元格 A1 而你没有。无论如何,我现在已经修改了代码以确保不会发生这种情况,并提供了一个动画 gif 来显示代码正在运行。以上是关于Range.Find 在作为公式的日期上的主要内容,如果未能解决你的问题,请参考以下文章