【问题标题】:Manipulate date with Excel macro screws locale format使用 Excel 宏螺丝区域设置格式操作日期
【发布时间】:2020-07-03 11:22:41
【问题描述】:

我有一个大的 xls 文件导出,其中的日期列如下所示:

10-Ott-2019
11-Ott-2019
11-Ott-2019
11-Ott-2019
12-Ott-2019
14-Ott-2019

我需要使用宏将所有月份更改为它们的数字:即“Ott”(十月)到它的数字 (10)

Columns("AC:AC").Select
    Selection.Replace What:="Ott", Replacement:="10", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, FormulaVersion:= _
        xlReplaceFormula2

我希望收到这个

10-10-2019
11-10-2019
11-10-2019
11-10-2019
12-10-2019
14-10-2019

...    

但不幸的是,excel 使用某种单元格自动格式将数据拧紧并返回

 10-10-2019
 10-11-2019
 10-11-2019
 10-11-2019
 10-12-2019
 14-10-2019

基本上如果日期小于或等于 12 excel 无论如何都将其视为月份数,它也会忽略系统区域设置的日期为意大利语。

作为旁注,我不需要将其格式化为日期,它可以是一个字符串,我会很好,但我不希望 excel 更改日期。

有什么想法吗?

我也试过这个宏:

Columns("AC:AC").Select
    Selection.NumberFormat = "dd-mm-yyyy"
    Selection.Replace What:="Ott", Replacement:="10", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, FormulaVersion:= _
        xlReplaceFormula2

但结果是一样的……

【问题讨论】:

  • 你试过ReplaceFormat:=True吗?
  • 是的,它不能解决问题
  • 在这里你可以下载我正在尝试修复的 xlsx,除了出现问题的列 AC 之外,它都是空白的(此文件中不包含宏):dropbox.com/s/cpfiaazyi4ud932/date_tofix.xlsx?dl=0

标签: excel vba date


【解决方案1】:

试试,

Excel会根据每个数据的格式自动将数据格式应用到单元格中。因此,只有正确输入数据值,才能得到正确的结果。

 Sub testSeveralMonth()
    Dim myDay() As String
    Dim vDB, vSplit
    Dim i As Long, r As Long, j As Integer
    Dim a, b
    Dim s As String
    
    a = Array("Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic")
    b = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
    
    vDB = Range("ac1", Range("ac" & Rows.Count).End(xlUp))
    
    r = UBound(vDB, 1)
    ReDim myDay(1 To r, 1 To 1)
    For i = 1 To r
        s = vDB(i, 1)
        For j = 0 To UBound(a)
            s = Replace(s, a(j), b(j))
        Next j
        If IsDate(s) Then
            vSplit = Split(s, "-")
            vDB(i, 1) = DateSerial(vSplit(2), vSplit(1), vSplit(0))
        End If
    Next i
   Range("ac:ac").NumberFormatLocal = "dd-mm-yyyy"
   Range("ac1").Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
   
End Sub

例如一个月

Sub test()
    Dim myDay() As String
    Dim vDB, vSplit
    Dim i As Long, r As Long
    
    vDB = Range("ac1", Range("ac" & Rows.Count).End(xlUp))
    
    r = UBound(vDB, 1)
    ReDim myDay(1 To r, 1 To 1)
    For i = 1 To r
        myDay(i, 1) = Replace(vDB(i, 1), "Ott", 10)
        If IsDate(myDay(i, 1)) Then
            vSplit = Split(myDay(i, 1), "-")
            vDB(i, 1) = DateSerial(vSplit(2), vSplit(1), vSplit(0))
        End If
    Next i
   Range("ac1").Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
   Range("ac:ac").NumberFormatLocal = "dd-mm-yyyy"
End Sub

结果图片

错误代码

Sub test2()
    Dim myDay() As String
    Dim vDB
    Dim i As Long, r As Long
    
    vDB = Range("ac1", Range("ac" & Rows.Count).End(xlUp))
    
    r = UBound(vDB, 1)
    ReDim myDay(1 To r, 1 To 1)
    For i = 1 To r
       vDB(i, 1) = Replace(vDB(i, 1), "Ott", 10)
    Next i
    Range("ac1").Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
    Range("ac:ac").NumberFormatLocal = "dd-mm-yyyy"
End Sub

错误图片

【讨论】:

  • 我认为你解决了这个问题,不幸的是你的代码在这一行给出了运行时错误 9“下标超出范围(错误 9)”:vDB(i, 1) = DateSerial(vSplit(2) , vSplit(1), vSplit(0))。另外我如何才能复制所有月份?
  • @DavideC,如果你想使用多个月,你可以创建一个循环来替换字母和数字几个月。
  • @DavideC,我编辑了几个月的答案。我认为错误的原因不仅仅是10月份的数据,而是几个月的数据,所以似乎因为无法处理而发生错误。
  • 非常感谢您的帮助,脚本现在可以运行,数据是安全的,但 excel 会打印 dd-01-yyyy、dd-02-yyyy 等
  • 这是我测试过的模板文件:dropbox.com/s/cpfiaazyi4ud932/date_tofix.xlsx?dl=0
【解决方案2】:

如果您的日期是真实日期而不是字符串,这可能会起作用。

Sub ReFormat()
    With Application.FindFormat
        .Clear
        .NumberFormat = "dd-mmm-yyyy"
    End With
    With Application.ReplaceFormat
        .Clear
        .NumberFormat = "dd-mm-yyyy"
    End With
    Columns("AC:AC").Replace What:="", Replacement:="", LookAt:=xlWhole, SearchOrder:= _
        xlByRows, MatchCase:=False, SearchFormat:=True, ReplaceFormat:=True
End Sub

【讨论】:

    【解决方案3】:

    您的最后一个宏产生错误。

    您可以尝试如下宏:

    Sub FindAndReplaceAll()
      dim ws as worksheet
      dim fnd as variant
      dim rplc as variant
    
      
      fnd = "Ott"
      rplc = "10"
    
      for each ws in ThisWorkbook.Worksheets
        ws.Cells.Replace What:=fnd , Replacement:=rplc , _
        LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase := False, _
        SearchFormat:=False, ReplaceFormat:= False
      next ws
    End sub
    

    现在,您当然需要每个月都这样做。这可以通过循环遍历列表来完成,或者只是将其全部更改 11 次。由于只需要更改 2 个变量,因此我建议使用后者,因为它很可能会更快。

    【讨论】:

    • 出现运行时错误“1004”。但是,上面发布的代码对我有用。
    • 这个有效,但不能解决问题,因为我仍然收到搞砸的日期,有些日子被切换到月份,反之亦然
    猜你喜欢
    • 2014-12-23
    • 2011-01-22
    • 1970-01-01
    • 2019-11-17
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多