Forum Discussion

Laurent500's avatar
Laurent500
Copper Contributor
Aug 18, 2022
Solved

Power Query | Create Column out of two dates

I have differents projects and each has budget, a start date and an end date.   The mission is to create month columns with the respective month name (or number) and distribute the budget on theses...
  • Lorenzo's avatar
    Aug 18, 2022

    Laurent500 

    The real challenge in your scenario is to calc. the #Months between [Start Date] and [End Date] as PQ currently doesn't have a function like Duration.Months or an equivalent to Excel/Dax https://docs.microsoft.com/en-us/dax/datediff-function-dax. I'm not aware of a perfect solution to this (One on the Net "claims" he figured it out but there are situations where his function doesn't return the correct #Months) ==> In the below query adjust AvgDaysPerMonth at your convenience

     

    With https://docs.microsoft.com/en-us/powerquery-m/list-accumulate in attached sample:

     

    (can be shortened)

    let
        Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
        ChangedTypes = Table.TransformColumnTypes(Source,
            {{"Project", type any}, {"Budget", type number}, {"Start Date", type date}, {"End Date", type date}}
        ),
        AvgDaysPerMonth = 365/12,
        CalcMonths = Table.AddColumn(ChangedTypes, "Months", each
            Number.RoundUp(
                (Duration.Days(Date.EndOfMonth([End Date]) - Date.StartOfMonth([Start Date])) +1) / AvgDaysPerMonth,
                0
            ), Int64.Type
        ),
        MaxMonths = List.Max(CalcMonths[Months]),
        EarliestStart = Date.StartOfMonth(List.Min(CalcMonths[Start Date])),
        MonthsList = List.Transform({0..MaxMonths}, each Date.AddMonths(EarliestStart, _)),
        AddedMonths = List.Accumulate(MonthsList, CalcMonths,
            (accum,current) as table => Table.AddColumn(accum, Date.ToText(current,"MMM yyyy"), each
                if (Date.StartOfMonth([Start Date]) <= current) and ([End Date] >= current)
                then [Budget] / [Months]
                else null,
                type nullable number
            )
        ),
        RemovedMonths = Table.RemoveColumns(AddedMonths,{"Months"})
    in
        RemovedMonths

     

     

Resources