【问题标题】:How to solve mixed date formats如何解决混合日期格式
【发布时间】:2014-01-29 06:00:54
【问题描述】:

我正在尝试在 Excel 2010 中编写 VBA 代码来进行一些时间计算。一切都按我想要的方式工作,但对于单元格日期格式。 Excel 表格是通过合并由不同 PC 和硬件数据记录器生成的多个 .xlsx 文件创建的。问题是有些工作表的日期为mm/dd/yy hh:mm:ss AM/PM,而另一些工作表的日期为dd/mm/yy hh:mm:ss AM/PM,两者混合在一个文件中。

我尝试将所有内容更改为Selection.NumberFormat = "dd/mm/yy hh:mm;@",但有些单元格并没有改变。我也试过这个功能:

Function Arreglar_Fecha()
    Dim temp As String
    temp = ""
    Do While ActiveCell.Value <> ""
       temp = ActiveCell.Value
       ActiveCell.Value = Day(temp) & "/" & Month(temp) & "/" & Year(temp) & " " & Hour(temp) & ":" & Minute(temp)
       ActiveCell.Offset(1, 0).Select
    Loop
End Function

但是,有些单元格发生了变化,有些则没有。更糟糕的是,有些日期和月份混在一起!

我可以访问一些原始 .xlsx 文件,但其中的所有日期格式也无法更改。

有人知道我该如何解决这个问题吗?

编辑在这里我获得了放置原始Excel文件Excel Data的权限。

【问题讨论】:

    标签: vba date excel


    【解决方案1】:

    您必须追溯您的源数据。例如,Excel 本身无法知道 2014 年 1 月 2 日应该是 2 月 1 日还是 1 月 2 日,只能知道它是 41671 还是 41641。

    编辑在您的第二个示例中,显然 28/9/2013 17:59 是 9 月 28 日。如果 10/01/13 12:11:00 PM 具有相同的格式(可能来自同一个文件),那么它是 1 月 10 日。但如果格式是不同的,那么它可能是 10 月 1 日。如果您看到格式为 dd/mm/yy hh:mm;@ 的 AM 和 PM,那么您的一些数据是文本,并且没有可靠的“自动”方法可以在不知道的情况下将其切换为日期/时间序列号文本约定(即无论是 DMY 还是 MDY),因此需要恢复为源。

    显然,大于 12 的“日”值实际上是月份,但对于小于 13 的情况,这并没有多大帮助,这取决于格式。

    此外,鉴于您的各种来源,可能会同时使用 1900 和 1904 约定,甚至可能还使用其他约定(您的数据记录器可能使用 UNIX 时间,从 1970 年开始)。

    【讨论】:

    • + 1 从技术上讲你是对的。 Excel不能知道。但是如果用户强行想要通过拆分转换为特定格式,那么这是可能的:)
    • +1 @pnuts 你说得有道理。当我读到这个问题时,这也是我的直觉反应。 “如果他们只看到日期并且前两项都小于 13,那么 OP 真的知道哪个日期应该是 DD-MM-YYYY 和 MM-DD-YYYY。如果 OP 回来,我不会感到惊讶编辑。但对 Sid 也 +1,因为他的方法。
    • @pnuts,事情是,一旦数据在 Excel 中,Excel 将完成其解释它的工作,并决定 DMY 或 MDY。如果日期是 DMY 或 MYD,则使用向导和 TELL Excel 导入数据会更容易。
    • @SiddharthRout,在你把那句话传回给我之后,我怎么能不爱你呢?而且,当然,我完全同意用户不一定要在 Excel 中输入数据来促进易于处理。我所以希望用户都学会如何操作他们每天使用的工具,让他们的生活更轻松。每天花五分钟学习一些基础知识,消除在故障排除上浪费的 小时 时间。 - 我认为这个对话应该转移到 Meta。
    • @pnuts,我几年前在另一个论坛上问过这个问题:excelforum.com/the-water-cooler/…——参与讨论的大多数人现在都是 MS MVP,但当时还不是。
    【解决方案2】:

    ActiveCell.Value = Day(temp) & "/" & Month(temp) & "/" & Year(temp) & " " & Hour(temp) & ":" & Minute(temp)

    也许代码将其作为文本读取?试试这个(未测试)

    Sub Arreglar_Fecha()
        Dim temp As String, Tmp As String
        Dim D As String, M As String, Y As String
        Dim H As String, Mn As String
    
        Do While ActiveCell.Value <> ""
           temp = Trim(ActiveCell.Value)
    
           D = Trim(Split(temp, "/")(0))
           M = Trim(Split(temp, "/")(1))
    
           Tmp = Trim(Split(temp, "/")(2))
    
           Y = Trim(Split(Tmp, " ")(0))
    
           Tmp = Trim(Split(Tmp, " ")(1))
    
           H = Trim(Split(Tmp, ":")(0))
           Mn = Trim(Split(Tmp, ":")(1))
    
           ActiveCell.Value = Format(DateSerial(Val(Y), Val(M), Val(D)) & _
                              " " & TimeSerial(Val(H), Val(Mn), 0), _
                              "dd/mm/yy hh:mm;@")
    
           ActiveCell.Offset(1, 0).Select
        Loop
    End Sub
    

    使用单个测试场景进行尝试是可行的。下面给你13/08/13 05:31

    Sub Test()
        Dim temp As String, Tmp As String
        Dim D As String, M As String, Y As String
        Dim H As String, Mn As String
    
        temp = "13/8/2013 5:31"
    
        D = Trim(Split(temp, "/")(0))
        M = Trim(Split(temp, "/")(1))
    
        Tmp = Trim(Split(temp, "/")(2))
    
        Y = Trim(Split(Tmp, " ")(0))
    
        Tmp = Trim(Split(Tmp, " ")(1))
    
        H = Trim(Split(Tmp, ":")(0))
        Mn = Trim(Split(Tmp, ":")(1))
    
        Debug.Print Format(DateSerial(Val(Y), Val(M), Val(D)) & _
                    " " & TimeSerial(Val(H), Val(Mn), 0), _
                    "dd/mm/yy hh:mm;@")
    End Sub
    

    【讨论】:

    • 首先感谢@Siddharth。我编辑了我的问题,将您的代码添加到我在原始文件link 中使用的循环中(我已获得公开许可)。几乎可以工作,但有两个问题,当(出于某种原因)一个单元格具有正确的格式时,宏会给出“9”错误。没什么大不了的,甚至可以手动修复购买手动更改活动单元;但另一个是 AM/PM 时间错误地更改为 24Hs,例如,如果时间是 5:01 PM,则转换为 5:01 小时,应该是 17:01。
    • 您在文件中的示例数据略有不同。我们也必须迎合上午/下午。
    • 好的,我找到了解决方案,我在 H = Trim(Split(Tmp, ":")(0)) 之后添加了此代码,因此将 12 添加到包含的小时值:If InStrRev(ActiveCell, "p.m") &lt;&gt; 0 Then H = H + 12。现在我只需要捕获异常(我不知道这在 VBA 中是否可行)或者只是手动跳过它,我将能够正确合并数据!
    • 你指的是第一个没有 AM/PM 的单元格吗?
    • 在使用 Split 之前只需使用 INSTR() 检查分隔符,然后相应地修改代码,一切都会好起来的 :)
    猜你喜欢
    • 2020-07-22
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 2017-12-15
    相关资源
    最近更新 更多