Excel 如何对函数值而不是单元格值使用IsError?

Excel 如何对函数值而不是单元格值使用IsError?,excel,vba,Excel,Vba,我在工作表中有一列包含未格式化的日期值。有三种类型,总是以月份缩写开头: JAN/19 JAN02/19 JAN19 我正在编写一个宏来循环该列并将其格式化为日期JAN/19和JAN19都将设置为每月的第一天,而JAN02/19将设置为01/02/19 为了处理列标题和顶部可能出现的空白行的错误,我想取左边的三个字符,看看它们是否是月份缩写。我正在尝试使用以下代码: If IsError(DateValue("01 " & Left(Cells(1, 1), 3) & " 19

我在工作表中有一列包含未格式化的日期值。有三种类型,总是以月份缩写开头:

JAN/19
JAN02/19
JAN19
我正在编写一个宏来循环该列并将其格式化为日期
JAN/19
JAN19
都将设置为每月的第一天,而
JAN02/19
将设置为
01/02/19

为了处理列标题和顶部可能出现的空白行的错误,我想取左边的三个字符,看看它们是否是月份缩写。我正在尝试使用以下代码:

If IsError(DateValue("01 " & Left(Cells(1, 1), 3) & " 19")) = True Then

     MsgBox "Oops, " & Left(Cells(1, 1), 3) & " is not a valid month abbreviation"

End If
如果
Left(单元格(1,1,3)
是有效的月份缩写,则跳过消息框,如果不是,则给出此错误,而不是
MsgBox
消息

iError()不会捕获类型不匹配。您需要执行一个运行时错误处理程序来捕获发生后的类似错误

另一方面,对于这个用例,您可以使用IsNumeric()而不是IsError()。我建议这样做:

If Not (IsNumeric(Left(Cells(1, 1), 3))) Then    
    MsgBox "Oops, " & Left(Cells(1, 1), 3) & " is not a valid month abbreviation"   
End If
IsDate()
是一个相当方便的函数,应该可以按预期工作:

Sub TestMe()

    If IsDate("01 " & Left(Cells(1, 1), 3) & " 19") Then
        Debug.Print "It is a date!"
    Else
        Debug.Print "Oops, " & Left(Cells(1, 1), 3) & " is not a valid month abbreviation"
    End If

End Sub

错误
是一种数据类型

IsError
功能用于确定
变量
是否具有变量子类型
错误
,即给定值是否为
变量/错误

在Excel中,当您读取包含例如
#值的单元格时,您会得到一个
变量/错误
。以编程方式,您可以使用
CVErr
函数和Excel错误枚举值获取
变量/错误
,例如:

Debug.Print IsError(CVErr(xlErrNA)) ' #N/A cell error
这个表达式中的问题是:

…是指
iError
被赋予了
日期
,因此函数将始终返回
False
=True
是冗余的)

但是,
IsError
甚至不需要计算:首先需要计算它的参数,这就是类型不匹配错误的原因:

Left(Cells(1, 1), 3)
如果
单元格(1,1)
包含
变量/错误
值,则将其强制为
字符串
会引发您得到的类型不匹配错误,因为
错误
不能隐式(或显式)转换为任何其他数据类型

解决方案是将
单元格(1,1)
拉入其自身的本地
变量
变量:

Dim cellValue As Variant
cellValue = ActiveSheet.Cells(1, 1).Value 'note: made qualifier and member call explicit
然后您可以评估该值是否为
错误

If Not IsError(cellValue) Then
    If IsDate("01 " & Left(cellValue, 3) & " 19") Then
        ' we're looking at a valid date value that VBA can convert to a Date data type
    Else
        ' we're looking at a malformed date
    End If
Else
    ' cellValue is a Variant/Error that we can't use.
End If

Test=DateValue(“01”和左(单元格(1,1,3)和“19”)
然后:
如果iError(Test)那么
试一下。@Damian和Vityata一样的错误-看你是对的@Mathieuguindon,但它不会:如果
单元格(1,1)
是一个
变体/错误
,那么
左(单元格(1,1,3)
正在将其强制转换为
变量/字符串
,这就是抛出类型不匹配错误的地方-早在
IsDate
运行之前就开始了。@MathieuGuindon-是的,我只是在测试问题的输入:)我想我可能误解了问题。。。鉴于OP的输入,我无法重新设置类型不匹配,我只是假设类型不匹配是由某个
变量/错误
单元格引起的;如果输入单元格错误,我确实会收到错误。对此表示歉意。该单元格将永远不会出现
变体/错误
,只有使用前三个字符作为一个月的结果。所以我相信
IsDate()
应该可以工作。@sethW很公平。请注意,您永远不应该假设任何关于单元格值的变量子类型的信息。
If Not IsError(cellValue) Then
    If IsDate("01 " & Left(cellValue, 3) & " 19") Then
        ' we're looking at a valid date value that VBA can convert to a Date data type
    Else
        ' we're looking at a malformed date
    End If
Else
    ' cellValue is a Variant/Error that we can't use.
End If