从一个单元格中提取 2 次并放入两个不同的列中?

Extract 2 times from a cell and put into two different columns?

我有一个这样的电子表格:

B 列:

The Auditor arrived at 9am and left at 2pm
The Auditor arrived 09:00, left 16:00

我想提取审计员到达的开始时间并将其放入 C 列,如下所示:

C 列

9
9

然后提取结束时间并将其放入D列。

D 列

2
4

然后在 E 列中我想计算审核员在现场的小时数:

E 列

5
7

目前我正在使用这个公式来确定单元格中第一个数字的位置:

这是我用来尝试检索数字的 C 列中的公式:

=MID(B18,MIN(FIND({0,1,2,3,4,5,6,7,8,9},B18&"0123456789")),1)

我的问题是这仅在开始时间是一位而不是两位或更多时才有效,所以上午 9 点不是 09:00。

有人可以告诉我最好的方法吗?

你能试试这个可怕的公式吗?将其放在 C18 单元格...

=24*IF(OR(IFERROR(FIND("am";MID(B18;MIN(FIND({0;1;2;3;4;5;6;7;8;9};B18&"0123456789"));5);1);0)>0;IFERROR(FIND("pm";MID(B18;MIN(FIND({0;1;2;3;4;5;6;7;8;9};B18&"0123456789"));5);1);0)>0)=TRUE;TIMEVALUE(MID(MID(B18;MIN(FIND({0;1;2;3;4;5;6;7;8;9};B18&"0123456789"));5);1;MIN(FIND({"am";"pm"};MID(B18;MIN(FIND({0;1;2;3;4;5;6;7;8;9};B18&"0123456789"));5)&"ampm";1)-1))&" "&MID(MID(B18;MIN(FIND({0;1;2;3;4;5;6;7;8;9};B18&"0123456789"));5);MIN(FIND({"am";"pm"};MID(B18;MIN(FIND({0;1;2;3;4;5;6;7;8;9};B18&"0123456789"));5)&"ampm";1));2));TIMEVALUE(MID(B18;MIN(FIND({0;1;2;3;4;5;6;7;8;9};B18&"0123456789"));5)))

这是一个 VBA 解决方案。即使您没有要求 VBA,用于此目的的 UDF(用户定义函数)编写起来也相对简单,将来也可以更改。我用了一个正则表达式来识别时间。

可接受的时间格式包括您示例中显示的时间格式,数字和 am/pm 之间有或没有 space,以及 2:00 下午或类似时间。如有必要,可以轻松添加其他时间格式。

要输入此用户定义函数 (UDF),alt-F11 打开 Visual Basic 编辑器。 确保您的项目在 Project Explorer window 中突出显示。 然后,从顶部菜单 select Insert/Module 和 将下面的代码粘贴到打开的 window 中。

要使用此用户定义函数 (UDF),请输入类似

的公式
=ExtrTm(B1)
=ExtrTm(B1,1)
=ExtrTm(B1,2)    

在某个单元格中。

第二个参数(如果省略则默认为一个)决定是否从字符串中提取第 1 次或第 2 次(如果有更多则为第 n 次)。

编辑: 编辑代码以提供正则表达式,允许可选地使用 dot (.) 作为时间分隔符。


Option Explicit
Function ExtrTm(S As String, Optional tmIndex As Long = 1) As Date
    Dim RE As Object, MC As Object
    'Const sPat As String = "\d+(?::\d+)?\s*(?:am|pm)?"

    'To allow for optional use of dot as a time separator, use
    Const sPat As String = "\d+(?:[:.]\d+)?\s*(?:am|pm)?"

Set RE = CreateObject("vbscript.regexp")
With RE
    .Global = True
    .Pattern = sPat
    .ignorecase = True
    If .test(S) = True Then
        Set MC = .Execute(S)
        ExtrTm = CDate(MC(tmIndex - 1))
    End If
End With

End Function

结果是 Excel 时间,是一天的一小部分。如果将结果格式化为时间,您将以人类可读的方式查看结果。如果您需要以小数小时表示(例如乘以小时费率),只需将返回值乘以 24。