improve xlookup speed (and add date comparison)

whexcelitious

New Member
Joined
Apr 10, 2023
Messages
4
Office Version
  1. 365
Platform
  1. Windows
I constructed an XLOOKUP to find the right rate of a worker from a set of contracts. The rate needs to be added to a list of timesheet records that hold the name of the worker, the contract he worked for, etc. So when every timesheet-row has the right rate, I can construct a pivot that shows the total hours worked and the total value (hours x rate) of that contract in a month-based overview.
However, I struggle finding the right rate... And my current solution (does not include the contract period yet..) is already quite slow (the total list of timesheet records counts about 8000 entries).
Q1: how can I expand the xlookup with taking the contract period into account
Q2: what would be a faster query to get the same result?

contractRate.xlsx
ABCDEF
1workOrderworkerNamecontractStartcontractEndRateTimecode
2w11111John Doe1-1-202230-6-202261A
3w11111John Doe1-1-202230-6-202266P
4w11111John Doe1-1-202231-12-202271A
5w11111John Doe1-1-202231-12-202276P
6w22222John Doe1-1-202230-6-202262A
7w22222John Doe1-1-202230-6-202267P
8w22222John Doe1-1-202231-12-202272A
9w22222John Doe1-1-202231-12-202277P
10w22222Michael Foe1-1-202230-6-202282A
11w22222Michael Foe1-1-202230-6-202287P
12w22222Michael Foe1-1-202231-12-202292A
13w22222Michael Foe1-1-202231-12-202297P
Contracts


This is the timesheet list: the red rate cells show the wrong rate due to the fact that the wrong contract is found.

contractRate.xlsx
ABCDEF
1dateTimecodeworkerNameworkOrder#hoursrate?
21-2-2022AJohn Doew11111161
31-2-2022PJohn Doew11111166
41-7-2022AJohn Doew11111161
51-7-2022PJohn Doew11111166
61-2-2022AJohn Doew22222162
71-2-2022PJohn Doew22222167
81-7-2022AJohn Doew22222162
91-7-2022PJohn Doew22222167
101-2-2022AMichael Foew22222182
111-2-2022PMichael Foew22222187
121-7-2022AMichael Foew22222182
131-7-2022PMichael Foew22222187
Timesheet
Cell Formulas
RangeFormula
F2:F13F2=XLOOKUP(1,(Contracts!F:F=Timesheet!B2)*(Contracts!B:B=Timesheet!C2)*(Contracts!A:A=Timesheet!D2),Contracts!E:E)
Named Ranges
NameRefers ToCells
Contracts!_FilterDatabase=Contracts!$A$1:$F$5F2:F13


any suggestions?
 

Excel Facts

Get help while writing formula
Click the italics "fx" icon to the left of the formula bar to open the Functions Arguments dialog. Help is displayed for each argument.
Hi & welcome to MrExcel.

1st thing is never use whole column references, that is why everything is so slow.
2nd if row 4 on the time sheet had a date in March which rate should be returned 61 or 71?
 
Upvote 0
Hi & welcome to MrExcel.

1st thing is never use whole column references, that is why everything is so slow.
2nd if row 4 on the time sheet had a date in March which rate should be returned 61 or 71?
Thnx Fluff,

To answer the last question first: both values are valid according to the contract, so either answer is ok. The second answer (71) is slightly better because that contract was created later (not visible in this dataset) so a contract with a later enddate replaces a contract that ends earlier.

Your first suggestion is not clear to me: how can I search the entire table of contract without using column references?
 
Upvote 0
You use column references, but not the entire column.
How about
Excel Formula:
=TAKE(FILTER(Contracts!$E$2:$E$10000,(Contracts!$F$2:$F$10000=B2)*(Contracts!$B$2:$B$10000=C2)*(Contracts!$A$2:$A$10000=D2)*(Contracts!$D$2:$D$10000>=A2)),-1)
 
Upvote 0
ah, never knew that A:A and A1:A1000 are different in terms of performance.
You use the TAKE() function which is a new function in O365, right? Although my Excel says it is a 365 version (Microsoft® Excel® for Microsoft 365 MSO (Version 2202 Build 16.0.14931.20646) 64-bit ) it does not know the TAKE function.
Is there another way to choose the last member of the returned array?
 
Upvote 0
You are behind on your updates, try
Excel Formula:
=LET(f,FILTER(Contracts!$E$2:$E$10000,(Contracts!$F$2:$F$10000=B2)*(Contracts!$B$2:$B$10000=C2)*(Contracts!$A$2:$A$10000=D2)*(Contracts!$D$2:$D$10000>=A2)),INDEX(f, ROWS(f)))
 
Upvote 0
Solution
You are behind on your updates, try
Excel Formula:
=LET(f,FILTER(Contracts!$E$2:$E$10000,(Contracts!$F$2:$F$10000=B2)*(Contracts!$B$2:$B$10000=C2)*(Contracts!$A$2:$A$10000=D2)*(Contracts!$D$2:$D$10000>=A2)),INDEX(f, ROWS(f)))
updates are managed by IT department (department of "no"...) so I will keep a lookout for TAKE() function but use your latest proposal instead.
Thanx a lot for that! I even managed to improve it a bit because your code only takes the end date of the contract into account. If e.g. the contracts do not overlap (say: the second contract of John Doe starts after the work date in the timesheet) your code still takes the second contract as valid. In this code the startdate is also added as filter:
Excel Formula:
=LET(f;FILTER(Contracts!$E$2:$E$100;(Contracts!$F$2:$F$100=B2)*(Contracts!$B$2:$B$100=C2)*(Contracts!$A$2:$A$100=D2)*(Contracts!$D$2:$D$100>=A2)*(Contracts!$C$2:$C$100<=A2));INDEX(f; ROWS(f)))

again: thnx a lot for your fast replies and helping me to understand Excel even better!
 
Upvote 0
Glad to help & thanks for the feedback.
 
Upvote 0

Forum statistics

Threads
1,215,307
Messages
6,124,163
Members
449,146
Latest member
el_gazar

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