简体   繁体   English

VBA range.find 发现错误的日期值

[英]VBA range.find finds wrong date value

I am looking up a price multiplier for a given date in an Excel sheet, but range.find gives the wrong date.我正在 Excel 工作表中查找给定日期的价格乘数,但 range.find 给出了错误的日期。 Here are the relevant code snippets:以下是相关的代码片段:

If Not IsWbOpen("daily_prices.xlsx") Then
        Workbooks.Open "C:\.....\daily_prices.xlsx"
    End If
    Set daily = Workbooks("daily_prices.xlsx").Sheets(1)
    daily.Range("A:A").NumberFormat = "dd/mm/yyyy"
End If

This part makes sure that the column A:A, which contains the dates, is formatted correctly.这部分确保包含日期的列 A:A 的格式正确。 The code then loops through a date range where d is a date between d1 and d2.然后代码循环遍历一个日期范围,其中 d 是 d1 和 d2 之间的日期。 In my test script, d1= Jan 1, 2023 (formatted as "01/01/2023"), and d2 = Jan 30, 2023 (formatted as "30/01/2023").在我的测试脚本中,d1= Jan 1, 2023(格式为“01/01/2023”),d2 = Jan 30, 2023(格式为“30/01/2023”)。 The Excel sheet "daily" has a header in row 1 and 49 different dates in column A, ordered chronologically from "11/01/2023" to "01/01/2024", and the related multiplier (k), starting in row 2. Only the dates that have a multiplier defined are present in the sheet. Excel 工作表“daily”在第 1 行有 header,在 A 列有 49 个不同的日期,按时间顺序从“11/01/2023”到“01/01/2024”,以及相关的乘数 (k),从行开始2. 只有定义了乘数的日期才会出现在工作表中。 The first group of dates is from "11/01/2023" at row 2 to "22/01/2023" at row 13, the next starts with "17/02/2023" at row 14, and so on.第一组日期从第 2 行的“11/01/2023”到第 13 行的“22/01/2023”,下一组从第 14 行的“17/02/2023”开始,依此类推。 Dates in between have no multiplier, and thus are not present.介于两者之间的日期没有乘数,因此不存在。 I search the multiplier with this part of the code:我用这部分代码搜索乘数:

Set c = daily.Range("A:A").Find(what:=d, After:=Range("A1"), LookIn:=xlValues)    'is this date in the daily prices?
  If Not c Is Nothing Then
     k = CDec(daily.Cells(c.Row, 4))  ' multiplier is in column 4 (D:D)
     rate = rate * k
  End If

As expected, c is NOTHING for all dates below "11/01/2023".正如预期的那样,c 对于“11/01/2023”以下的所有日期都是空的。 When d = "11/01/2023", c becomes "not NOTHING" but strangely it returns "11/11/2023" instead of "11/01/2023", which is in row 40 instead of row 2, thus it fetches the multiplier of row 40 instead of row 2. I have re-checked all the code after reading several similar cases and made sure that column A is formatted correctly as "date", but I still get "11/01/2023" wrongly 'found' at row 40 instead of row 2, and the value returned is "11/11/2023" instead of "11/01/2023".当 d = "11/01/2023" 时,c 变为 "not NOTHING" 但奇怪的是它返回 "11/11/2023" 而不是 "11/01/2023",它位于第 40 行而不是第 2 行,因此它获取第 40 行而不是第 2 行的乘数。我在阅读了几个类似的案例后重新检查了所有代码,并确保 A 列的格式正确为“日期”,但我仍然错误地得到“11/01/2023” 'found' 在第 40 行而不是第 2 行,返回的值是“11/11/2023”而不是“11/01/2023”。 Instead of "12/01/2023", it finds "31/12/2023", and instead of "14/01/2023", which is part of the dataset, it finds nothing.它没有找到“12/01/2023”,而是找到了“31/12/2023”,也没有找到作为数据集一部分的“14/01/2023”,但什么也没找到。 What did I overlook, where is the error?我忽略了什么,错误在哪里?

Eventually, I found the solution.最终,我找到了解决方案。 It appears that using dates formatted as dates leads to ambiguity with Range.Find(d) as it's very similar to a text search, and depending what date format you use, their partial strings (month and day) may create confusion in certain language versions of Windows. I noticed this when I was looking for a date with day=11 or 12 and found a date with month=11 or 12. This is typical for the confusion that occurs sometimes when you use data formats like "mm-dd-yyyy" (US) and "dd/mm/yyyy" (other) and looks like a Windows bug to me.看起来使用格式化为日期的日期会导致 Range.Find(d) 出现歧义,因为它与文本搜索非常相似,并且根据您使用的日期格式,它们的部分字符串(月份和日期)可能会在某些语言版本中造成混淆Windows。当我在寻找日期为 day=11 或 12 的日期并找到了 month=11 或 12 的日期时,我注意到了这一点。这是典型的混淆,当您使用诸如“mm-dd-”之类的数据格式时有时会出现这种情况yyyy”(美国)和“dd/mm/yyyy”(其他),对我来说看起来像一个 Windows 错误。 Windows should distinguish the two formats clearly, but sometimes it doesn't. Windows 应该可以清楚地区分这两种格式,但有时却没有。 There was a similar problem at VBA Range.Find method not finding a value that IS in the range that helped me find the solution.VBA Range.Find 方法中也有类似的问题,找不到帮助我找到解决方案的范围内的值 I needed to format the search object temporarily as numbers我需要暂时将搜索 object 格式化为数字

daily.Range("A:A").NumberFormat = "0"

and also search for the long integer value of the running date, thus the starting value is并搜索运行日期的 long integer 值,因此起始值为

d = CLng(date1)

where d is type number and date1 is type date.其中 d 是类型编号,date1 是类型日期。 The search term is then simply搜索词就是

Set c = daily.Range("A:A").Find(d) 
If Not c Is Nothing Then ...

At the end I reformat the date column with最后我重新格式化日期列

daily.Range("A:A").NumberFormat = "dd/mm/yyyy;@"

This resolved the problem.这解决了问题。 Thank you all for your kind help.谢谢大家的帮助。 @Ron Rosenfeld's hint came closest as he proposed to search for What:=CDbl(date) , which is what I am basically doing, except that I prefer CLng over CDbl as I need the date as an integer and not as a floating point number. @Ron Rosenfeld 的提示最接近,因为他建议搜索What:=CDbl(date) ,这是我基本上在做的,除了我更喜欢 CLng 而不是 CDbl 因为我需要日期作为 integer 而不是浮点数. The only problem with that idea was that you cannot search for.value2.该想法的唯一问题是您无法搜索 .value2。 You can only search for xlValues (which is not the same) or xlFormulas.您只能搜索 xlValues(不同)或 xlFormulas。 Neither would find this long integer number in the cell's properties.也不会在单元格的属性中找到这个长长的 integer 数字。
Transforming both the search object and the search item to numbers resolves the ambiguity completely.将搜索 object 和搜索项都转换为数字可以完全解决歧义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM