【问题标题】:Convert Excel Text to Time将 Excel 文本转换为时间
【发布时间】:2020-04-14 03:00:28
【问题描述】:

我必须将一些格式化文本转换为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(),它们都在一个单元格公式中,但它们都不适用于所有情况。

您能否就如何解决这个问题给我一个想法或一些建议?

谢谢,

保罗

【问题讨论】:

  • 请显示一些现有代码。是什么导致了文本时间值?能否更改问题的根源以提供三 (3) 个不同的数值 Hr/Min/Sec?这是一次性转换为时间,还是预计在未来几天内会继续出现更多行?
  • 请检查为3 minutes 12 seconds ==> 00:02:00 编写的输出。不应该是00:03:12吗?
  • @Paul Vicioso VBA 代码中的一个选项
  • 谢谢,很抱歉回复晚了,第一个 VBA 不是一个选项,这就是为什么我没有将它作为标签包含在内。第二个是的,示例数据中有一个错误:3 分 12 秒 ==> 00:02:00 应该是 3 分 12 秒 ==> 00:03:12。感谢您的热心帮助。

标签: excel vba string date time


【解决方案1】:

我玩了一天你的问题,发现其他人也这样做了。我很欣赏 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

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

【讨论】:

  • 最后,我说服了客户使用宏,所以我使用了这个解决方案,效果非常好。谢谢。
【解决方案2】:

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

如果您有带有FILTERXML 函数的 Windows Excel 2013+,您可以使用以下内容:

=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函数:

  • 创建命名公式:
    • 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 在 cmets 中指出的那样,可以通过创建数组公式来缩短公式:

使用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 来“确认”这个 array-formula kbd> 同时点击 enter。如果您正确执行此操作,Excel 将在公式周围放置大括号 {...},如公式栏中所示

【讨论】:

  • 您可以将第一个公式包含在 SUM 中:=SUM(IFERROR(FILTERXML("&lt;t&gt;&lt;s&gt;" &amp; SUBSTITUTE(LOWER(A1)," ","&lt;/s&gt;&lt;s&gt;") &amp; "&lt;/s&gt;&lt;/t&gt;","//s[contains(.,"&amp;{"'hour'","'min'","'sec'"}&amp;")]/preceding-sibling::*[1]")/{24,1440,8640},0)),具体取决于它需要 CSE 的版本。
  • 与第二个相同:=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))
  • @ScottCraner 好点。而且我怀疑通过使用SUMPRODUCT,可以避免对 CSE 的需求。
  • 不幸的是,无论 SUMPRODUCT 还是 SUM,使用 IFERROR 都需要 CSE
  • @ScottCraner 嗯。没想到。
【解决方案3】:

好吧,您可以根据自己的需要进行编辑:

公式如下:

=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)

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

【讨论】:

    【解决方案4】:

    如果您决定使用 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
    

    输出:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-29
      • 1970-01-01
      相关资源
      最近更新 更多