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

时间:2017-06-28 15:17:54

标签: excel formula

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

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。

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

2 个答案:

答案 0 :(得分:2)

这是一个VBA解决方案。即使你没有要求VBA,为此目的的UDF(用户定义函数)编写起来相对简单,并且将来会改变。我使用正则表达式来识别时间。

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

要输入此用户定义函数(UDF), alt-F11 将打开Visual Basic编辑器。 确保在Project Explorer窗口中突出显示您的项目。 然后,从顶部菜单中选择“插入/模块” 将下面的代码粘贴到打开的窗口中。

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

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

在某个单元格中。

第二个参数(如果省略,默认为1),确定是否从字符串中提取第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即可。

enter image description here

答案 1 :(得分:1)

你能试试这个可怕的公式吗?将其放在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)))