[英]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:
Formulas
→ Defined Names
→ Define Name
→ New Name
→ seq_99 → Refers 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)
算法:
hour
或min
或sec
注意:自定义格式列 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 的主要优势是几乎任何事情都可以使用几行额外的代码来处理。 工作表函数没有这种能力。
如果您决定使用 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.