Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 将日期格式更改为yyyy-mm-dd_Excel_Vba_Date_Format - Fatal编程技术网

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

Excel 将日期格式更改为yyyy-mm-dd,excel,vba,date,format,Excel,Vba,Date,Format,我有一个日期列,其中包含混合格式的日期。例如: A 21.03.1990 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 Ac

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

A
21.03.1990
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.yyyyy
不变。如有任何建议,我将不胜感激。

更新:新答案

这里有一个解决方案,将做的工作!子程序包括一个进行替换的函数(函数本身非常有用!)。运行sub,将修复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 
它的工作原理:我有一个漂亮的RegexReplace函数,允许您使用正则表达式进行替换。子mearly在A列中循环,并对您提到的两种情况进行正则表达式替换。我首先使用Instr()的原因是为了确定它是否需要替换,以及需要替换的类型。从技术上讲,您可以跳过这一步,但在不需要的单元上进行替换确实非常昂贵。最后,为了安全起见,我将单元格格式化为自定义日期格式,而不管里面是什么

如果您不熟悉正则表达式(对于ref:),我使用的表达式是:

  • ()中的每一项都是捕获组,也就是你想要处理的东西
  • \d代表一个数字[0-9]
  • {2} 表示的是2,而{4}表示的是4。我在这里是为了安全
  • 前的\。因为“.”有特殊的含义,所以在第一次替换时需要
  • 在VBA正则表达式中,使用$+组数引用捕获组。这就是我如何翻转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
      
      Sub-convertDates()
      暗rRng As范围
      变暗rCell As范围
      以字符串形式显示
      朦胧的西耶尔,斯蒙顿,星期四,阿达特
      '存储日期的范围,不包括标题
      设置rRng=Sheet1.范围(“A2:A11”)
      '目标的列名
      sDest=“B”
      '您也可以使用以下选项,只需选择范围即可。
      '设置rRng=Application.selection
      对于rRng.单元格中的每个rCell
      sYear=99999
      如果仪表(rCell.Value,“.”大于0,则
      aDate=拆分(rCell.Value,“.”)
      如果UBound(aDate)=2,则
      sDay=aDate(0)
      sMonth=aDate(1)
      sYear=aDate(2)
      如果结束
      ElseIf InStr(rCell.Value,“/”)则大于0
      aDate=拆分(rCell.Value,“/”)
      如果UBound(aDate)=2,则
      sDay=aDate(1)
      sMonth=aDate(0)
      sYear=aDate(2)
      如果结束
      如果结束
      带rCell.范围(sDest和“1”)
      如果sYear 99999那么
      出错时继续下一步
      .Value=“””和格式(CDate(星期一和星期四和星期四),“YYYY-MM-DD”)
      '如果无法转换日期,只需将原始值放入dest
      “牢房。你可以根据自己的喜好来定制。
      如果错误号为0,则.Value=rCell.Value
      错误转到0
      其他的
      .Value=rCell.Value
      如果结束
      以
      下一个
      端接头
      
      这并不需要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年)。但如果你不是这样,那么这个公式可以很容易地调整以适应你的目的

      月(日)和“-”日(日)和“-”年(日)

      @Jean-François Corbett有一个公式解决方案,它可以工作,但通过前面的错误消息(基于
      #VALUE!
      具有信息性)可以缩短一半以上,如果两个日期都应用IFERRO而不是ISERRO,并替换左、中、右各一套:

      =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
      

      据我所知,“21.03.1990”不是日期格式,它只是以这种方式输入的文本。你能检查一下单元格格式并确认吗?如果是文本,那么更改日期的格式对内容没有任何影响。当然,VBA可能会带来更多的麻烦。这项任务可以用一个相当简单的Excel公式来完成。如果ISTEXT(单元格)和INSTR(1,cell.text,“.”),那么cell.value=DATESERIAL(右(cell.text,4),MID(cell.text,4,2),左(cell.text,2))。这应该转换成真正的Excel数据格式,之后你可以应用你的单元格格式。+1非常好!我倾向于用VBA编写代码(主要是因为我有错误输入长公式的坏习惯),但这是最有效的方法。
           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