"运行时错误13 - 类型不匹配"从文本单元格解析日期时

时间:2017-07-03 19:45:39

标签: excel vba excel-vba

我将.csv文件从其他程序导入Excel。日期格式为文本,格式如下: mm / dd / yy或 17年7月3日 导入的文件非常非结构化,第一个字段中的日期不仅仅是日期。

我想将2017-07-03写入单元格(2,13)

以下是我使用

的代码
ActiveSheet.Cells(2, 13).Select
ActiveCell.FormulaR1C1 = "=IF(LEN(RC[-12]))=8, _  'How I identify date 
20&MID((RC[-12]),7,2)&" - "&                      'To get 2017 4 digit Year
MID((RC[-12]),1,2)&" - "&                         'To extract 2 digit month
MID((RC[-12]),4,2)),"""")"                        'To extract 2 digit day

这给了我运行时错误13 - 类型不匹配。 我认为我的代码是通过混合值和文本导致错误,但我看不到在哪里。

2 个答案:

答案 0 :(得分:0)

错误消息的原因是由于公式未正确创建。

应该看起来像:

Cells(2, 13).FormulaR1C1 = "=IF(LEN(RC[-12])=8, 20 & MID(RC[-12],7,2) & ""-"" & MID(RC[-12],1,2) & ""-"" & MID(RC[-12],4,2),"""")"

我建议在VBA中进行转换,然后将结果写入工作表,而不是将公式写入工作表。这可以使您的代码在将来更容易理解,调试和维护。

以下代码可以缩短,但故意不是为了提供更清晰的说明。它被编写为一个宏,它将处理A列中的所有内容,并以您指定的格式将日期写入M列。

我注意到在您的问题中,您指定的格式为2017-07-03,但在您的代码中,您生成的格式为2017 - 07 - 03。我在代码中生成了前者,但如果这是你真正想要的那样,应该明白如何改变后者。

另请注意,在代码中,我使用Excel的默认转换为2位数年份,假设两位数年份在1930 - 2029范围内。如有必要,可以改变。

代码使用更复杂的方法来确保转换的值确实是一个日期。但它不会检查“非法”日期,并会将2/31/17转换为2017-03-03。您的公式方法将返回字符串2017-02-31如果可能是一个问题,在VBA宏中添加代码来标记此类问题将是微不足道的。

还有其他方法可以检查有效日期,包括查看CDate或VBA的DateValue函数是否返回日期或错误。但是这些可能无法在不同语言环境中的工作簿中正常工作,在Windows区域设置中使用不同的默认短日期格式。

而不是将结果写为文本,结果可以写成一个真实日期,格式化为您希望的单元格的.numberformat属性(可以在将来的计算中使用),并且该选项在宏中的评论。

如果您要求结果是动态的,使用公式,宏可以很容易地转换为用户定义函数,但您必须确保单元格格式为“文本”,否则Excel将尝试转换结果将日期转换为“真实日期”(取决于您真正想要的两种格式中的哪一种)。

回复有关代码的任何问题。

Option Explicit
Sub ConvertOnlyDates()
    Dim V As Variant
    Dim YR As Long, MN As Long, DY As Long
    Dim DT As Date

    Dim WS As Worksheet
    Dim rSrc As Range, C As Range

'Define the range to check:  Columns A
'Always best to explicitly define worksheets and cells
'  and not rely on ActiveSheet, Activate, Select, etc
Set WS = Worksheets("sheet2")
With WS
    Set rSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp))
End With

For Each C In rSrc

    'check if a date
    V = Split(C.Text, "/")
        If UBound(V) = 2 Then
            If V(0) > 0 And V(0) <= 12 _
                And V(1) > 0 And V(1) <= 31 _
                And V(2) >= 0 And V(2) <= 99 Then

                    MN = V(0)
                    DY = V(1)

                    'note that this is Excel's default (at least for now)
                    YR = V(2) + IIf(V(2) < 30, 2000, 1900)

                    DT = DateSerial(YR, MN, DY)

                    'Can be written as text
                    '  or as a real date with proper formatting

                    '  REAL DATE
                    'With C.Offset(0, 12) 'write in column M
                    '    .NumberFormat = "yyyy-mm-dd"
                    '    .Value = DT
                    'End With

                    With C.Offset(0, 12)
                        .NumberFormat = "@"
                        .Value = Format(DT, "yyyy-mm-dd")
                    End With
                End If
            End If
Next C

End Sub

答案 1 :(得分:-1)

您没有为每一行用双引号正确关闭字符串。使用延续字符_不允许您在中间断开字符串。如果你正确连接,你可以这样做:

ActiveCell.FormulaR1C1 = "=IF(LEN(RC[-12]))=8," & _       'How I identify date 
                         "20&MID((RC[-12]),7,2)&" - " & _ 'To get 2017 4 digit Year
                         "MID((RC[-12]),1,2)&" - " & _    'To extract 2 digit month
                         "MID((RC[-12]),4,2)),"""")"      'To extract 2 digit day

(如果您花时间以上面显示的方式缩进连续行,您的代码将更具可读性。如果您遵循此格式,您可以更快速,更轻松地选择目标变量和作业。)