VBA 2010 - CDate 类型不匹配问题

Posted

技术标签:

【中文标题】VBA 2010 - CDate 类型不匹配问题【英文标题】:VBA 2010 - CDate Type Mismatch Issue 【发布时间】:2016-11-29 18:13:10 【问题描述】:

我有以下代码在某些笔记本电脑上运行没有问题,然后在其他笔记本电脑上运行时会出现类型不匹配的错误。在 AA 列中是格式为 (mm/dd/yyyy) 的日期,而在 AB 列中具有格式为 (hh:mm:ss) 的相应时间。 我从 Now() 中减去日期和时间。我无法真正解决问题,因为它在我的笔记本电脑上运行良好。对于其他人,它会出错。 CLng(CDate(Now())) 有一个值,但其他两个会导致类型不匹配。我已经尝试了下面的两行以及连接日期和时间的另一行,然后执行 CLng(CDate(.

'If CLng(CDate(Now())) - CLng(CDate(Range("AA" & i).Value)) + CLng(CDate(Range("AB" & i).Value)) >= 7 Then
 If CLng(CDate(Now())) - CLng(CDate(FMT(Range("AA" & i), "mm/dd/yyyy"))) + CLng(CDate(FMT(Range("AB" & i), "hh:mm:ss"))) >= 7 Then

其中 FMT 是一个公共函数:

Public Function FMT$(ByVal Value, ByVal strFormat)
FMT = VBA.Format$(Value, strFormat)
End Function

我要求我的同事将他所在地区日期/时间设置的屏幕截图发送给我。我想可能是这种情况。我已经阅读了与此类似的其他问题,但无法弄清楚。提前致谢。

【问题讨论】:

Date 的时间部分是分数。在只包含时间的Date 上使用CLng 将从中午开始四舍五入。你到底想计算什么? AA 列中的日期格式为 (mm/dd/yyyy),AB 列中的时间格式为 (hh:mm:ss)。我想从 Now() 中减去日期和时间。感谢您提供有关 CLng 的信息。最初,我将日期和时间连接起来,然后使用 CLng,这对我来说非常有用。但对其他人来说,它不起作用,所以我认为我的连接方式可能有问题,所以我拆分了日期和时间。但事实并非如此。 AA 和 AB 列中是否有日期和时间,或者这些列中是否有看起来像日期和时间的字符串? (如果您将单元格格式暂时切换为General 并且单元格显示数字,则内容为日期/时间,但如果它们继续显示类似于日期和时间的内容,则内容只是字符串。)跨度> 我对它进行了格式检查,它是文本格式。 【参考方案1】:

如果 AA 和 AB 列包含文本而不是日期和时间,请尝试使用以下语句:

If Now() - (DateValue(Range("AA" & i)) + TimeValue(Range("AB" & i))) >= 7 Then

如果用户有一个本地日期设置,例如dd/mm/yyyy,但您的列正在存储一个表示其他区域设置日期设置中的日期的字符串,这可能仍然会出现问题。如果是这种情况,您可能需要解析字段并执行以下操作:

Dim myDateStr As String
Dim myTimeStr As String
Dim myDateTime As Date
myDateStr = Range("AA" & i)
myTimeStr = Range("AB" & i)
myDateTime = DateSerial(CInt(Mid(myDateStr, 7, 4)), CInt(Mid(myDateStr, 1, 2)), CInt(Mid(myDateStr, 4, 2))) + _
             TimeSerial(CInt(Mid(myTimeStr, 1, 2)), CInt(Mid(myTimeStr, 4, 2)), CInt(Mid(myTimeStr, 7, 2)))

If Now() - myDateTime >= 7 Then

【讨论】:

这对我有用!我将确保它真正快速地适用于其他人,但我认为这可能会奏效。我会尽快跟进。 我明白了.. 我希望有一个解决方案可以避免必须根据每个人的设置自定义代码.. 为每个人更新此代码需要做很多工作有修订的时间。是否可以将格式从文本更改为可用格式以绕过此问题? @jmeddy - 如果 AA 和 AB 中的值存储在用户的日期/时间设置中,那么我提供的第一种方法将起作用。如果 AA 和 AB 中的值存储在固定的 mm/dd/yyyy 和 hh:mm:ss 设置中,那么我提供的备用代码将起作用,而与用户的设置无关。 使用您提供的备用代码,它就像一个魅力。非常感谢!【参考方案2】:

您可以使用Range 对象的Value2 属性来获取DateTime 的数字表示。试试:

If CDbl(Now()) - (Range("AA" & i).Value2 + Range("AB" & i).Value2) >= 7 Then

请务必将Now() 转换为Double,否则它将仅使用DateTime 的日期部分。

我发现使用 DateTime 的数字表示更容易,因为它允许您绕过区域设置。

【讨论】:

感谢您的回复。我试了一下,发现同一部分的类型不匹配:(Range("AA" & i).Value2 + Range("AB" & i).Value2).. 当我将鼠标悬停在Range("AA" & i).Value2 上时,我得到 MM/DD/YYYY,而对于Range("AB" & i).Value2,我得到 hh:mm:ss。 CDbl(Now()) 给出了 42703.48.. 的数字表示。似乎我仍然需要找到一种方法来转换为数字表示而不使用区域设置? 我不是 100% 确定,但我认为如果我在 AA/AB 列中的日期/时间格式不是文本的话,你的答案会奏效..?

以上是关于VBA 2010 - CDate 类型不匹配问题的主要内容,如果未能解决你的问题,请参考以下文章

启动应用程序时 VBA 类型不匹配

vba 拆分功能的类型错误和不匹配

VBA:私有子中的编译错误 ByRef 参数类型不匹配

ByRef 参数类型不匹配 - Excel VBA

excel:使用查找的vba类型不匹配

切换到 64 位 Excel 后如何修复 VBA“类型不匹配”错误