Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Grow your Fabric skills and prepare for the DP-600 certification exam by completing the latest Microsoft Fabric challenge.

Reply
VeronikaStolfa
Frequent Visitor

How to add additional row with dates in Power Query

Hello all

 

Please be so kind and help me to resolve the issue with adding additional row to Power Query. 

 

I need to add additional row with start date which would be for all articles from date 1.12.2020 and end date will be according to first end date minus 1 day in existing data table. I've already created Custom column with formula {Number.From([Start_date])..Number.From([EndDATE])} because I need to list all days between the periods.

 

Information about products are part of my data set and I would like to keep them, it means that new rows should contain all information.

 

All articles have different start and end dates.

 

Now I have for example this:

Article number

Old price

Start_date

New price

End_date

123456

14.00

1.1.2021

15.00

2.5.2022

 

And this should be the result:

Article number

Old price

Start_date

New price

End_date

123456

14.00

1.12.2020

14.00

31.12.2020

123456

14.00

1.1.2021

15.00

2.5.2022

 

History of price is in different dates, but we need to start from the same date (1.12.2020) and as we don’t know what is the prices before the first known date, we need to set up all first old prices from 1.12.2020.

 

Thank you in advance! 🙂 

1 ACCEPTED SOLUTION

I think I understand what you want, and I believe the following will provide it, based only on the five columns you show.

ronrsnfld_4-1659036409486.png

 

I believe I have commented the code  enough so you can understand it, but ask questions if you have them.

Main Code

 

 

 

let

//edit to reflect your actual data source
    Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{
        {"Article number", Int64.Type}, {"End_date", type date}, {"Old buying price", type number}, 
        {"Start_date", type date}, {"New buying price", type number}}),

//Group by article number
// then run custom function on each subtable
    #"Grouped Rows" = Table.Group(#"Changed Type", {"Article number"}, {
        {"Count", each fnSemiMonthly(_)}}),

//remove unneeded column and expand the subtables, renaming the columns
    #"Removed Columns" = Table.RemoveColumns(#"Grouped Rows",{"Article number"}),
    #"Expanded Count" = Table.ExpandTableColumn(#"Removed Columns", "Count", 
        {"End_date", "Article number", "Old buying price"}, 
        {"Date", "Article number", "Price"}),

//set the data types
    #"Changed Type1" = Table.TransformColumnTypes(#"Expanded Count",{
        {"Date", type date}, {"Article number", Int64.Type}, {"Price", type number}}),

//set desired column order
    #"Reordered Columns" = Table.ReorderColumns(#"Changed Type1",{"Article number", "Date", "Price"})
in
    #"Reordered Columns"

 

 

 

 

Custom Function

 

 

 

//Rename fnSemiMonthly

(tbl as table)=>

let
    Source = tbl,

//create a list (then make it a table) of all dates from 2022.12.01 to the later of Today vs the last date in the table, for the1st and 15th of each month
    #"Semi Monthly Dates" = Table.FromList(List.Generate(
        ()=>[d=#date(2020,12,1)],
        each [d] <= List.Max({List.Max(Source[Start_date]),Date.From(DateTime.LocalNow())}),
        each [d=if Date.Day([d]) = 1 then Date.AddDays([d],14) else Date.StartOfMonth(Date.AddMonths([d],1))],
        each [d]), Splitter.SplitByNothing(), type table[End_date=date]),

//Combine with the original table
    #"Combine with Source" = Table.Combine({#"Semi Monthly Dates",Source}),

//Sort by date
//Then fillup to replace the nulls with the first filled in entry
    #"Sorted Rows" = Table.Sort(#"Combine with Source",{{"End_date", Order.Ascending}}),
    #"Filled" = Table.FillUp(#"Sorted Rows",{"Article number", "Old buying price"}),

//Remove duplicates, then fill down new buying price to
//  replace prices in old price column if needed
    #"Removed Duplicates" = Table.Distinct(#"Filled", {"End_date"}),
    #"Filled Down" = Table.FillDown(#"Removed Duplicates",{"New buying price"}),
    #"Replaced Value" = Table.ReplaceValue(#"Filled Down",null,each [New buying price],Replacer.ReplaceValue,{"Old buying price"}),
    #"Removed Columns" = Table.RemoveColumns(#"Replaced Value",{"Start_date", "New buying price"}),

//Fill down to get last article numbers filled in
    #"Filled Down1" = Table.FillDown(#"Removed Columns",{"Article number"}),

//Remove dates that are not the 1st or 15th
    #"Remove Rows" = Table.SelectRows(#"Filled Down1", each Date.Day([End_date]) = 1 or Date.Day([End_date]) = 15)
in
    #"Remove Rows"

 

 

 

 

Results

Article numberDatePrice

22212/1/20200.359
22212/15/20200.359
2221/1/20210.359
2221/15/20210.359
2222/1/20210.359
2222/15/20210.359
2223/1/20210.359
2223/15/20210.366
2224/1/20210.366
2224/15/20210.366
2225/1/20210.384
2225/15/20210.384
2226/1/20210.384
2226/15/20210.384
2227/1/20210.384
2227/15/20210.384
2228/1/20210.384
2228/15/20210.384
2229/1/20210.384
2229/15/20210.384
22210/1/20210.384
22210/15/20210.384
22211/1/20210.384
22211/15/20210.384
22212/1/20210.384
22212/15/20210.384
2221/1/20220.422
2221/15/20220.422
2222/1/20220.422
2222/15/20220.422
2223/1/20220.422
2223/15/20220.422
2224/1/20220.422
2224/15/20220.422
2225/1/20220.422
2225/15/20220.422
2226/1/20220.422
2226/15/20220.422
2227/1/20220.422
2227/15/20220.422
11112/1/20200.95
11112/15/20200.95
1111/1/20210.95
1111/15/20210.95
1112/1/20210.95
1112/15/20210.95
1113/1/20210.95
1113/15/20210.95
1114/1/20210.95
1114/15/20210.95
1115/1/20210.95
1115/15/20210.95
1116/1/20210.95
1116/15/20210.95
1117/1/20210.95
1117/15/20210.95
1118/1/20210.95
1118/15/20210.95
1119/1/20210.95
1119/15/20210.95
11110/1/20210.95
11110/15/20210.95
11111/1/20210.95
11111/15/20210.95
11112/1/20210.95
11112/15/20210.95
1111/1/20220.95
1111/15/20220.95
1112/1/20220.95
1112/15/20220.95
1113/1/20220.95
1113/15/20220.95
1114/1/20220.95
1114/15/20220.95
1115/1/20220.95
1115/15/20220.95
1116/1/20220.95
1116/15/20220.95
1117/1/20220.99
1117/15/20220.99
1118/1/20220.99
1118/15/20220.99
1119/1/20220.99

View solution in original post

11 REPLIES 11
VeronikaStolfa
Frequent Visitor

Hello, I'm sending you example of data on the screen shot below as I was not able to send it as attachment.

 

Capture.PNG

 

INPUT

I chose just few columns as example, which are the most important:

Capture1.PNG

 

OUTPUT

PART 1PART 1

PART2.PNG

PART3.PNG

*if newest price list is after today date, the date and price would be the same. If newest price lists is before actual date - give actual date

 

Every articel should have the start record from 1.12.2020 and price should be added according to oldest price lists. It means, if some articel has oldest price lists from 5.3.2021 - we need to add dates 1.12.2020,15.12.2020,1.1.2021,15.1.2021,1.2.2021,15.2.2021 a 1.3.2021 (always first and 15th day in the month).

 

This is little bit different approach, but this is exactly what I need. 

 

Thank you.

I cannot copy/paste your data sample screenshot. You can either post it as text, or upload the workbook to some sharing site (eg OneDrive; DropBox, etc) and post a link here.

Extract from original data ->

 

POMArticle numberart_novar_notunit_noArticle nameKS/MUEnd_dateOld buying priceStart_dateNew buying pricestatus_articlesubsys_art_namedivisionsuppl_nosuppl_nameDifference price SUMDifference price %
12345_1_111234511xxx12021-01-31112021-02-01121_4_7xxxBF43 MEAT & POULTRY21212xxx1.7110%
123456_1_1212345611xxxxx12021-01-31142021-02-01101_4_7xxxxxBF43 MEAT & POULTRY12345bbb0.910%
1234566_1_112123456611hhhhhh12021-01-319.92021-02-0110.891_4_7hhhhhhBF43 MEAT & POULTRY38031ddd0.9910%
2790120_1_126279012011dddddddd12021-03-3172021-04-0181_3_0ddddddddBF43 MEAT & POULTRY35709bbb00%
2901231_1_127290123111dddddddd12021-04-3072021-05-0181_3_0ddddddddBF18 DAIRY35709ccc00%
3012342_1_128301234211bb12021-05-3172021-06-0181_3_0bbBF18 DAIRY35709ddd00%
3123453_1_129312345311bb12021-08-3172021-09-0181_3_0bbBF18 DAIRY35709xxx00%
3234564_1_130323456411bbbbb12021-08-0272021-08-0381_3_0bbbbbBF18 DAIRY21212bbb00%
3345675_2_131334567521bbb12021-01-2472021-01-2581_3_0bbbBF18 DAIRY12345ccc-665.65-100%
3456786_2_132345678621bbbbbb12021-01-2872021-01-2981_3_0bbbbbbBF18 DAIRY33333ddd00%
3567897_1_133356789711bbbb12022-06-1472022-06-1581_4_2bbbbBF01 WINES33333xxx0.21214%
3679008_1_134367900811bbbbbbbb12022-07-1472022-07-1581_4_2bbbbbbbbBF16 FROZEN FOOD45454bbb00%

 

 

 

 

 

 

Article numberEnd_dateOld buying priceStart_dateNew buying price
2222021-03-040.3592021-03-050.366
2222021-04-300.3662021-05-010.384
2222021-08-250.3842021-08-260.384
2222021-12-310.3842022-01-010.422
2222022-02-080.4222022-02-090.422
1112022-06-300.952022-07-010.99
1112022-08-310.992022-09-010.99

Article numberdateprice
2221.12.20200.359
22215.12.20200.359
2221.1.20210.359
22215.1.20210.359
2221.2.20210.359
22215.2.20210.359
2221.3.20210.359
22215.3.20210.366
2221.4.20210.366
22215.4.20210.366
2221.5.20210.384
22215.5.20210.384
2221.6.20210.384
22215.6.20210.384
2221.7.20210.384
22215.7.20210.384
2221.8.20210.384
22215.8.20210.384
2221.9.20210.384
22215.9.20210.384
2221.10.20210.384
22215.10.20210.384
2221.11.20210.384
22215.11.20210.384
2221.12.20210.384
22215.12.20210.384
2221.1.20220.422
22215.1.20220.422
2221.2.20220.422
22215.2.20220.422
2221.3.20220.422
22215.3.20220.422
2221.4.20220.422
22215.4.20220.422
2221.5.20220.422
22215.5.20220.422
2221.6.20220.422
22215.6.20220.422
2221.7.20220.422
22215.7.20220.422
1111.12.20200.95
11115.12.20200.95
1111.1.20210.95
11115.1.20210.95
1111.2.20210.95
11115.2.20210.95
1111.3.20210.95
11115.3.20210.95
1111.4.20210.95
11115.4.20210.95
1111.5.20210.95
11115.5.20210.95
1111.6.20210.95
11115.6.20210.95
1111.7.20210.95
11115.7.20210.95
1111.8.20210.95
11115.8.20210.95
1111.9.20210.95
11115.9.20210.95
1111.10.20210.95
11115.10.20210.95
1111.11.20210.95
11115.11.20210.95
1111.12.20210.95
11115.12.20210.95
1111.1.20220.95
11115.1.20220.95
1111.2.20220.95
11115.2.20220.95
1111.3.20220.95
11115.3.20220.95
1111.4.20220.95
11115.4.20220.95
1111.5.20220.95
11115.5.20220.95
1111.6.20220.95
11115.6.20220.95
1111.7.20220.99
11115.7.20220.99
1111.8.20220.99
11115.8.20220.99
1111.9.20220.99

In your last two postings, you show article numbers which do not appear in your Extract from Original Data.  How are these being computed from the original data extract?

 

Also, in your penultimate posting, you show multiple lines with the same article number, but this does not occur in either your screenshot or extract of your original data. Please clarify what you are showing.

 

This task is quite different as my very first request as we would like to apply different approach.

Description of my previous tables:

Extract – original data should demonstrate how many different columns we have. Before I sent just example of one article and you sent me back code for one article, but I have no idea how to apply it for thousand of different articles.

 

INPUT – 2 articles which are not part of previous extract. I wanted to demonstrate that for us is important article number, end_date,old buying price, start_date and new buying price. And from this input I created output which is desired for us.

OUTPUT desired result

Description of result – I will demonstrate it on one article 111 for better understanding . We can see that first known price is 0.95 in 2022-06-30.

We need to add date 2020-12-01,2020-12-15,2021-01-01, 2021-01-15,2021-02-01,2021-02-15 .......until date 2022-06-15 as end date ends 2022-06-30 and we need list just first and 15th day in the month as report should show us evolution of prices on the month level (articles can be changed whenever – because of that 1st and 15th day is the best indicator for us) . We need to have start date for every articel from 2020-12-01.

Then we should focus on oldest Start_date, in this example it is 2022-07-01, dates will look like 2022-07-01, 2022-07-15,2022-08-01,2022-08-15.

Another period starts from 2022-09-01, at this point we know that date is after today date and we use just this date 2022-09-01. If this date would be 2022-07-01 – we know that this date is before actual date so give me actual date, dates will look like this – 2022-07-01,2022-07-15 (as today is 2022-07-28)

 

Article number

End_date

Old buying price

Start_date

New buying price

111

2022-06-30

0.95

2022-07-01

0.99

111

2022-08-31

0.99

2022-09-01

0.99

I think I understand what you want, and I believe the following will provide it, based only on the five columns you show.

ronrsnfld_4-1659036409486.png

 

I believe I have commented the code  enough so you can understand it, but ask questions if you have them.

Main Code

 

 

 

let

//edit to reflect your actual data source
    Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{
        {"Article number", Int64.Type}, {"End_date", type date}, {"Old buying price", type number}, 
        {"Start_date", type date}, {"New buying price", type number}}),

//Group by article number
// then run custom function on each subtable
    #"Grouped Rows" = Table.Group(#"Changed Type", {"Article number"}, {
        {"Count", each fnSemiMonthly(_)}}),

//remove unneeded column and expand the subtables, renaming the columns
    #"Removed Columns" = Table.RemoveColumns(#"Grouped Rows",{"Article number"}),
    #"Expanded Count" = Table.ExpandTableColumn(#"Removed Columns", "Count", 
        {"End_date", "Article number", "Old buying price"}, 
        {"Date", "Article number", "Price"}),

//set the data types
    #"Changed Type1" = Table.TransformColumnTypes(#"Expanded Count",{
        {"Date", type date}, {"Article number", Int64.Type}, {"Price", type number}}),

//set desired column order
    #"Reordered Columns" = Table.ReorderColumns(#"Changed Type1",{"Article number", "Date", "Price"})
in
    #"Reordered Columns"

 

 

 

 

Custom Function

 

 

 

//Rename fnSemiMonthly

(tbl as table)=>

let
    Source = tbl,

//create a list (then make it a table) of all dates from 2022.12.01 to the later of Today vs the last date in the table, for the1st and 15th of each month
    #"Semi Monthly Dates" = Table.FromList(List.Generate(
        ()=>[d=#date(2020,12,1)],
        each [d] <= List.Max({List.Max(Source[Start_date]),Date.From(DateTime.LocalNow())}),
        each [d=if Date.Day([d]) = 1 then Date.AddDays([d],14) else Date.StartOfMonth(Date.AddMonths([d],1))],
        each [d]), Splitter.SplitByNothing(), type table[End_date=date]),

//Combine with the original table
    #"Combine with Source" = Table.Combine({#"Semi Monthly Dates",Source}),

//Sort by date
//Then fillup to replace the nulls with the first filled in entry
    #"Sorted Rows" = Table.Sort(#"Combine with Source",{{"End_date", Order.Ascending}}),
    #"Filled" = Table.FillUp(#"Sorted Rows",{"Article number", "Old buying price"}),

//Remove duplicates, then fill down new buying price to
//  replace prices in old price column if needed
    #"Removed Duplicates" = Table.Distinct(#"Filled", {"End_date"}),
    #"Filled Down" = Table.FillDown(#"Removed Duplicates",{"New buying price"}),
    #"Replaced Value" = Table.ReplaceValue(#"Filled Down",null,each [New buying price],Replacer.ReplaceValue,{"Old buying price"}),
    #"Removed Columns" = Table.RemoveColumns(#"Replaced Value",{"Start_date", "New buying price"}),

//Fill down to get last article numbers filled in
    #"Filled Down1" = Table.FillDown(#"Removed Columns",{"Article number"}),

//Remove dates that are not the 1st or 15th
    #"Remove Rows" = Table.SelectRows(#"Filled Down1", each Date.Day([End_date]) = 1 or Date.Day([End_date]) = 15)
in
    #"Remove Rows"

 

 

 

 

Results

Article numberDatePrice

22212/1/20200.359
22212/15/20200.359
2221/1/20210.359
2221/15/20210.359
2222/1/20210.359
2222/15/20210.359
2223/1/20210.359
2223/15/20210.366
2224/1/20210.366
2224/15/20210.366
2225/1/20210.384
2225/15/20210.384
2226/1/20210.384
2226/15/20210.384
2227/1/20210.384
2227/15/20210.384
2228/1/20210.384
2228/15/20210.384
2229/1/20210.384
2229/15/20210.384
22210/1/20210.384
22210/15/20210.384
22211/1/20210.384
22211/15/20210.384
22212/1/20210.384
22212/15/20210.384
2221/1/20220.422
2221/15/20220.422
2222/1/20220.422
2222/15/20220.422
2223/1/20220.422
2223/15/20220.422
2224/1/20220.422
2224/15/20220.422
2225/1/20220.422
2225/15/20220.422
2226/1/20220.422
2226/15/20220.422
2227/1/20220.422
2227/15/20220.422
11112/1/20200.95
11112/15/20200.95
1111/1/20210.95
1111/15/20210.95
1112/1/20210.95
1112/15/20210.95
1113/1/20210.95
1113/15/20210.95
1114/1/20210.95
1114/15/20210.95
1115/1/20210.95
1115/15/20210.95
1116/1/20210.95
1116/15/20210.95
1117/1/20210.95
1117/15/20210.95
1118/1/20210.95
1118/15/20210.95
1119/1/20210.95
1119/15/20210.95
11110/1/20210.95
11110/15/20210.95
11111/1/20210.95
11111/15/20210.95
11112/1/20210.95
11112/15/20210.95
1111/1/20220.95
1111/15/20220.95
1112/1/20220.95
1112/15/20220.95
1113/1/20220.95
1113/15/20220.95
1114/1/20220.95
1114/15/20220.95
1115/1/20220.95
1115/15/20220.95
1116/1/20220.95
1116/15/20220.95
1117/1/20220.99
1117/15/20220.99
1118/1/20220.99
1118/15/20220.99
1119/1/20220.99
ronrsnfld
Super User
Super User

It appears, from your example, that you want the added row end date to be the first Start date -1, that being the case, see the following code:

let
    Source = Table.FromColumns(
        {{123456}, {14}, {#date(2021,1,1)}, {15}, {#date(2022,2,5)}},
        type table[Article number=Int64.Type, Old price=Currency.Type, Start_date=date, New price=Currency.Type, End_date=date]),

//add row with Start Date = 1-dec-2020 and end date = first start_date -1
    #"Add Row" = let 
        artNum = Source[Article number]{0},
        startDt = #date(2020,12,1),
        endDt = Date.AddDays(Source[Start_date]{0}, - 1),
        price = Source[Old price]{0}
    in 
        Table.InsertRows(Source, 0, {[Article number=artNum, Old price=price, Start_date=startDt, New price=price, End_date=endDt]})
in
    #"Add Row"

 

Note my dates are MDY format

 

Original

ronrsnfld_0-1658489120756.png

 

Result

ronrsnfld_1-1658489154476.png

 

 

Hi, thank you for the code. Is there any other option? As I have a lot of columns and articles there and I think it is impossible to write the code for more then 20 thousand of articles. Thank you 🙂

You should be able to just group by article number and then apply the same algorithm to each sub group. Please supply a realistic example either as text or as a downloadable workbook if you need assistance in adapting this. As a side note , in the future, the more realistic your example, the better solutions can be provided.

Helpful resources

Announcements
RTI Forums Carousel3

New forum boards available in Real-Time Intelligence.

Ask questions in Eventhouse and KQL, Eventstream, and Reflex.

MayPowerBICarousel1

Power BI Monthly Update - May 2024

Check out the May 2024 Power BI update to learn about new features.

Top Solution Authors
Top Kudoed Authors