繁体   English   中英

将 Excel 文本转换为时间

[英]Convert Excel Text to Time

我必须将一些格式化文本转换为 excel 时间,但我自己找不到解决方案。

以下是输入文本的一些示例以及应如何转换:

 - 1 Hour 14 minutes    ==> 01:14:00
 - 1 minute.            ==> 00:01:00
 - 1 Hour 1 minute      ==> 01:01:00
 - 2 minutes            ==> 00:02:00
 - 3 minutes 12 seconds ==> 00:03:12
 - 29 seconds           ==> 00:00:29

请注意,有些时候分和秒都有,而有些时候只有分/秒之一,除了有些时候你会找到分钟(复数),而有些时候只有分钟(单数)。 最后,一些标点符号有时会出现在文本中。

数据在电子表格列中,我想在电子表格的不同列中提取 excel 格式化时间。

我在单元格公式中尝试了不同版本的TimeValue()DateValue()以及一些嵌套的 replace(),但它们都不适用于所有情况。

你能给我一个关于如何解决这个问题的想法或一些建议吗?

谢谢,

保罗

由于您没有包含 VBA 作为标签,这里有一些公式解决方案。

如果您有 Windows Excel 2013+ 和FILTERXML function,您可以使用以下内容:

=IFERROR(FILTERXML("<t><s>" & SUBSTITUTE(LOWER(A1)," ","</s><s>") & "</s></t>","//s[contains(.,'hour')]/preceding-sibling::*[1]")/24,0)+
IFERROR(FILTERXML("<t><s>" & SUBSTITUTE(LOWER(A1)," ","</s><s>") & "</s></t>","//s[contains(.,'min')]/preceding-sibling::*[1]")/1440,0)+
IFERROR(FILTERXML("<t><s>" & SUBSTITUTE(LOWER(A1)," ","</s><s>") & "</s></t>","//s[contains(.,'sec')]/preceding-sibling::*[1]")/86400,0)

如果您没有FILTERXML function:

  • 创建一个命名公式:
    • FormulasDefined NamesDefine NameNew Nameseq_99Refers to:=IF(ROW(INDEX($A:$A,1,1):INDEX($A:$A,255,1))=1,1,(ROW(INDEX($A:$A,1,1):INDEX($A:$A,255,1))-1)*99)

然后使用这个公式:

=IFERROR(INDEX(TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),seq_99,99)),-1+MATCH("hour*",TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),seq_99,99)),0))/24,0)+
IFERROR(INDEX(TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),seq_99,99)),-1+MATCH("min*",TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),seq_99,99)),0))/1440,0)+
IFERROR(INDEX(TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),seq_99,99)),-1+MATCH("sec*",TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),seq_99,99)),0))/86400,0)

算法:

  • 查找字符串hourminsec
  • 返回每个字符串之前的节点
  • 除以适当的因子以创建 excel 时间值

注意:自定义格式列 B 为hh:mm:yy

在此处输入图像描述

正如@ScottCraner 在评论中指出的那样,可以通过创建数组公式来缩短公式:

使用FILTERXML

=SUM(IFERROR(FILTERXML("<t><s>" & SUBSTITUTE(LOWER(A1)," ","</s><s>") & "</s></t>","//s[contains(.,"&{"'hour'","'min'","'sec'"}&")]/preceding-sibling::*[1]")/{24,1440,8640},0))

没有FILTERXML

=SUM(IFERROR(INDEX(TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),seq_99,99)),-1+MATCH({"hour*","min*","sec*"},TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),seq_99,99)),0))/{24,1440,8640},0))

在 Excel 的一些早期版本中,您可能需要通过按住ctrl + shift的同时按enter来“确认”这个数组公式 如果您正确执行此操作,Excel 将在公式周围放置大括号{...} ,如公式栏中所示

我玩了你的问题一天,看到其他人也做了同样的事情。 我很佩服 Ron Rosenfeld 提供的使用 FilterXML 的解决方案,我曾简单地认为它过于古怪而放弃了。 它不是。 但它并不整洁。 对于“整洁”,请看下面的 UDF。 从工作表中使用=TextToTime(A1)之类的内容调用它,并确保将您放入的单元格格式化为时间,可能类似于hh:mm:ss

Function TextToTime(Cell As Range) As Double

    Dim Fun(2) As String
    Dim Txt() As String
    Dim Tmp As Variant
    Dim i As Integer

    Txt = Split(Cell.Value)
        For i = 1 To UBound(Txt)
            If Not IsNumeric(Txt(i)) Then
                Tmp = 0
                Tmp = InStr("HMS", UCase(Left(Trim(Txt(i)), 1)))
                If Tmp Then
                    Fun(Tmp - 1) = Val(Txt(i - 1))
                End If
            End If
        Next i

    For i = LBound(Fun) To UBound(Fun)
        If Fun(i) = "" Then Fun(i) = 0
    Next i

    TextToTime = TimeValue(Join(Fun, ":"))
End Function

这款 function 用途广泛。 它可以翻译诸如“5 小时 10 分 15 秒”或“5 小时 10 分 15 秒”(带逗号)甚至“5 小时 10 分 15 秒”之类的字符串。 它需要数字周围的空格,但不会因多余的空格或拼写错误而犹豫。 它在“75 分 66 秒”时失败,但如果这是一个问题,可以处理。 VBA 的主要优势是几乎任何事情都可以使用几行额外的代码来处理。 工作表函数没有这种能力。

好吧,您可以接受并编辑它以满足您的需要:

在此处输入图像描述

这是公式:

=IF(IFERROR(FIND("da",A2,1),0)>0,LEFT(A2,FIND(" ",A2,1)-1)*24,0)+IFERROR(1*MID(A2,FIND(" ",A2,FIND(" ",A2,1)+1),FIND(" ",A2,FIND(" ",A2,FIND(" ",A2,1)+1)+1)-FIND(" ",A2,FIND(" ",A2,1)+1)),0*1)

我只是想把日期转换成小时,这样你就可以完成你想要的。

如果您决定使用 VBA 并且在 A 列中保持相同的格式,则可以使用以下代码:

代码:

Sub Converter()

    Dim i As Long, y As Long, LastRow As Long
    Dim arrData As Variant, arrLine As Variant
    Dim Hours As String, Minutes As String, Seconds As String

    With ThisWorkbook.Worksheets("Sheet1")

        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row

        arrData = .Range("A1:A" & LastRow)

        For i = LBound(arrData) To UBound(arrData)

            Hours = "00"
            Minutes = "00"
            Seconds = "00"

            arrLine = Split(arrData(i, 1), " ")

            For y = LBound(arrLine) To UBound(arrLine)

                If InStr(1, UCase(arrLine(y)), "HOUR") > 0 Then
                    Hours = Right("0" & arrLine(y - 1), 2)
                ElseIf InStr(1, UCase(arrLine(y)), "MINUTE") > 0 Then
                    Minutes = Right("0" & arrLine(y - 1), 2)
                ElseIf InStr(1, UCase(arrLine(y)), "SECOND") > 0 Then
                    Seconds = Right("0" & arrLine(y - 1), 2)
                End If

            Next y

            .Range("B" & i).Value = Hours & ":" & Minutes & ":" & Seconds

        Next i

    End With

End Sub

Output:

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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