Home » Fill Missing Time Fields

Fill Missing Time Fields

You need to fill in the blanks. Time In for blanks will be Time Out from non blank rows from the top sequentially. Once a row’s Time In is used, Time In from next non-blank row will be used. Time out will be Time In + Duration. Duration is in hours Ex. Item C – Time In from Item A will be used. Item E – Time In from Item B will be used. Item H – Time In from Item D will be used. Item J – Time In from Item F will be used.

📌 Challenge Details and Links
ExcelBI Power Query Challenge Number: 150
Challenge Difficulty: ⭐️⭐️⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn

Solving the challenge of Fill Missing Time Fields with Power Query

_x000D_
Power Query solution 1 for Fill Missing Time Fields, proposed by Zoran Milokanović:
let
 Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
 R = each let T = Time.From(_) in Number.From(hashtag#time(Time.Hour(T), Time.Minute(T), 0)) + Number.From(Time.Second(T) > 29) / 1440,
 F = each Table.SelectRows(Source, (r) => (r[Time In] = null) = _),
 V = (_, O, C) => Table.ReplaceValue(_, null, O, (x, y, z) => z, C),
 S = V(V(Source, each F(false){List.PositionOf(F(true)[Items], [Items])}[Time Out], {"Time In"}), each R([Time In] + [Duration] / 24), {"Time Out"})
in
 S


                    
                  
          
_x000D_ _x000D_
Power Query solution 2 for Fill Missing Time Fields, proposed by Kris Jaganah:
let
 Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 Dup = Table.DuplicateColumn(Source, "Time Out", "Time Out - Copy"),
 BlankOrNot = Table.AddColumn(Dup, "Null or not", each if [Time In] = null then 0 else 1),
 Group = Table.Group(BlankOrNot, {"Null or not"}, {{"All", each _, type table [Items=text, Time In=nullable number, Time Out=nullable number, Duration=number, #"Time Out - Copy"=nullable number, Null or not=number]}}),
 Indx = Table.AddColumn(Group, "Custom", each Table.AddIndexColumn([All],"Index",1,1)),
 Remove = Table.RemoveColumns(Indx,{"Null or not", "All"}),
 Xpand = Table.ExpandTableColumn(Remove, "Custom", {"Items", "Time In", "Time Out", "Duration", "Time Out - Copy", "Null or not", "Index"}, {"Items", "Time In", "Time Out", "Duration", "Time Out - Copy", "Null or not", "Index"}),
 Sort = Table.Sort(Xpand,{{"Index", Order.Ascending},{"Items", Order.Descending}}),
 FillUp = Table.FillUp(Sort,{"Time Out - Copy"}),
 StageTimeIn = Table.AddColumn(FillUp, "In", each if [Time In] = null then [#"Time Out - Copy"] else [Time In]),
 Remove1 = Table.RemoveColumns(StageTimeIn,{"Time In", "Time Out - Copy", "Null or not", "Index"}),



                    
                  
          
_x000D_ _x000D_
Power Query solution 3 for Fill Missing Time Fields, proposed by Kris Jaganah:
XType = Table.TransformColumnTypes(Remove1,{{"In", type time }, {"Time Out", type time}}),
 Sort1 = Table.Sort(FillOut,{{"Items", Order.Ascending}}),
 Remove2 = Table.RemoveColumns(Sort1,{"Time Out"}),
 Rename = Table.RenameColumns(Remove2,{{"Custom" ,"Time Out"}, {"In", "Time In" }}),
 ReOrder = Table.ReorderColumns(Rename,{"Items", "Time In", "Time Out", "Duration"})
in
 ReOrder
                    
                  
_x000D_ _x000D_
Power Query solution 4 for Fill Missing Time Fields, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
 Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 Type = Table.TransformColumnTypes(Source,{{"Time In", type time}, {"Time Out", type time}}),
 NoNulls = Table.SelectRows(Type, each [Time In]<>null),
 Out = List.FirstN(List.RemoveNulls(Type[Time Out]), Table.RowCount(Nulls)),
 Nulls = Table.SelectRows(Type, each [Time In]=null)[[Items],[Duration]],
 TimeIn = Table.FromColumns(Table.ToColumns(Nulls)&{Out}, Table.ColumnNames(Nulls)&{"Time In"}),
 TimeOut = Table.AddColumn(TimeIn, "Time Out", each hashtag#duration(0,0,Int64.From([Duration]*60),0)+[Time In]),
 Sol = Table.Sort(NoNulls&TimeOut, "Items")
in
 Sol


                    
                  
          
_x000D_ _x000D_
Power Query solution 5 for Fill Missing Time Fields, proposed by Luan Rodrigues:
let
 Fonte = Tabela1,
 ct = {List.FirstN(List.RemoveNulls(Fonte[Time Out]),List.Count(List.Select(Fonte[Time In], each _ = null)))},
 gp = Table.Group(Fonte, {"Time In"}, {{"Contagem", each if [Time In]{0} = null then Table.RenameColumns(
Table.RemoveColumns(Table.AddColumn(Table.FromColumns(Table.ToColumns(_)&ct, Table.ColumnNames(Fonte)&{"a"} ), "b", each hashtag#duration(0,0,Number.Round([Duration]*60, 0),0) + Duration.From([a]) ),{"Time Out","Time In"}),{{"a","Time In"},{"b","Time Out"}}) else _}})[Contagem],
 cmb = Table.Combine(gp),
 tp = Table.TransformColumnTypes(cmb,{{"Time In", type duration}, {"Time Out", type duration}}),
 res = Table.Sort(tp,{{"Items", 0}})
in
 res


                    
                  
          
_x000D_ _x000D_
Power Query solution 6 for Fill Missing Time Fields, proposed by An Nguyen:
let
 Raw= Excel.CurrentWorkbook () { [Name = "Raw" ] } [Content] ,
 NewDuration = Table.AddColumn ( Raw , "New Duration" , each [Duration] / 24) ,
 AsType = Table.TransformColumnTypes ( NewDuration , {
 { "Time In" , type time } ,
 { "Time Out" , type time } ,
 { "New Duration" , type duration}
 }
 ) ,
 AddIndexColumn = Table.AddIndexColumn ( AsType , "Index" , 1 ) ,
 RunnningCountNull = Table.AddColumn ( AddIndexColumn , "IndexFillNull" , 
 each List.Count(
 List.PositionOf(
 List.Range( AddIndexColumn [Time In] , 0 , [Index] ) , 
 null , Occurrence.All ) 
 ) - 1
 ) ,
 TimeOutNotNull = List.RemoveNulls ( AsType [Time Out] ) ,
 NewTimeIn = Table.AddColumn ( RunnningCountNull , "Time In" , each if [Time In] = null then TimeOutNotNull{[IndexFillNull]} else [Time In]) ,
 NewTimeOut = Table.AddColumn ( NewTimeIn , "Time Out" , each [Time In] + [New Duration] ) ,
 Result = Table.SelectColumns ( NewTimeOut , {"Items" , "Time  In" , "Time  Out", "Duration" } )
in
 Result


                    
                  
          
_x000D_ _x000D_
Power Query solution 7 for Fill Missing Time Fields, proposed by Eric Laforce:
let
  Source = Excel.CurrentWorkbook(){[Name = "tData150"]}[Content], 
  LTO = List.Buffer(List.RemoveNulls(Source[Time Out])), 
  Transform = List.Accumulate(
    Table.ToRecords(Source), 
    [r = {}, i = 0], 
    (s, c) =>
      let
        n = 
          if ((c[Time In] <> null)) then
            c
          else
            Record.TransformFields(
              c, 
              {{"Time In", each LTO{s[i]}}, {"Time Out", each LTO{s[i]} + c[Duration] / 24}}
            )
      in
        [r = s[r] & {n}, i = s[i] + Number.From(c <> n)]
  ), 
  ToTable = Table.FromRecords(Transform[r])
in
  ToTable
_x000D_ _x000D_
Power Query solution 8 for Fill Missing Time Fields, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
 S = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 C = Table.TransformColumnTypes(S,{{"Time In", type time}, {"Time Out", type time}}),
 M = Table.TransformColumns(C, {{"Duration", each hashtag#duration(0,0,Number.Round(_*60, 0),0), type duration}}),
 F = Table.SelectRows(M, each ([Time In] <> null)),
 Tbl = Table.AddIndexColumn(F, "Index", 1, 1, Int64.Type),
 C2 = M,
 F2 = Table.SelectRows(C2, each ([Time In] = null)),
 R = Table.SelectColumns(F2,{"Items", "Duration"}),
 In = Table.AddIndexColumn(R, "Index", 0, 1, Int64.Type),
 A = Table.AddColumn(In, "Time In", each Tbl[Time Out]{[Index]},type time),
 A2 = Table.AddColumn(A, "Time Out", each [Time In]+[Duration], type time),
 Tbl2 = Table.ReorderColumns(A2,{"Items", "Time In", "Time Out", "Duration", "Index"}),
 C3 = Table.Combine({Tbl,Tbl2}),
 S2 = Table.Sort(C3,{{"Items", Order.Ascending}}),
 R2 = Table.SelectColumns(S2,{"Items", "Time In", "Time Out", "Duration"}),
 Sol = Table.TransformColumns(R2,{{"Duration", Duration.TotalHours, type number}})
in
 Sol


                    
                  
          
_x000D_ _x000D_
Power Query solution 9 for Fill Missing Time Fields, proposed by Peter Tholstrup:
let
 source = [
 _input = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
 _types = {{"Time In", type time},{"Time Out", type time}},
 _result = Table.TransformColumnTypes(_input, _types)
 ][_result], 
 keep = Table.SelectRows(source, each [Time In] <> null), 
 transform = Table.SelectRows(source, each [Time In] = null), 
 time_in = List.FirstN(keep[Time Out], Table.RowCount(transform)), 
 time_out = List.Transform(
 List.Zip({time_in, transform[Duration]}), 
 each _{0} + hashtag#duration(0,0,Number.Round(_{1}*60,0),0)
 ), 
 transformed = hashtag#table(
 Table.ColumnNames(source), 
 List.Zip({transform[Items], time_in, time_out, transform[Duration]})
 ), 
 result = Table.Sort(Table.Combine({keep, transformed}),"Items")
in
 result


                    
                  
          
_x000D_ _x000D_
Power Query solution 10 for Fill Missing Time Fields, proposed by Glyn Willis:
let
 Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 #"Changed Type" = Table.TransformColumnTypes(Source,{{"Items", type text}, {"Time In", type time}, {"Time Out", type time}, {"Duration", Currency.Type}}),
 FR = Table.SelectRows(#"Changed Type", each ([Time In] <> null)),
 FR1 = Table.SelectRows(#"Changed Type", each ([Time In] = null)),
 Prep = Table.FromColumns(
 Table.ToColumns(FR)&{FR1[Items]&List.Repeat({null},List.Count(FR[Items])-List.Count(FR1[Items]))},
 Table.ColumnNames(#"Changed Type")&{"Prv"}),
 #"Merged Queries" = Table.NestedJoin(FR1, {"Items"}, Prep, {"Prv"}, "Prep", JoinKind.LeftOuter)[[Items],[Duration],[Prep]],
 #"Expanded Prep" = Table.ExpandTableColumn(#"Merged Queries", "Prep", {"Time Out"}, {"Time In"}),
 #"Added Custom" = Table.AddColumn(#"Expanded Prep", "Time Out", each [Time In] + hashtag#duration(0,0,Int64.From(60*[Duration]),0),type time),
 #"Appended Query" = Table.Combine({FR, #"Added Custom"}),
 #"Sorted Rows" = Table.Sort(#"Appended Query",{{"Items", Order.Ascending}})
in
 #"Sorted Rows"


                    
                  
          
_x000D_ _x000D_
Power Query solution 11 for Fill Missing Time Fields, proposed by Arden Nguyen, CPA:
let
 Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 a = List.Buffer(List.RemoveNulls(Source[Time Out])), 
 b = List.Buffer(Table.SelectRows(Source, each [Time In] = null)[Items]),
 c = Table.TransformColumnTypes(Source, {{"Time In", Time.Type}, {"Time Out", Time.Type}}),
 d = Table.ReplaceValue(c,each [Time In], each [Time In] ?? a{List.PositionOf(b,[Items])},(v,o,n) as time => Time.From(n),{"Time In"}),
 e = Table.ReplaceValue(d,each [Time Out], each [Time Out] ?? ( [Time In] + hashtag#duration(0,0,Byte.From(60*[Duration]),0) ),(v,o,n) as time => Time.From(n),{"Time Out"}) 
in
 e


                    
                  
          
_x000D_

Solving the challenge of Fill Missing Time Fields with Excel

_x000D_
Excel solution 1 for Fill Missing Time Fields, proposed by Bo Rydobon 🇹🇭:
=LET(z,B2:C11,d,D1:D11,
HSTACK(A1:A11,REDUCE(B1:C1,TAKE(z,,1),LAMBDA(a,v,LET(r,ROWS(v:B2),x,SORT(a),b,DROP(x,-1,1),t,LEFT(TEXT(INDEX(d,r+1),"00/24"),2)/24^2,
VSTACK(a,IF(v,INDEX(z,r,),XLOOKUP(TRUE,DROP(x,1,-1)-b>t,b,,1)+{0,1}*t))))),d))
_x000D_ _x000D_
Excel solution 2 for Fill Missing Time Fields, proposed by Bo Rydobon 🇹🇭:
=LET(b,B2:B11,d,D2:D11,i,MAP(b,LAMBDA(v,IF(v,v,INDEX(TOCOL(C2:C11,3),COUNTIF(v:B2,""))))),HSTACK(A2:A11,i,i+d/24,d))
_x000D_ _x000D_
Excel solution 3 for Fill Missing Time Fields, proposed by محمد حلمي:
=LET(b,B2:B11,d,D2:D11,i,LAMBDA(a,d,a+d),
c,IF(b,b,XLOOKUP(SCAN(0,b=0,i),SCAN(0,b>0,i),C2:C11)),
HSTACK(A2:A11,c,c+ROUND(d*60,)/1440,d))
_x000D_ _x000D_
Excel solution 4 for Fill Missing Time Fields, proposed by Sunny Baggu:
=LET(
 _a, FILTER(A2:D11, B2:B11 <> ""),
 _b, FILTER(A2:D11, B2:B11 = ""),
 _i, TAKE(_b, , 1),
 _d, TAKE(_b, , -1),
 _ti, TAKE(INDEX(_a, , 3), ROWS(_i)),
 _to, _ti + ROUND(60 * _d, 0) / (60 * 24),
 SORT(VSTACK(_a, HSTACK(_i, _ti, _to, _d)))
)
_x000D_ _x000D_
Excel solution 5 for Fill Missing Time Fields, proposed by Charles Roldan:
=LET(ID, A2:A11, In, B2:B11, Out, C2:C11, Dur, D2:D11, Fill, --ISBLANK(In),
 NewIn, In + Fill * INDEX(TOCOL(Out, 1), 
 Fill * SCAN(, Fill, LAMBDA(a, b, a + b))),
 NewOut, ROUND((NewIn + Dur / 24) * 288, ) / 288,
 HSTACK(ID, TEXT(NewIn, "h:mm"), TEXT(NewOut, "h:mm"), Dur))
_x000D_ _x000D_
Excel solution 6 for Fill Missing Time Fields, proposed by Tolga Demirci, PMP, PMI-ACP, MOS-Expert:
=LET(j;(0.042)*D2:D11;i;LET(w;LAMBDA(a;b;a+b);q;IF(ISERROR(SEQUENCE(C2:C11<>"";;1;1));1;0);IF(C2:C11<>"";B2:B11;INDEX(FILTER(C2:C11;C2:C11<>"");IFERROR(IF(C2:C11<>"";SEQUENCE(COUNTA(C2:C11<>"");;1;1);"")-SCAN(0;q;w);0)+IF(q=0;0;SCAN(0;q;w)))));HSTACK(A2:A11;i;i+j;j))
_x000D_ _x000D_
Excel solution 7 for Fill Missing Time Fields, proposed by Edwin Tisnado:
=LET(b,B2:B11,c,C2:C11,d,D2:D11,u,FILTER(c,c<>0),j,IF(b=0,SCAN(0,b,LAMBDA(x,y,IF(y=0,x+1,x+0)))),q,IF(j,INDEX(u,j),b),VSTACK(A1:D1,HSTACK(A2:A11,q,q+d/24,d)))
_x000D_ _x000D_
Excel solution 8 for Fill Missing Time Fields, proposed by LUIS FLORENTINO COUTO CORTEGOSO:
=LET(d,D2:D11,v,MAP(B2:B11,LAMBDA(x,IF(x="",SMALL(C2:C11,COUNTBLANK(B2:x)),x))),w,v+d/24,VSTACK(A1:D1,HSTACK(A2:A11,v,w,d)))
_x000D_ _x000D_
Excel solution 9 for Fill Missing Time Fields, proposed by Luis Couto:
=LET(d,D2:D11,v,MAP(B2:B11,LAMBDA(x,IF(x="",SMALL(C2:C11,COUNTBLANK(B2:x)),x))),w,v+d/24,VSTACK(A1:D1,HSTACK(A2:A11,v,w,d)))

=LET(w,A2:A11,x,B2:B11,y,C2:C11,z,D2:D11,i,FILTER(SEQUENCE(ROWS(y)),y<>""),m,MAP(x,LAMBDA(t,LET(b,SUM(--(B2:t="")),IF(t="",INDEX(y,INDEX(i,b)),t)))),n,IF(y="",ROUNDUP(m+z/24,3),y),VSTACK(A1:D1,HSTACK(w,m,n,z)))
_x000D_

Solving the challenge of Fill Missing Time Fields with Python

_x000D_
Python solution 1 for Fill Missing Time Fields, proposed by Jan Willem Van Holst:
In Python:
import pandas as pd
from datetime import datetime, timedelta
df = pd.read_csv(r"C:JWLENOVOPYTHONPower_Query_Challenge_150.csv", sep=';', usecols=[0,1,2,3])
df['Duration'] = df['Duration'].str.replace(',','.').astype(float)
remain= df.dropna().to_numpy().tolist()
workingList = df.fillna('').to_numpy().tolist()
for row in workingList:
 if row[1]=='':
 row[1] = remain[0][2]
 del remain[0]
 time = datetime.strptime(row[1], '%H:%M')
 minutesToAdd = row[3]*60
 newtime = pd.Timestamp(time + timedelta(minutes=minutesToAdd)).round(freq='min')
 newtimeString = newtime.strftime('%H:%M')
 # print(row[0], row[1], time, minutesToAdd, newtime, newtimeString)
 row[2]=n&ewtimeString
answer = workingList
                    
                  
_x000D_

Solving the challenge of Fill Missing Time Fields with R

_x000D_
R solution 1 for Fill Missing Time Fields, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
library(lubridate)
library(hms)
input = read_excel("Power Query/PQ_Challenge_150.xlsx", range = "A1:D11") %>%
 janitor::clean_names() 
test = read_excel("Power Query/PQ_Challenge_150.xlsx", range = "F1:I11") %>%
 janitor::clean_names() %>% 
 mutate(across(c(time_in, time_out), ~as_hms(.x)))
result = input %>%
 mutate(across(c(time_in, time_out), ~as_hms(.x))) %>%
 group_by(empty = is.na(time_in)) %>%
 mutate(nr = row_number()) %>%
 ungroup() %>%
 group_by(nr) %>%
 mutate(time_in = if_else(empty, first(time_out), time_in),
 time_out = if_else(empty, time_in + dminutes(round(duration * 60,0)), time_out)) %>%
 ungroup() %>%
 select(-c(empty, nr))
                    
                  
_x000D_ &&

Leave a Reply