PQ question - dynamically adding rows if a person has not completed training

scott_86_

New Member
Joined
Sep 27, 2018
Messages
44
Office Version
  1. 365
Platform
  1. Windows
Hi,

In the screen shot below (sorry, I am unable to input a mini sheet due to organisational restrictions), I have tbl_training, tbl_report and tbl_outcome.

tbl_training has a list of training items that all employees are required to complete.

tbl_report has a report of training that employees have completed with a completion date, however, does not have a row for the items in tbl_training that they have not completed.

tbl_outcome is an example of the outcome I am trying to achieve so that all employees also have an additional row(s) row for the items in tbl_training they have not completed with the Date Completed column being left as null.

Would anyone be able to assist in some applied steps to take to achieve this? Thank you.

1734908668249.png
 
Last edited:

Excel Facts

Can you AutoAverage in Excel?
There is a drop-down next to the AutoSum symbol. Open the drop-down to choose AVERAGE, COUNT, MAX, or MIN
Since you have not uploaded a file, I can only suggest a solution as I will not attempt to recreate your tables. I would suggest you do an anti join to find the missing training. Once this is completed, then join the original table back to the new anti join. If you want a demo, then post your sample files to a third party location or use XL2BB here. Pictures cannot be manipulated.
 
Upvote 0
I like transforming data on the fly, so this would be my approach:

Power Query:
let
    tblTraining = Excel.CurrentWorkbook(){[Name="tbl_training"]}[Content],
    tblReport = Excel.CurrentWorkbook(){[Name="tbl_report"]}[Content],

    GroupByEmployee = Table.Group(tblReport, {"Employee"}, {{"Data", each _}}),
    AddMissingTrainings = Table.TransformColumns(GroupByEmployee, {"Data",
    each
        let
            Existing = _[Training],
            Missing = List.Difference(tblTraining[Training], Existing),
            AddMissing = Table.InsertRows(_, Table.RowCount(_), List.Transform(Missing, each [Training=_ , Employee ID = null, Employee = null, Date Completed = null, Role = null])),
            Result = Table.FillDown(AddMissing,{"Employee ID", "Employee", "Role"})
        in
            Result
        }),
    RestoreTable = Table.ExpandTableColumn(AddMissingTrainings, "Data", {"Training", "Employee ID", "Date Completed", "Role"}),
    Result = Table.ReorderColumns(RestoreTable,{"Training", "Employee ID", "Employee", "Date Completed", "Role"})
   
in
    Result

Training
AA
BB
CC
DD
TrainingEmployee IDEmployeeDate CompletedRole
AA111Colin1/1/2023IT
AA222Ricky1/2/2023Admin
BB222Ricky1/3/2023Admin
AA333Michael1/4/2023IT
BB333Michael1/5/2023IT
CC333Michael1/6/2023IT
AA444Jane1/7/2023Admin
BB444Jane1/8/2023Admin
CC444Jane1/9/2023Admin
DD444Jane1/10/2023Admin
TrainingEmployee IDEmployeeDate CompletedRole
AA111Colin1/1/2023IT
BB111ColinIT
CC111ColinIT
DD111ColinIT
AA222Ricky1/2/2023Admin
BB222Ricky1/3/2023Admin
CC222RickyAdmin
DD222RickyAdmin
AA333Michael1/4/2023IT
BB333Michael1/5/2023IT
CC333Michael1/6/2023IT
DD333MichaelIT
AA444Jane1/7/2023Admin
BB444Jane1/8/2023Admin
CC444Jane1/9/2023Admin
DD444Jane1/10/2023Admin
 
Last edited:
Upvote 0
Since you have not uploaded a file, I can only suggest a solution as I will not attempt to recreate your tables. I would suggest you do an anti join to find the missing training. Once this is completed, then join the original table back to the new anti join. If you want a demo, then post your sample files to a third party location or use XL2BB here. Pictures cannot be manipulated.

Hi, I think I have figured out using XLB22. Please see below.

Looking forward to learning more about anti join (first time I have heard of it was in your post!)


Book1
ABCDEF
1Table Name = tbl_training
2TrainingTraining ID
3AAAA11
4BBBB22
5CCCC33
6DDDD44
7
8
9Table Name = tbl_report
10TrainingTraining IDEmployee IDEmployeeDate CompletedRole
11AAAA11111Colin01/01/2023IT
12AAAA11222Ricky01/02/2023Admin
13BBBB22222Ricky01/03/2023Admin
14AAAA11333Michael01/04/2023IT
15BBBB22333Michael01/05/2023IT
16CCCC33333Michael01/06/2023IT
17AAAA11444Jane01/07/2023Admin
18BBBB22444Jane01/08/2023Admin
19CCCC33444Jane01/09/2023Admin
20DDDD44444Jane01/10/2023Admin
Sheet2
 
Upvote 0
Power Query:
let
    tr_list = List.Buffer(tbl_training[Training]), 
    report = Table.Group(
        tbl_report, 
        "Employee ID", 
        {"x", (x) => x & #table({"Training"}, List.Zip({List.RemoveItems(tr_list, x[Training])}))}
    ), 
    result = Table.FillDown(Table.Combine(report[x]), List.RemoveItems(Table.ColumnNames(tbl_report), {"Date Completed"}))
in
    result
 
Upvote 0
Solution
Power Query:
let
    tr_list = List.Buffer(tbl_training[Training]),
    report = Table.Group(
        tbl_report,
        "Employee ID",
        {"x", (x) => x & #table({"Training"}, List.Zip({List.RemoveItems(tr_list, x[Training])}))}
    ),
    result = Table.FillDown(Table.Combine(report[x]), List.RemoveItems(Table.ColumnNames(tbl_report), {"Date Completed"}))
in
    result
Beautiful! Thanks for sharing. I now learned that I can apply the transformation with the Table.Group function instead of an extra Table.TransformColumns step!
 
Upvote 0
Power Query:
let
    tr_list = List.Buffer(tbl_training[Training]),
    report = Table.Group(
        tbl_report,
        "Employee ID",
        {"x", (x) => x & #table({"Training"}, List.Zip({List.RemoveItems(tr_list, x[Training])}))}
    ),
    result = Table.FillDown(Table.Combine(report[x]), List.RemoveItems(Table.ColumnNames(tbl_report), {"Date Completed"}))
in
    result

Hi AlienSx,

Thanks very much for that. I just replied to your post a few minutes ago asking a question on specifically how to apply the code within the advanced editor; however, I worked it out so am now editing my post. 👍
 
Last edited:
Upvote 0
Power Query:
let
    tr_list = List.Buffer(tbl_training[Training]),
    report = Table.Group(
        tbl_report,
        "Employee ID",
        {"x", (x) => x & #table({"Training"}, List.Zip({List.RemoveItems(tr_list, x[Training])}))}
    ),
    result = Table.FillDown(Table.Combine(report[x]), List.RemoveItems(Table.ColumnNames(tbl_report), {"Date Completed"}))
in
    result

Hi AlienSx.

Furthermore to my above post confirming this works, would it be possible to also reference the below tbl_employees table to include employees who have not completed any of the tbl_training items within tbl_report?

So in this case the result would include 8 extra rows for the 2 people people who have not completed any training at all. 4 for Eddie and 4 for Clare - with a null value in the Date Completed column.



Book2
ABC
9Table Name = tbl_employees
10Employee IDEmployeeEmployee Type
11111ColinFull-time
12222RickyFull-time
13333MichaelFull-time
14444JaneFull-time
15555EddieCasual
16666ClareCasual
Sheet1
 
Upvote 0

Forum statistics

Threads
1,224,847
Messages
6,181,331
Members
453,032
Latest member
Pauh

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top