Home » Monthly Per Diem Calculation

Monthly Per Diem Calculation

The data is for business trip start and end dates of employees. Split the records of an employee month-wise and calculate the amount of per diem paid in that month which is equal to number of days * Per Diem.

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

Solving the challenge of Monthly Per Diem Calculation with Power Query

Power Query solution 1 for Monthly Per Diem Calculation, proposed by John V.:
let
 S = Excel.CurrentWorkbook(){0}[Content],
 N = List.Skip(Table.ColumnNames(S)),
 F = Date.From, M = Date.Month, T = List.Transform,
 R = Table.AddColumn(S, "R", each 
 let
 s = F([Start Date]), e = F([End Date]), d = [Per Diem], 
 t = M(e) - M(s) - 1,
 a = T({0..t}, each Date.EndOfMonth(Date.AddMonths(s, _))),
 b = T(a, each Date.AddDays(_, 1)),
 c = {s} & b , v = a & {e},
 f = T({0..1 + t}, each d * (1 + Duration.Days(v{_} - c{_})))
 in
 Table.FromColumns({c, v, f}, N)
 )[[Employee], [R]]
in
 Table.ExpandTableColumn(R, "R", N)

Blessings!


                    
                  
          
Power Query solution 2 for Monthly Per Diem Calculation, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content], 
  R = Table.ToRows(Source), 
  Y = Date.Year, 
  M = Date.Month, 
  F = Date.From, 
  A = Date.AddDays, 
  E = Date.EndOfMonth, 
  S = Table.FromRows(
    List.TransformMany(
      R, 
      (x) =>
        let
          d = (Y(x{2}) - Y(x{1})) * 12 + M(x{2}) - M(x{1})
        in
          List.Accumulate(
            List.Reverse({0 .. d}), 
            {}, 
            (s, c) =>
              let
                l = List.Last(s)
              in
                s
                  & {
                    if d = 0 then
                      {x{0}, F(x{1}), F(x{2})}
                    else if s = {} then
                      {x{0}, F(x{1}), E(F(x{1}))}
                    else
                      {l{0}, A(l{2}, 1), if c = 0 then F(x{2}) else E(A(l{2}, 1))}
                  }
          ), 
      (x, y) => y & {x{3} * (Duration.Days(y{2} - y{1}) + 1)}
    ), 
    Table.ColumnNames(Source)
  )
in
  S
Power Query solution 3 for Monthly Per Diem Calculation, proposed by Kris Jaganah:
let
 Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 XType = Table.TransformColumnTypes(Source,{{"Start Date", type date}, {"End Date", type date}, {"Per Diem", Int64.Type}}),
 NoMonths = Table.AddColumn(XType, "Month Num", each { Date.Month([Start Date])..Date.Month([End Date])}),
 Xpand = Table.ExpandListColumn(NoMonths, "Month Num"),
 Start = Table.AddColumn(Xpand, "Start", each if [Month Num] - Date.Month([Start Date]) = 0 then [Start Date] else hashtag#date(Date.Year([Start Date]),[Month Num],1)),
 End = Table.AddColumn(Start, "End", each List.Min( {Date.EndOfMonth([Start] ) ,[End Date]} )),
 Per = Table.AddColumn(End, "Per", each (Number.From( [End] - [Start])+1)*[Per Diem]),
 SelectCol = Table.SelectColumns(Per,{"Employee", "Start", "End", "Per"}),
 Rename = Table.RenameColumns(SelectCol,{{"Start", "Start Date"}, {"End", "End Date"}, {"Per", "Per Diem"}}),
 XType1 = Table.TransformColumnTypes(Rename,{{"End Date", type date}, {"Start Date", type datetime}})
in
 XType1


                    
                  
          
Power Query solution 4 for Monthly Per Diem Calculation, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Group = Table.Group(
    Source, 
    {"Employee"}, 
    {
      {
        "All", 
        each 
          let
            a = _, 
            b = List.Transform(
              {Number.From([Start Date]{0}) .. Number.From([End Date]{0})}, 
              Date.From
            ), 
            c = List.Distinct(List.Transform(b, Date.Month)), 
            d = List.Transform(c, each List.Select(b, (x) => Date.Month(x) = _)), 
            e = List.Transform({0 .. List.Count(d) - 1}, each {d{_}{0}, List.Last(d{_})}), 
            f = List.Transform(
              {0 .. List.Count(e) - 1}, 
              each (Duration.Days(e{_}{1} - e{_}{0}) + 1) * a[Per Diem]{0}
            ), 
            g = Table.FromColumns(
              Table.ToColumns(Table.FromRows(e)) & {f}, 
              List.Skip(Table.ColumnNames(Source))
            )
          in
            g
      }
    }
  ), 
  Sol = Table.ExpandTableColumn(Group, "All", Table.ColumnNames(Group[All]{0}))
in
  Sol
Power Query solution 5 for Monthly Per Diem Calculation, proposed by Luan Rodrigues:
let
  Fonte = Tabela1, 
  add = Table.AddColumn(
    Fonte, 
    "Personalizar", 
    each [
      n = [Per Diem], 
      a = List.Transform(
        {Number.From([Start Date]) .. Number.From([End Date])}, 
        each Table.FromRows({{_} & {Date.ToText(Date.From(_), "MMyyyy")}})
      ), 
      b = Table.AddColumn(
        Table.Group(
          Table.Combine(a), 
          {"Column2"}, 
          {
            {"Start Date", each Date.From(List.Min([Column1]))}, 
            {"End Date", each Date.From(List.Max([Column1]))}, 
            {"count", each Table.RowCount(_)}
          }
        ), 
        "PerDiem", 
        each n * [count]
      )
    ][b]
  ), 
  rem = Table.RemoveColumns(add, {"Start Date", "End Date", "Per Diem"}), 
  res = Table.ExpandTableColumn(rem, "Personalizar", {"Start Date", "End Date", "PerDiem"})
in
  res
Power Query solution 6 for Monthly Per Diem Calculation, proposed by Brian Julius:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  AddDateList = Table.AddColumn(
    Source, 
    "DateList", 
    each [
      a = Number.From([Start Date]), 
      b = Number.From([End Date]), 
      c = {a .. b}, 
      d = List.Transform(c, each Date.From(_))
    ][d]
  ), 
  Expand = Table.ExpandListColumn(
    Table.SelectColumns(AddDateList, {"Employee", "Per Diem", "DateList"}), 
    "DateList"
  ), 
  AddMonth = Table.AddColumn(Expand, "Month", each Date.Month([DateList]), Int64.Type), 
  Group = Table.Group(
    AddMonth, 
    {"Employee", "Month"}, 
    {
      {"Count", each Table.RowCount(_), Int64.Type}, 
      {"PerDiem", each List.Max([Per Diem]), type number}, 
      {"Start Date", each List.Min([DateList]), type date}, 
      {"End Date", each List.Max([DateList]), type date}
    }
  ), 
  AddTotalPerDiem = Table.AddColumn(Group, "Per Diem", each [Count] * [PerDiem]), 
  Clean = Table.RemoveColumns(AddTotalPerDiem, {"Month", "Count", "PerDiem"})
in
  Clean
Power Query solution 7 for Monthly Per Diem Calculation, proposed by Bhavya Gupta:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  CT = Table.TransformColumnTypes(Source, {{"Start Date", type date}, {"End Date", type date}}), 
  Transformed = Table.AddColumn(
    CT, 
    "Transform", 
    each 
      let
        r = {
          1 .. (Date.Year([End Date]) - Date.Year([Start Date]))
            * 12 + Date.Month([End Date]) - Date.Month([Start Date]) + 1
        }
      in
        Table.FromColumns(
          {
            List.Transform(
              r, 
              (x) =>
                List.Max({Date.StartOfMonth(Date.AddMonths([Start Date], x - 1)), [Start Date]})
            ), 
            List.Transform(
              r, 
              (x) => List.Min({Date.EndOfMonth(Date.AddMonths([Start Date], x - 1)), [End Date]})
            )
          }, 
          {"Start Date", "End Date"}
        )
  ), 
  RemovedCols = Table.RemoveColumns(Transformed, {"Start Date", "End Date"}), 
  ReorderedCols = Table.ReorderColumns(RemovedCols, {"Employee", "Transform", "Per Diem"}), 
  Expanded = Table.ExpandTableColumn(ReorderedCols, "Transform", {"Start Date", "End Date"}), 
  Output = Table.ReplaceValue(
    Expanded, 
    each [Start Date], 
    each [End Date], 
    (a, b, c) => (Duration.Days(c - b) + 1) * a, 
    {"Per Diem"}
  )
in
  Output
Power Query solution 8 for Monthly Per Diem Calculation, proposed by Ramiro Ayala Chávez:
let
Origen = Excel.CurrentWorkbook(){[Name="Tabla1"]}[Content],
t = Table.TransformColumnTypes(Origen,{{"Start Date", type date}, {"End Date", type date}}),
a = Table.AddColumn(t, "A", each Duration.Days([End Date]-[Start Date])),
b = Table.AddColumn(a, "B", each List.Dates([Start Date],[A]+1,hashtag#duration(1,0,0,0))),
c = Table.AddColumn(b, "C", each List.Distinct(List.Transform([B], each Date.EndOfMonth(_)))),
d = Table.AddColumn(c, "D", each List.Transform([C], each Date.StartOfMonth(_))),
e = Table.TransformColumns(d, {{"C", each List.RemoveLastN(_)},{"D", each List.RemoveFirstN(_)}}),
f = Table.AddColumn(e, "E", each List.Split(List.Sort({[Start Date]}&[C]&[D]&{[End Date]}),2))[[Employee], [Per Diem],[E]],
g = Table.TransformColumns(f, {"E", each Table.FromRows(_)}),
h = Table.ExpandTableColumn(g, "E", {"Column1", "Column2"}, {"Start Date", "End Date"}),
i = Table.AddColumn(h, "F", each (Duration.Days([End Date]-[Start Date])+1)*[Per Diem]),
Sol = Table.RenameColumns(Table.RemoveColumns(i, "Per Diem"),{"F","Per Diem"})
in
Sol


                    
                  
          
Power Query solution 9 for Monthly Per Diem Calculation, proposed by Eric Laforce:
let
  Source = Excel.CurrentWorkbook(){[Name = "tData149"]}[Content], 
  CType = Table.TransformColumnTypes(Source, {{"Start Date", type date}, {"End Date", type date}}), 
  Add_Split = Table.AddColumn(
    CType, 
    "Split", 
    each 
      let
        _S = _[Start Date], 
        _E = _[End Date], 
        _P = _[Per Diem], 
        L = List.Generate(
          () => [S = Date.StartOfMonth(_S), E = Date.AddDays(_S, - 1), P = 0], 
          each _[S] < _E, 
          each 
            let
              newS = Date.AddDays(_[E], + 1), 
              newE = List.Min({Date.EndOfMonth(newS), _E})
            in
              [S = newS, E = newE, P = (Duration.Days(newE - newS) + 1) * _P]
        )
      in
        Table.FromRecords(List.Skip(L))
  ), 
  Expand = Table.ExpandTableColumn(
    Add_Split[[Employee], [Split]], 
    "Split", 
    {"S", "E", "P"}, 
    List.Skip(Table.ColumnNames(Source))
  )
in
  Expand
Power Query solution 10 for Monthly Per Diem Calculation, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
  S = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Changed = Table.TransformColumnTypes(
    S, 
    {
      {"Employee", type text}, 
      {"Start Date", type datetime}, 
      {"End Date", type datetime}, 
      {"Per Diem", Int64.Type}
    }
  ), 
  A = Table.AddColumn(Changed, "List", each {Number.From([Start Date]) .. Number.From([End Date])}), 
  Ex = Table.ExpandListColumn(A, "List"), 
  #"Changed Type1" = Table.TransformColumnTypes(Ex, {{"List", type date}}), 
  #"Inserted Month Name" = Table.AddColumn(
    #"Changed Type1", 
    "Month Name", 
    each Date.MonthName([List]), 
    type text
  ), 
  #"Grouped Rows" = Table.Group(
    #"Inserted Month Name", 
    {"Employee", "Month Name"}, 
    {
      {"Per Diem", each List.Sum([Per Diem]), type nullable number}, 
      {
        "Tbl", 
        each _, 
        type table [
          Employee = nullable text, 
          Start Date = nullable datetime, 
          End Date = nullable datetime, 
          Per Diem = nullable number, 
          List = nullable date, 
          Month Name = text
        ]
      }
    }
  ), 
  #"Added Custom1" = Table.AddColumn(#"Grouped Rows", "Start Date", each List.Min([Tbl][List])), 
  #"Added Custom2" = Table.AddColumn(#"Added Custom1", "End Date", each List.Max([Tbl][List])), 
  #"Removed Other Columns" = Table.SelectColumns(
    #"Added Custom2", 
    {"Employee", "Start Date", "End Date", "Per Diem"}
  )
in
  #"Removed Other Columns"
Power Query solution 11 for Monthly Per Diem Calculation, proposed by Rafael González B.:
let
 Source = Excel.CurrentWorkbook(){1}[Data],
 A = Table.AddColumn(Source, "B", each 
 let
 u = [Employee],
 v = [Per Diem],
 a = {Number.From([Start Date])..Number.From([End Date])},
 b = List.Transform(a, each Date.From(_)),
 c = List.Transform(b, each Date.Month(_)),
 d = Table.FromColumns({b,c}),
 e = Table.Group(d, 
 {"Column2"}, 
 {{"Start Date", each List.Min([Column1])}, 
 {"End Date", each List.Max([Column1])}
 }),
 f = Table.AddColumn(e, "Per Diem", each (Duration.Days([End Date] - [Start Date]) + 1) * v),
 g = Table.AddColumn(f, "Employee", each u),
 h = g[[Employee], [Start Date], [End Date], [Per Diem]]
 in 
 h
 )[B]
in
 Table.Combine(A)

🧙‍♂️🧙‍♂️🧙‍♂️



                    
                  
          
Power Query solution 12 for Monthly Per Diem Calculation, proposed by Sandeep Marwal:
let
 Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 #"Changed Type" = Table.TransformColumnTypes(Source,{{"Employee", type text}, {"Start Date", type date}, {"End Date", type date}, {"Per Diem", Int64.Type}}),
 #"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each List.Dates([Start Date],1+Number.From([End Date])-Number.From([Start Date]),hashtag#duration(1,0,0,0))),
 #"Expanded Custom" = Table.ExpandListColumn(#"Added Custom", "Custom"),
 #"Inserted Month Name" = Table.AddColumn(#"Expanded Custom", "Month Name", each Date.MonthName([Custom]), type text),
 #"Grouped Rows" = Table.Group(#"Inserted Month Name", {"Employee", "Month Name"}, {{"Count", each 
[
Start Date = List.First(_[Custom]),
End Date =List.Last(_[Custom]),
Per Diem =_[Per Diem]{0} * List.Count(_[Custom])
]
}}),
 #"Expanded Count" = Table.ExpandRecordColumn(#"Grouped Rows", "Count", {"Start Date", "End Date", "Per Diem"}, {"Start Date", "End Date", "Per Diem"}),
 #"Removed Columns" = Table.RemoveColumns(#"Expanded Count",{"Month Name"}),
 #"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns",{{"Start Date", type date}, {"End Date", type date}})
in
 #"Changed Type1"


                    
                  
          
Power Query solution 13 for Monthly Per Diem Calculation, proposed by Glyn Willis:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  #"Changed Type" = Table.TransformColumnTypes(
    Source, 
    {
      {"Employee", type text}, 
      {"Start Date", type date}, 
      {"End Date", type date}, 
      {"Per Diem", Int64.Type}
    }
  ), 
  #"Added Custom" = Table.AddColumn(
    #"Changed Type", 
    "Custom", 
    each [
      d = Duration.Days([End Date] - [Start Date]) + 1, 
      m = ((Date.Year([End Date]) - Date.Year([Start Date])) * 12)
        + (Date.Month([End Date]) - Date.Month([Start Date])), 
      g = 
        let
          f = m = 0, 
          d = [Per Diem], 
          s = [Start Date], 
          e = [End Date]
        in
          Table.FromRecords(
            List.Generate(
              () => [
                SD = s, 
                ED = if f then e else Date.EndOfMonth(s), 
                D  = (Duration.Days(ED - SD) + 1) * d, 
                i  = 0
              ], 
              each [i] <= m, 
              each [
                SD = Date.AddDays([ED], 1), 
                ED = if i = m then e else Date.EndOfMonth(SD), 
                D  = (Duration.Days(ED - SD) + 1) * d, 
                i  = [i] + 1
              ]
            )
          )
    ][g], 
    type table [SD = date, ED = date, D = number]
  )[[Employee], [Custom]], 
  #"Expanded Custom" = Table.ExpandTableColumn(
    #"Added Custom", 
    "Custom", 
    {"SD", "ED", "D"}, 
    {"Start Date", "End Date", "Diem"}
  )
in
  #"Expanded Custom"
Power Query solution 14 for Monthly Per Diem Calculation, proposed by Arden Nguyen, CPA:
let
  a = Table.AddColumn(
    Source, 
    "Dates", 
    each List.Transform({Number.From([Start Date]) .. Number.From([End Date])}, Date.From)
  ), 
  b = Table.ExpandListColumn(a, "Dates"), 
  c = Table.AddColumn(b, "Month", each Date.EndOfMonth([Dates])), 
  d = Table.Group(
    c, 
    {"Employee", "Month"}, 
    {
      {"Start Date", each List.First([Dates]), type date}, 
      {"End Date", each List.Last([Dates]), type date}, 
      {"Per Diem", each List.Sum([Per Diem]), type number}
    }, 
    GroupKind.Local, 
    (x, y) => Byte.From(x[Month] <> y[Month] or x[Employee] <> y[Employee])
  ), 
  sol = Table.SelectColumns(d, {"Employee", "Start Date", "End Date", "Per D&iem"})
in
  sol
Power Query solution 15 for Monthly Per Diem Calculation, proposed by Kerwin Tan CPA:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  #"Changed Type" = Table.TransformColumnTypes(
    Source, 
    {
      {"Employee", type text}, 
      {"Start Date", type date}, 
      {"End Date", type date}, 
      {"Per Diem", Currency.Type}
    }
  ), 
  Transform = Table.AddColumn(
    #"Changed Type", 
    "Custom", 
    each 
      let
        currRow = _, 
        cnt = Date.Month(currRow[End Date]) - Date.Month(currRow[Start Date]), 
        lst = {0 .. cnt}, 
        transformation = List.TransformMany(
          lst, 
          (_) =>
            let
              emp = currRow[Employee], 
              startDt = List.Max(
                {currRow[Start Date], Date.StartOfMonth(Date.AddMonths(currRow[Start Date], _))}
              ), 
              endDt = List.Min(
                {currRow[End Date], Date.EndOfMonth(Date.AddMonths(currRow[Start Date], _))}
              ), 
              pdiem = currRow[Per Diem], 
              pdiemAdj = (Duration.Days(endDt - startDt) + 1) * pdiem
            in
              {{emp, startDt, endDt, pdiemAdj}}, 
          (x, y) => y
        ), 
        tbl = Table.FromRows(
          transformation, 
          type table [
            Employee = text, 
            #"Start Date" = date, 
            #"End Date" = date, 
            #"Per Diem" = Int64.Type
          ]
        )
      in
        tbl
  ), 
  Output = Table.Combine(Transform[Custom])
in
  Output

Solving the challenge of Monthly Per Diem Calculation with Excel

Excel solution 1 for Monthly Per Diem Calculation, proposed by Bo Rydobon 🇹🇭:
=LET(z,A2:D6,REDUCE(A1:D1,TAKE(z,,1),LAMBDA(a,v,LET(r,ROWS(A2:v),b,INDEX(z,r,2),c,INDEX(z,r,3),
w,WRAPROWS(SORT(TOCOL(DROP(VSTACK(b,c,EOMONTH(b,SEQUENCE(YEARFRAC(b+1,EOMONTH(c,0))*12+1)-1)+{0,1}),-1),3)),2),
VSTACK(a,IFNA(HSTACK(v,w,(DROP(w,,1)-TAKE(w,,1)+1)*INDEX(z,r,4)),v))))))
Excel solution 2 for Monthly Per Diem Calculation, proposed by John V.:
=REDUCE(A1:D1,SEQUENCE(ROWS(A2:D6)),LAMBDA(a,v,LET(f,LAMBDA(c,INDEX(A2:D6,v,c)),s,f(2),b,WRAPROWS(TOCOL(VSTACK(s,EOMONTH(s,SEQUENCE(MONTH(f(3))-MONTH(s))-1)+{0,1},f(3)),2),2),i,TAKE(b,,1),VSTACK(a,HSTACK(IF(i,f(1)),b,IF(i,f(4)*(1+BYROW(b*{-1,1},SUM))))))))
Excel solution 3 for Monthly Per Diem Calculation, proposed by محمد حلمي:
=REDUCE(A1:D1,A2:A6,LAMBDA(a,d,VSTACK(a,LET(
q,TAKE(d:D6,1),w,MEDIAN(q),c,MAX(q),j,MIN(q),
i,EOMONTH(w,SEQUENCE(MONTH(c)-MONTH(w)+1)-1),
v,FILTER(i,i
Excel solution 4 for Monthly Per Diem Calculation, proposed by 🇰🇷 Taeyong Shin:
=LET(func,LAMBDA(a,v,LET(f,LAMBDA(c,INDEX(A2:D6,ROWS(A2:v),c)),s,f(2),e,f(3),n,MONTH(e)-MONTH(s),d,IF(n,WRAPROWS(VSTACK(s,TOCOL(EOMONTH(s,SEQUENCE(n,,0))+{0,1}),e),2),HSTACK(s,e)),VSTACK(a,HSTACK(T(TAKE(d,,1))&f(1),d,(BYROW(d*{-1,1},SUM)+1)*f(4))))),REDUCE(A1:D1,A2:A6,func))
Excel solution 5 for Monthly Per Diem Calculation, proposed by Kris Jaganah:
=REDUCE(A1:D1,B2:B6,LAMBDA(x,y,VSTACK(x,LET(a,OFFSET(y,,1),b,SEQUENCE(MONTH(a)-MONTH(y)+1),c,INDEX(OFFSET(y,,-1),SEQUENCE(MAX(b),,,0)),d,SCAN("",DROP(HSTACK(b,y),,1),LAMBDA(x,y,IF(ISNA(y),EOMONTH(x,0)+1,y))),e,EOMONTH(d,0),f,IF(a>e,e,a),HSTACK(c,d,f,(f-d+1)*OFFSET(y,,2))))))
Excel solution 6 for Monthly Per Diem Calculation, proposed by Bhavya Gupta:
=LET(emp,A2:A6,sd,B2:B6,ed,C2:C6,pd,D2:D6,rw,ROUNDUP(YEARFRAC(EOMONTH(0+sd,-1)+1,EOMONTH(0+ed,0),1)*12,),rt,SCAN(0,rw,LAMBDA(x,y,x+y)),s,SEQUENCE(MAX(rt)),fn,LAMBDA(ra,XLOOKUP(s,rt,ra,,1,2)),k,s-fn(rt-rw)-2,fsd,MAP(EOMONTH(fn(sd),k)+1,fn(sd),LAMBDA(a,b,MAX(a,b))),fed,MAP(EOMONTH(fn(sd),k+1),fn(ed),LAMBDA(a,b,MIN(a,b))),HSTACK(fn(emp),fsd,fed,fn(pd)*(fed-fsd+1)))
Excel solution 7 for Monthly Per Diem Calculation, proposed by Tolga Demirci, PMP, PMI-ACP, MOS-Expert:
=LET(p;MAP(B2:B6;C2:C6;LAMBDA(x;y;TEXTJOIN(";";;MAP(UNIQUE(TEXT(SEQUENCE(y-x+1;;x;1);"aa"));LAMBDA(j;LET(i;SEQUENCE(y-x+1;;x;1);MIN(FILTER(i;TEXT(i;"aa")=j))))))));q;MAP(B2:B6;C2:C6;LAMBDA(x;y;TEXTJOIN(";";;MAP(UNIQUE(TEXT(SEQUENCE(y-x+1;;x;1);"aa"));LAMBDA(j;LET(i;SEQUENCE(y-x+1;;x;1);MAX(FILTER(i;TEXT(i;"aa")=j))))))));w;MAP(A2:A6;B2:B6;C2:C6;LAMBDA(a;b;c;CONCAT(TEXTJOIN(";";;IF(UNIQUE(TEXT(SEQUENCE(c-b+1;;b;1);"aa"))<>"";a;""));";")));HSTACK(TOCOL(TEXTSPLIT(TEXTJOIN(;;w);";";";";TRUE;;" "));TEXT(TEXTSPLIT(TEXTJOIN(";";;p);;";");"gg/aa/yyyy");TEXT(TEXTSPLIT(TEXTJOIN(";";;q);;";");"gg/aa/yyyy");(DATEVALUE(TEXT(TEXTSPLIT(TEXTJOIN(";";;q);;";");"gg/aa/yyyy"))-DATEVALUE(TEXT(TEXTSPLIT(TEXTJOIN(";";;p);;";");"gg/aa/yyyy"))+1)*BYROW(TOCOL(TEXTSPLIT(TEXTJOIN(;;w);";";";";TRUE;;" "));LAMBDA(z;XLOOKUP(z;A2:A6;D2:D6)))))
Excel solution 8 for Monthly Per Diem Calculation, proposed by LUIS FLORENTINO COUTO CORTEGOSO:
=LET(k,MAP(A2:A6,B2:B6,C2:C6,D2:D6,LAMBDA(e,x,y,p,LET(i,SEQUENCE(y-x+1,,x),TEXTJOIN("/",,BYROW(UNIQUE(MONTH(i)),LAMBDA(m,LET(j,FILTER (i,MONTH(i)=m),TEXTJOIN(",",,e,MIN(j),MAX(j),ROWS(j)*p)))))))),r,REDUCE(A1:D1,k,LAMBDA(a,l,VSTACK(a,TEXTSPLIT(l,",","/")))),IFERROR(r*1,r))
Excel solution 9 for Monthly Per Diem Calculation, proposed by Hazem Hassan:
=LET(j,A2:A6,a,WRAPROWS(TOCOL(TEXTSPLIT(CONCAT(j&"-"&MAP(j,B2:B6,C2:C6,LAMBDA(z,x,y,LET(b,SEQUENCE(y-x+1,,x),c,MONTH(b),r,TOROW(UNIQUE(c)),TEXTJOIN("-"&z&{"*","-"},1,TOROW(VSTACK(XLOOKUP(r,c,b),XLOOKUP(r,c,b,,,-1)),,1)))))&"@"),{"-","*","-"},"@",1,),3,0),4),t,CHOOSECOLS(a,{2,4}),HSTACK(TAKE(a,,1),t,BYROW(t,LAMBDA(x,1+ABS(SUM(x*{1,-1}))))*VLOOKUP(TAKE(a,,1),$A$2:$D$6,4,0)))

Solving the challenge of Monthly Per Diem Calculation with Python

Python solution 1 for Monthly Per Diem Calculation, proposed by Jan Willem Van Holst:
In Python:
from datetime import date
df = pd.read_csv(r"C:JWLENOVOPYTHONPower_Query_Challenge_149.csv",sep=';',
 usecols=['Employee', 'Start Date', 'End Date', 'Per Diem']).dropna()
df['Start Date'] = pd.to_datetime(df['Start Date'], format='%d/%m/%Y')
df['End Date'] = pd.to_datetime(df['End Date'], format='%d/%m/%Y')
def fx(row):
 emp, start, end, perDiem = row
 rangeD = [date.fromisoformat(x) for x in pd.date_range(start=start, end=end).strftime("%Y-%m-%d").to_list()]
 rangeM = list(set([x.month for x in rangeD]))
 listPerMonth = []
 for i in rangeM:
 listPerMonth.append([x.strftime("%d-%m-%Y") for x in rangeD if x.month == i])
 detailPerMont = []
 for i in listPerMonth:
 detailPerMont.append([emp, i[0], i[-1], len(i)*perDiem])
 return detailPerMont
AsList = df.to_numpy().tolist()
answer =[]
for row in AsList:
 answer = answer + fx(row)
                    
                  

Solving the challenge of Monthly Per Diem Calculation with R

R solution 1 for Monthly Per Diem Calculation, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
input = read_excel("Power Query/PQ_Challenge_149.xlsx", range = "A1:D6") %>%
 janitor::clean_names()
test = read_excel("Power Query/PQ_Challenge_149.xlsx", range = "F1:I12") %>%
 janitor::clean_names() %>% 
 arrange(employee, start_date)
result = input %>%
 mutate(days = map2(start_date, end_date, ~ seq(.x, .y, by = "day"))) %>%
 unnest(days) %>%
 mutate(month = floor_date(days, "month")) %>%
 select(-start_date, -end_date) %>%
 group_by(employee, per_diem, month) %>%
 summarise(n_days = n(),
 start_date = min(days),
 end_date = max(days)) %>%
 ungroup() %>%
 mutate(total = n_days * per_diem) %>%
 select(employee, start_date, end_date, per_diem = total) %>%
 arrange(employee, start_date)
                    
                  

&&

Leave a Reply