将date格式更改为yyyy-mm-dd

我有一个包含混合格式date的date列。 例如:

一个
1990年3月21日
1990年3月21日

所以,基本上在一列中有两种不同的格式: dd.mm.yyyymm/dd/yyyy 。 我正在尝试编写一个VBA脚本,将列中所有date的格式更改为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的初学者,所以请原谅我。 该代码的问题是,它只是重写不变A列到列B,当我在格式function从yyyy-mm-dd更改参数为dd/mm/yyyy它的作品,但只适用于date格式mm/dd/yyyy ,并保持dd.mm.yyyy不变。 我将不胜感激任何意见。

更新:新的答案

这是一个解决scheme,将完成这项工作! 子例程包含一个replace函数(函数本身非常有用!)。 运行小组,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放在同一个模块里:

 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函数,允许你使用正则expression式来replace。 子通过你的A列循环,并为你提到的2个案例做一个正则expression式replace。 我首先使用Instr()的原因是为了确定是否需要replace,以及哪种types。 你可以在技术上跳过这个,但是replace不需要的单元是非常昂贵的。 最后,我将单元格格式化为您的自定义date格式,而不pipe内部为了安全措施。

如果你不熟悉正则expression式(参考: http : //www.regular-expressions.info/ ),我使用的expression式是:

  • ()中的每个项目都是捕获组,也就是你想要的东西
  • \ d代表一个数字[0-9]。
  • {2}表示2,{4}表示4。 为了安全起见,我已经明确表示了。
  • 之前的。 在第一个replace是需要自“。” 有特殊的意义。
  • 在VBA正则expression式中,通过使用$ + no引用捕获组。 组。 这是我如何翻转3项的顺序。

看看这是否你想要的。 您可能需要为自己的应用程序量身定做。

希望这可以帮助!

 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 

你真的不需要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))) 

假定date和月份总是以两位数字的forms给出(例如总是03而不是只有3),年份有四位数字(即“限制”到1000-9999)。 但如果不是这样的话,那么可以很容易地调整公式以适应你的目的。

月份(date)及“ – ”及date(date)及“ – ”及年份(date)

@ Jean-FrançoisCorbett有一个公式解决scheme,但是可以通过前面的错误消息(基于#VALUE!是信息性的)和另一个IF(两个DATE)应用IFERROR而不是ISERROR来缩短一半以上,和SUBSTITUTE代替一个左,中,右设置:

 =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 

这是一个简单的解决scheme:

  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