Home » Check Date Within Name Range

Check Date Within Name Range

In result table, populate Y and N against the names given in T1. Date range in Dates column of result table is min of From and max of To for the names given in T1. T1 doesn’t have E and F, hence while computing min and max, dates from E & F will not be considered. Y – If a date is within the date range otherwise N. For example, range of dates for A is from 2/1/23 to 3/5/23. Hence, all dates within this range is Y for A. All dates outside this range is N. Note – Dates are in MDY format, hence you may need to convert in your native format.

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

Solving the challenge of Check Date Within Name Range with Power Query

Power Query solution 1 for Check Date Within Name Range, proposed by Omid Motamedisedeh:
let
 
 Table2 = Table.TransformColumnTypes(Excel.CurrentWorkbook(){[Name="Table2"]}[Content],{{"From", type date}, {"To", type date}}),
 X = [A=List.Min(Table2[From]),B=List.Max(Table2[To]),C=List.Dates(A,Number.From(B-A),hashtag#duration(1,0,0,0))][C],
 Table1 = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 Y = {X} & List.Transform(Table1[Name], (ox)=> [A=Table.SelectRows(Table2, each [Name]=ox), B=List.Transform(X, each try (if (_>=A[From]{0} and _<=A[To]{0}) then "y" else "n") otherwise "n")][B] ),
 Result = Table.FromColumns(Y,{"Date"} & Table1[Name])
in
 Result
                    
                  
          
Power Query solution 2 for Check Date Within Name Range, proposed by Bo Rydobon 🇹🇭:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  N = Table.ExpandListColumn(
    Table.TransformColumns(
      Table.AddColumn(
        Source, 
        "Date", 
        each Excel.CurrentWorkbook(){[Name = "Table2"]}[Content]{[Name = [Name]]}?
      ), 
      {"Date", each try {Number.From([From]) .. Number.From([To])} otherwise {}}
    ), 
    "Date"
  ), 
  ND = N
    & Table.AddColumn(
      Table.FromValue({List.Min(N[Date]) .. List.Max(N[Date])}, [DefaultColumnName = "Date"]), 
      "Name", 
      each "Date"
    ), 
  Pivot = Table.Pivot(
    Table.DuplicateColumn(Table.SelectRows(ND, each [Date] <> null), "Date", "Ds"), 
    List.Distinct(N[Name]), 
    "Name", 
    "Ds", 
    each if List.Count(_) > 0 then "Y" else "N"
  ), 
  ChangedType = Table.TransformColumnTypes(Pivot, {{"Date", type date}})
in
  ChangedType
Power Query solution 3 for Check Date Within Name Range, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table2"]}[Content], 
  Table1 = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  DateRange = Table.CombineColumns(
    Table.SelectRows(Source, each List.Contains(Table1[Name], [Name])), 
    {"From", "To"}, 
    each List.Transform({Number.From(_{0}) .. Number.From(_{1})}, Date.From), 
    "DR"
  ), 
  Solution = Table.FromRows(
    List.Transform(
      List.Sort(List.Distinct(List.Combine(DateRange[DR]))), 
      (d) => {d}
        & List.Transform(
          Table1[Name], 
          (t1) =>
            if Table.RowCount(
              Table.SelectRows(DateRange, each List.Contains([DR], d) and [Name] = t1)
            )
              > 0
            then
              "Y"
            else
              "N"
        )
    ), 
    {"Dates"} & Table1[Name]
  )
in
  Solution
Power Query solution 4 for Check Date Within Name Range, proposed by Kris Jaganah:
let
 Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 Change = Table.TransformColumnTypes(Source,{{"From", Int64.Type}, {"To", Int64.Type}}),
 Source1 = Excel.CurrentWorkbook(){[Name="Table2"]}[Content],
 Merge = Table.NestedJoin(Source1, {"Name"}, Change, {"Name"}, "Change", JoinKind.LeftOuter),
 Expand = Table.ExpandTableColumn(Merge, "Change", {"From", "To"}, {"Change.From", "Change.To"}),
 Rept = Table.AddColumn(Expand, "Y", each List.Repeat({"Y"},(if [Change.From]=null then 1 else [Change.To]-[Change.From]+1))),
 Expand1 = Table.ExpandListColumn(Rept, "Y"),
 SortPrep = Table.AddColumn(Expand1, "Sort", each if[Change.From]=null then "" else[Change.From]),
 Group = Table.Group(SortPrep, {"Sort", "Name"}, {{"All", each _, type table [Name=text, Change.From=nullable number, Change.To=nullable number, Y=text, Sort=any]}}),
 DateIndx = Table.AddColumn(Group, "Custom", each try Table.AddIndexColumn([All],"Date",[Sort]) otherwise null),
 ExpDate = Table.ExpandTableColumn(DateIndx, "Custom", {"Y", "Date"}, {"Custom.Y", "Dates"}),
 


                    
                  
          
Power Query solution 5 for Check Date Within Name Range, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Origen = Excel.CurrentWorkbook(){[Name = "Tabla1"]}[Content], 
  Tabla2 = Excel.CurrentWorkbook(){[Name = "Tabla2"]}[Content], 
  Fecha = Table.SelectRows(
    Table.AddColumn(
      Tabla2, 
      "Dia", 
      each List.Transform({Number.From([From]) .. Number.From([To])}, Date.From)
    )[[Name], [Dia]], 
    each List.Contains(Origen[Name], [Name])
  ), 
  Lista = Table.FromColumns({List.Sort(List.Distinct(List.Combine(Fecha[Dia])))}, {"Dates"}), 
  Sol = List.Accumulate(
    Origen[Name], 
    Lista, 
    (s, c) =>
      Table.AddColumn(
        s, 
        c, 
        each try
          
            if List.Contains(Table.SelectRows(Fecha, each [Name] = c)[Dia]{0}, [Dates]) then
              "Y"
            else
              "N"
        otherwise
          "N"
      )
  )
in
  Sol
Power Query solution 6 for Check Date Within Name Range, proposed by Luan Rodrigues:
let
  Fonte = Excel.CurrentWorkbook(){[Name = "Tabela2"]}[Content], 
  fil = Excel.CurrentWorkbook(){[Name = "Tabela1"]}[Content][Name], 
  list = [
    a = List.Combine(List.RemoveFirstN(Table.ToColumns(Fonte), 1)), 
    b = Table.FromList(
      {Number.From(List.Min(a)) .. Number.From(List.Max(a))}, 
      Splitter.SplitByNothing()
    )
  ][b], 
  mes = Table.NestedJoin(list, {"Column1"}, exp, {"Personalizar"}, "list", JoinKind.LeftOuter), 
  ep = Table.ExpandTableColumn(mes, "list", {"Name"}), 
  f = Table.SelectRows(ep, each List.Contains(fil, [Name])), 
  dup = Table.DuplicateColumn(f, "Column1", "Dates"), 
  pv = Table.Pivot(dup, List.Distinct(dup[Name]), "Name", "Column1"), 
  reo = Table.ReorderColumns(pv, fil, MissingField.UseNull), 
  tip = Table.TransformColumnTypes(reo, {{"Dates", type date, "en-US"}}), 
  res = Table.ReplaceValue(tip, null, "N", (a, b, c) => if a = null then "N" else "Y", fil), 
  tab = Table.AddColumn(Fonte, "Personalizar", each {Number.From([From]) .. Number.From([To])}), 
  exp = Table.ExpandListColumn(tab, "Personalizar")
in
  res
Power Query solution 7 for Check Date Within Name Range, proposed by Eric Laforce:
let
 T1 = Excel.CurrentWorkbook(){[Name="tData86_1"]}[Content],
 T2 = Excel.CurrentWorkbook(){[Name="tData86_2"]}[Content],
 Names = T1[Name], 
 TRanges = Table.SelectRows(T2, each List.Contains(Names, [Name]) ),
 DMin = List.Min(TRanges[From]), DMax = List.Max(TRanges[To]),
 CDates = {Number.From(DMin)..Number.From(DMax)},
 CData = List.Accumulate(Names, {}, (s,c)=>let 
 _D = Table.SelectRows(TRanges, each [Name]=c){0}?,
 _Col = if (_D=null) then List.Repeat({"N"}, Duration.Days(DMax-DMin)+1)
 else List.Repeat({"N"}, Duration.Days(_D[From]-DMin)*Number.From(_D[From]>DMin)) 
 & List.Repeat({"Y"}, Duration.Days(_D[To]-_D[From])+1)
 & List.Repeat({"N"}, Duration.Days(DMax-_D[To])*Number.From(DMax>_D[To]))
 in s &{_Col}),
 Result = Table.FromColumns({CDates} & CData, {"Dates"} & Names), 
 CType = Table.TransformColumnTypes(Result,{{"Dates", type date}})
in
 CType

NB : Each Name-Column is 3 or 1 repetitions of 'N'/'Y' letter
based on Number of days "Before"/"During"/"After" each Periode
Instead of calculating it individually


                    
                  
          
Power Query solution 8 for Check Date Within Name Range, proposed by Victor Wang:
let
  Source = Table.SelectRows(T2, each List.Contains(T1[Name], [Name])), 
  listOfDates = Table.FromRecords(
    Table.TransformRows(
      Source, 
      each [Name = [Name], Dates = {Number.From([From]) .. Number.From([To])}]
    )
  ), 
  expandDatesToRows = Table.ExpandListColumn(listOfDates, "Dates"), 
  duplicateDates = Table.DuplicateColumn(expandDatesToRows, "Dates", "Dates2"), 
  pivotNames = Table.Pivot(
    duplicateDates, 
    T1[Name], 
    "Name", 
    "Dates2", 
    each if List.IsEmpty(_) then "N" else "Y"
  ), 
  typeDate = Table.TransformColumnTypes(pivotNames, {{"Dates", type date}})
in
  typeDate
Power Query solution 9 for Check Date Within Name Range, proposed by Gráinne Duggan:
let
 Source2 = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 Source = Excel.CurrentWorkbook(){[Name="Table2"]}[Content], 
 FilterNull = Table.SelectRows(Table.NestedJoin(Source2, {"Name"}, Source, {"Name"}, "Source", JoinKind.FullOuter), each ([Name] <> null)),
 Expand = Table.ExpandTableColumn(FilterNull, "Source", {"From", "To"}, {"From", "To"}),
 AddedDates = Table.AddColumn(Table.TransformColumnTypes(Expand,{{"From", type date}, {"To", type date}}), "Custom", each if [From] = null then { 1 } else {Number.From( [From])..Number.From( [To])}),
 ExpandDates = Table.ExpandListColumn(AddedDates, "Custom")[[Name],[Custom]],
 AddYN = Table.AddColumn(ExpandDates, "Custom.1", each if [Custom] = 1 then "N" else "Y"), 
 Sort = Table.Sort(Table.TransformColumnTypes(AddYN,{{"Custom", type date}}),{{"Name", Order.Ascending}}),
 Pivot = Table.Pivot(Sort, List.Distinct(Sort[Name]), "Name", "Custom.1"),
 ReplaceNull = Table.ReplaceValue(Pivot,null,"N",Replacer.ReplaceValue,{"A", "C", "D", "B"}),
 Filter = Table.SelectRows(ReplaceNull, each ([Custom] <> hashtag#date(1899, 12, 31)))
in
 Filter
                    
                  
          

Solving the challenge of Check Date Within Name Range with Excel

Excel solution 1 for Check Date Within Name Range, proposed by Bo Rydobon 🇹🇭:
=LET(a,TOROW(A2:A5),c,C2:C6,
f,XLOOKUP(a,c,D2:D6,""),t,MAXIFS(E2:E6,c,a),
m,MIN(f),s,SEQUENCE(MAX(t)-m+1,,m),
VSTACK(HSTACK("Dates",a),HSTACK(s,IF((f<=s)*(t>=s),"Y","N"))))
Excel solution 2 for Check Date Within Name Range, proposed by Bo Rydobon 🇹🇭:
=LET(a,A2:A5,b,C2:E6,c,TAKE(b,,1),d,FILTER(b,COUNTIF(a,c)),f,MIN(d),s,SEQUENCE(MAX(d)-f+1,,f),
VSTACK(HSTACK("Dates",TOROW(a)),REDUCE(s,a,LAMBDA(g,v,LET(x,XLOOKUP(v,c,b,0),HSTACK(g,IF((s>=MIN(x))*(s<=MAX(x)),"Y","N")))))))
Excel solution 3 for Check Date Within Name Range, proposed by محمد حلمي:
=LET(i,TOROW(A2:A5),l,C2:C6,m,MIN(IF(i=l,D2:D6)),
s,SEQUENCE(MAX(IF(i=l,E2:E6))-m+1,,m),VSTACK(
HSTACK("Dates",i),REDUCE(s,i,LAMBDA(a,d,LET(r,IF(l=d,D2:E6),HSTACK(a,IF((MIN(r)<=s)*(MAX(r)>=s),"Y","N")))))))
Excel solution 4 for Check Date Within Name Range, proposed by Oscar Mendez Roca Farell:
=LET(_n, A2:A5,_d, LAMBDA(i, XLOOKUP(_n, C2:C6, i, "")), _f,_d(D2:D6),_t,_d(E2:E6),_s, SEQUENCE(MAX(_t)-MIN(_f)+1, ,MIN(_f)), _r,IF((_s>=TOROW(_f))*(_s<=TOROW(_t)),"Y","N"), VSTACK(HSTACK("Dates", TOROW(_n)), HSTACK(_s,_r)))
Excel solution 5 for Check Date Within Name Range, proposed by Sunny Baggu:
=LET(
 _ftbl, CHOOSEROWS(
 HSTACK(C2:E6, E2:E6 - D2:D6 + 1),
 TOCOL(XMATCH(A2:A5, C2:C6), 2)
 ),
 _e1, LAMBDA(x, INDEX(_ftbl, , x)),
 _min, MIN(_e1(2)),
 _max, MAX(_e1(3)),
 _rng, SEQUENCE(_max - _min + 1, , _min),
 _res, DROP(
 REDUCE(
 "",
 A2:A5,
 LAMBDA(a, v,
 HSTACK(
 a,
 LET(
 _r, MATCH(v, _e1(1)),
 _list, SEQUENCE(INDEX(_e1(4), _r, 1), , INDEX(_e1(2), _r, 1)),
 IF(ISNUMBER(XMATCH(_rng, _list)), "Y", "N")
 )
 )
 )
 ),
 ,
 1
 ),
 VSTACK(HSTACK("Dates", TOROW(A2:A5)), HSTACK(_rng, _res))
)

&&&

Leave a Reply