繁体   English   中英

将日期格式更改为yyyy-mm-dd

[英]Changing the date format to yyyy-mm-dd

我有一个日期列,其中包含混合格式的日期。 例如:

一种
1990年3月21日
1990年3月21日

因此,在一列中基本上有两种不同的格式: dd.mm.yyyymm/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/ ),我使用的表达式是:

  • ()中的每个项目都是捕获组-也就是您要弄乱的东西
  • \\ d代表数字[0-9]。
  • {2}表示2的平均值,{4}表示4的平均值。 为了安全起见,我在这里已经明确表示。
  • 之前的\\。 在第一个替换中,因为“。” 具有特殊的意义。
  • 在VBA正则表达式中,您使用$ + no来引用捕获组。 组。 这就是我翻转3个项目的顺序的方式。

您实际上并不需要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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM