我将.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 - 类型不匹配。 我认为我的代码是通过混合值和文本导致错误,但我看不到在哪里。
答案 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
(如果您花时间以上面显示的方式缩进连续行,您的代码将更具可读性。如果您遵循此格式,您可以更快速,更轻松地选择目标变量和作业。)