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

Get Fabric Certified for FREE during Fabric Data Days. Don't miss your chance! Request now

Reply
ScottA
Frequent Visitor

Looping / Custom Function Question

I have a table of employees that need to complete a course. There are two different ranks of employees, “C” and “F”. They must each complete the course in the window between their ‘target date’ and ‘expiry date’. The list is ordered in ascending order based on expiry date i.e. those who expire soonest are the top priority to complete the course.

 

Employee Table

Employee #RankTarget DateExpiry Date
1C13/01/202210/03/2022
2C18/01/202215/03/2022
3C18/01/202215/03/2022
4C18/01/202215/03/2022
5F18/01/202215/03/2022
6F18/01/202215/03/2022
7C18/01/202215/03/2022
8F1/02/202229/03/2022
9C15/02/202212/04/2022
10F4/03/202229/04/2022
11F5/03/202230/04/2022
12F15/03/202210/05/2022
13C14/04/20229/06/2022
14C11/05/20226/07/2022
15F15/05/202210/07/2022
16C9/06/20224/08/2022

Separately I have a table of the planned course dates, and the capacity on that course for each rank (“C” and “F”).

 

Course Table

CourseC capacityF capacity
19/01/202232
16/02/202232
16/03/202232
13/04/202232
11/05/202232
8/06/202232

 

 

What I would like to do is loop through the table of employees, and assign course dates to employees from the possible options in the course table. The course assigned must sit within the target to expiry window, and we cannot exceed the capacity on any given course. To do this I imagine we need to (re)calculate assigned vs capacity at each step to determine if there are any more people we can put on the course, or we need to move to the next date.

 

For example;

Employees 1, 2, and 3 (all of rank “C”) can go on the 19/01/22 course. Employee 4 however needs to go on the 16/02/22 course, as the 19/01/22 course is now full for rank “C” (though can still be utilised for “F” employees), etc etc etc.

 

The output I would like is a column with courses assigned. There needs to be some redundancy built in if there are no possible options (as in the case of employee 16). I would like to achieve this with M language (power query), not DAX.

 

I think this can be achieved and have watched some videos on looping and custom functions but cannot think how to apply it in this sense. Very much appreciate any help.

 

Cheers

Ideal Output

Employee #RankTarget DateExpiry Date**Output
1C13/01/202210/03/202219-Jan
2C18/01/202215/03/202219-Jan
3C18/01/202215/03/202219-Jan
4C18/01/202215/03/202216-Feb
5F18/01/202215/03/202219-Jan
6F18/01/202215/03/202219-Jan
7C18/01/202215/03/202216-Feb
8F1/02/202229/03/202216-Feb
9C15/02/202212/04/202216-Feb
10F4/03/202229/04/202216-Mar
11F5/03/202230/04/202216-Mar
12F15/03/202210/05/202213-Apr
13C14/04/20229/06/202211-May
14C11/05/20226/07/202211-May
15F15/05/202210/07/20228-Jun
16C9/06/20224/08/2022-
1 ACCEPTED SOLUTION
mahoneypat
Microsoft Employee
Microsoft Employee

This is a challenging one. I didn't have time to finish it, but the attached pbix shows one way to approach this with List.Accumulate. It iterates over the list of Course dates and generates the first X Employees for which the Course date is between the Target and Expiry dates. Those Employees are removed from the list and the remaining employees are passed to the next iteration, and so on. This generates the list of "C" employees and you could adapt same approach for the "F" employees. From there you can merge the Employee table with this resulting table to get your desired result.

 

Note that Employee 16 didn't have a fit for any of the Course dates. Also, this approach is not very performant, so it would be slow if your tables are large.

 

Pat

 





Did I answer your question? Mark my post as a solution! Kudos are also appreciated!

To learn more about Power BI, follow me on Twitter or subscribe on YouTube.


@mahoneypa HoosierBI on YouTube


View solution in original post

3 REPLIES 3
mahoneypat
Microsoft Employee
Microsoft Employee

This is a challenging one. I didn't have time to finish it, but the attached pbix shows one way to approach this with List.Accumulate. It iterates over the list of Course dates and generates the first X Employees for which the Course date is between the Target and Expiry dates. Those Employees are removed from the list and the remaining employees are passed to the next iteration, and so on. This generates the list of "C" employees and you could adapt same approach for the "F" employees. From there you can merge the Employee table with this resulting table to get your desired result.

 

Note that Employee 16 didn't have a fit for any of the Course dates. Also, this approach is not very performant, so it would be slow if your tables are large.

 

Pat

 





Did I answer your question? Mark my post as a solution! Kudos are also appreciated!

To learn more about Power BI, follow me on Twitter or subscribe on YouTube.


@mahoneypa HoosierBI on YouTube


Hi @mahoneypat ,

 

Thanks very much for the time you put in to this. My delay in response has been trying to figure out a) what you have done and b) how to make it faster.

 

When transcribing the solution code to my real data I ran into a severe performance problem. The query just spun and sucked up CPU to the point after waiting 90 minutes it had only loaded 10 rows and I never could wait long enough to actually see the solution load. 

 

In the real world I have ~150 employees of each rank, and 18 months worth of courses averaging about 1.5 courses per week. So definitely larger than the example, but actually not very large in the scheme of things. 

 

By adding in extra buffers (Table.Buffer, List.Buffer) and then using them at each step I have solved this issue and its now very quick. The additions I have made to your code are shown below in yellow.

 

Thanks Again

 

ScottA_0-1642455826329.png

 

 

Glad you got it working faster. I had also tried it with List.Generate and it was similarly slow. I tested your change on my end. All I had to do was buffer the emp2 table, and it was already very quick. That makes sense, since it is the emp2 table that references the other query (i.e., I should have thought to do that).

 

Now you could improve the code further to accept a Rank value as a parameter too, so it would work for any course (and the code could be streamlined/formatted to look better).

 

Pat





Did I answer your question? Mark my post as a solution! Kudos are also appreciated!

To learn more about Power BI, follow me on Twitter or subscribe on YouTube.


@mahoneypa HoosierBI on YouTube


Helpful resources

Announcements
Fabric Data Days Carousel

Fabric Data Days

Advance your Data & AI career with 50 days of live learning, contests, hands-on challenges, study groups & certifications and more!

October Power BI Update Carousel

Power BI Monthly Update - October 2025

Check out the October 2025 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Kudoed Authors