[英]Changing the date format to yyyy-mm-dd
我有一个日期列,其中包含混合格式的日期。 例如:
一种
1990年3月21日
1990年3月21日
因此,在一列中基本上有两种不同的格式: dd.mm.yyyy
和mm/dd/yyyy
。 我正在尝试编写VBA脚本,以将列中所有日期的格式更改为yyyy-mm-dd
。 到目前为止,这就是我得到的:
Sub changeFormat()
Dim rLastCell As Range
Dim cell As Range, i As Long
Dim LValue As String
i = 1
With ActiveWorkbook.Worksheets("Sheet1")
Set rLastCell = .Range("A65536").End(xlUp)
On Error Resume Next
For Each cell In .Range("A1:A" & rLastCell.Row)
LValue = Format(cell.Value, "yyyy-mm-dd")
.Range("B" & i).Value = LValue
i = i + 1
Next cell
On Error GoTo 0
End With
End Sub
我知道这不是一段优雅的代码,但是我是VBA的初学者,所以请原谅我。 该代码的问题在于,当我将Format函数中的参数从yyyy-mm-dd
更改为dd/mm/yyyy
时,它只是将未更改的A列重写为B列,但它仅适用于mm/dd/yyyy
格式的日期,并且保持dd.mm.yyyy
不变。 我将不胜感激任何建议。
更新:新答案
这是可以解决问题的解决方案! 该子例程包含一个进行替换的函数(该函数本身确实非常有用!)。 运行该子程序,A列中的所有事件都将得到修复。
Sub FixDates()
Dim cell As range
Dim lastRow As Long
lastRow = range("A" & Rows.count).End(xlUp).Row
For Each cell In range("A1:A" & lastRow)
If InStr(cell.Value, ".") <> 0 Then
cell.Value = RegexReplace(cell.Value, _
"(\d{2})\.(\d{2})\.(\d{4})", "$3-$2-$1")
End If
If InStr(cell.Value, "/") <> 0 Then
cell.Value = RegexReplace(cell.Value, _
"(\d{2})/(\d{2})/(\d{4})", "$3-$1-$2")
End If
cell.NumberFormat = "yyyy-mm-d;@"
Next
End Sub
将此功能放在同一模块中:
Function RegexReplace(ByVal text As String, _
ByVal replace_what As String, _
ByVal replace_with As String) As String
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
RE.pattern = replace_what
RE.Global = True
RegexReplace = RE.Replace(text, replace_with)
End Function
工作原理 :我有一个漂亮的RegexReplace函数,可让您使用正则表达式进行替换。 该sub循环遍历您的A列,并为您提到的这两种情况进行正则表达式替换。 我首先使用Instr()的原因是确定是否需要替换以及哪种替换。 从技术上讲,您可以跳过此步骤,但是在不需要它的单元格上进行替换确实非常昂贵。 最后,我将单元格格式化为自定义日期格式,而不管其中的内容如何安全。
如果您不熟悉Regex(供参考: http : //www.regular-expressions.info/ ),我使用的表达式是:
您实际上并不需要VBA。 这个单线工作表公式可以解决这个问题:
=IF(ISERROR(FIND(".",A1)),IF(ISERROR(FIND("/",A1)),"invalid format",
DATE(RIGHT(A1,4),LEFT(A1,2),MID(A1,4,2))),
DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2)))
假设日期和月份始终以两位数字给出(例如,始终为03,而永远不只是3),而年份则为四位数字(即,“限制”到1000-9999年)。 但是,如果您不是这种情况,则可以轻松调整公式以适合您的目的。
看看这是否满足您的要求。 您可能需要为自己的应用程序量身定制。
希望这可以帮助!
Sub convertDates()
Dim rRng As Range
Dim rCell As Range
Dim sDest As String
Dim sYear, sMonth, sDay, aDate
'Range where the dates are stored, excluding header
Set rRng = Sheet1.Range("A2:A11")
'Column name of destination
sDest = "B"
'You could also use the following, and just select the range.
'Set rRng = Application.selection
For Each rCell In rRng.Cells
sYear = 99999
If InStr(rCell.Value, ".") > 0 Then
aDate = Split(rCell.Value, ".")
If UBound(aDate) = 2 Then
sDay = aDate(0)
sMonth = aDate(1)
sYear = aDate(2)
End If
ElseIf InStr(rCell.Value, "/") > 0 Then
aDate = Split(rCell.Value, "/")
If UBound(aDate) = 2 Then
sDay = aDate(1)
sMonth = aDate(0)
sYear = aDate(2)
End If
End If
With rCell.Range(sDest & "1")
If sYear <> 99999 Then
On Error Resume Next
.Value = "'" & Format(CDate(sMonth & "/" & sDay & "/" & sYear), "YYYY-MM-DD")
'If it can't convert the date, just put the original value in the dest
'cell. You can tailor this to your own preference.
If Err.Number <> 0 Then .Value = rCell.Value
On Error GoTo 0
Else
.Value = rCell.Value
End If
End With
Next
End Sub
@Jean-FrançoisCorbett提供了一个有效的公式解决方案,但通过附加错误消息(以#VALUE!
为参考依据)和另一个IF(均为DATE),可以使用IFERROR而不是ISERROR将其缩短一半以上。并用“替换”代替一组“左”,“中”,“右”:
=IFERROR(1*(MID(A1,4,3)&LEFT(A1,3)&RIGHT(A1,4)),1*SUBSTITUTE(A1,".","/"))
这会将@Issun在注释中提及的解释应用于OP,并假定输出将为格式为yyyy-mm-dd
单元格。
可以使用如下子例程编写:
Sub Macro1()
Range("B1:B10").Formula = "=IFERROR(1*(MID(A1,4,3)&LEFT(A1,3)&RIGHT(A1,4)),1*SUBSTITUTE(A1,""."",""/""))"
End Sub
这是一个简单的解决方案:
Sub ChangeFormat1()
Dim ws as Worksheet
Set ws = Thisworkbook.Sheets("Sheet1")
LR = ws.cells(rows.count,1).End(Xlup).Row
with ws
For I = 1 to LR
.cells(I,2).value = .cells(I,1).value
Next
End with
ws.range("B1:B" & LR).numberformat = "yyyy-mm-dd"
End Sub
月(日期)和“-”和日(日期)和“-”和年(日期)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.