• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Match Mentors to Mentees (With large test data)

Can't pair with mentors 'cause your post #18 attachment has column G empty except for an unique mentor !​
Attach at least a sample with this column filled according to your real need …​

How fast ? As my way could be fast …​
Regarding column G, my original ideas are to show the no. of Mentees for specifically for each Mentors. For example, Mentor A and B may have 8 and 5 mentees respectively. For the sample data, it is actually like filling all cells in column G with "10" of the #18 attachment (each mentor will have 10 mentees).

For 1500 mentees with 100 mentors, your way is less than 35 seconds (Super super fast), while vletm's file takes around 3 mins.
 
Last edited by a moderator:
the #18 attachment (each mentor will have 10 mentees) […] your way is less than 35 seconds
According to post #18 attachment the below one shot Excel basics VBA demonstration​
requiring at the first run less than seven seconds on an old slow laptop​
and by default a mentor without any mentees # has the same # than cell G3 …​
For good enough readers only so well follow the directions this time :​
• first delete Module1 as the VBA procedure is not designed to work within such module;​
paste the VBA procedure only to the top of the result worksheet module;​
• as a reminder 'Processing Sheet' is useless as all temporary data are located in 'Mentors' & result worksheets …​
Code:
Const D = "¤", K = 16
  Dim Rg(1) As Range, V(1)

Sub Check(C%, X)
    Dim W, Y, L&, R&, F&, M&, N&
        W = [{5,6,7}]
        Y = Application.Match(W, X, 0)
        For L = 1 To UBound(W):  Y(L) = IIf(IsError(Y(L)), Cells(W(L)).Address, D):  Next
        Y = Join(Filter(Y, D, False), ",")
    With UsedRange.Rows
        L = .Cells(Rows.Count, 3).End(xlUp)(2).Row:  If L > .Count Then Exit Sub
    For R = L To .Count
           Set Rg(0) = Rg(1)(C).Find(Join(Application.Index(.Item(R), 1, X), D), , xlValues, 1)
        If Not Rg(0) Is Nothing Then
                   F = Rg(0).Row:  M = 0
            Do
               If V(0)(Rg(0).Row, 1) > M Then M = V(0)(Rg(0).Row, 1): N = Rg(0).Row Else If M And V(0)(Rg(0).Row, 1) = M Then Exit Do
                   Set Rg(0) = Rg(1)(C).FindNext(Rg(0))
            Loop Until Rg(0).Row = F
            If M Then
               .Item(R).Columns("C:D") = Rg(1).Parent.Rows(N).Columns("A:B").Value
                If Y > "" Then .Item(R).Range(Y).Font.ColorIndex = K
               .Cells(R, .Columns.Count) = 1
                V(0)(N, 1) = M - 1
            End If
        End If
    Next
       .Item(L & ":" & .Count).Sort .Cells(L, .Columns.Count), 1, Header:=2
    End With
End Sub

Sub Demo1r()
    Dim R&, X, L&, G%, M&
        UsedRange.Clear
    With Sheet1
        R = .Evaluate("IF(ISNUMBER(G3),G3,0)"):  If R < 1 Then Beep: Exit Sub
        Set Rg(1) = .UsedRange.Columns
        Application.ScreenUpdating = False
        Rg(1)("J:M").Formula = Array("=D1&""" & D & """&E1", "=J1&""" & D & """&F1", "=D1&""" & D & """&F1", "=E1&""" & D & """&F1")
        V(0) = .Evaluate(Replace("IF(ISNUMBER(#),#,IF(ISNUMBER(" & Rg(1)(1).Address & ")," & R & ",0))", "#", Rg(1)(7).Address))
    End With
        [A1:H1] = [{"Mentee ID","Mentee Name","Mentor ID","Mentor Name","Gender","Programme","Code"," "}]
    With Sheet2.[A1].CurrentRegion.Rows
        .Range("A3:B" & .Count).Copy [A2]
        .Range("D3:F" & .Count).Copy [E2]
    End With
        Check 11, [{5,6,7}]         ' #1 : Gender & Programme & Code
        Check 13, [{6,7}]           ' #2 : Programme & Code
        Check 10, [{5,6}]           ' #3 : Gender & Programme
        Check 5, [{6}]              ' #4 : Programme
        Check 12, [{5,7}]           ' #5 : Gender & Code
        Rg(1)("J:M").Clear
        Check 6, [{7}]              ' #6 : Code
     V(1) = V(0)                    ' #7 : Gender
        X = Rg(1)(4)
    For R = 3 To UBound(X):  V(1 + (X(R, 1) = "Male"))(R, 1) = 0:  Next
        X = Array(1, 1)
    With UsedRange.Rows
        L = .Cells(Rows.Count, 3).End(xlUp)(2).Row
    For R = L To .Count
             G = 1 + (.Cells(R, 5) = "Female")
        If X(G) Then
                    M = Application.Match(Application.Max(V(G)), V(G), 0)
            If V(G)(M, 1) Then
               .Item(R).Columns("C:D") = Rg(1).Parent.Rows(M).Columns("A:B").Value
               .Item(R).Columns("F:G").Font.ColorIndex = K
               .Cells(R, .Columns.Count) = 1
                V(G)(M, 1) = V(G)(M, 1) - 1
            Else
                X(G) = 0:  If X(1 - G) = 0 Then Exit For
            End If
        End If
    Next
       .Item(L & ":" & .Count).Sort .Cells(L, .Columns.Count), 1, Header:=2
        L = .Cells(Rows.Count, 3).End(xlUp)(2).Row
    If L <= .Count Then             ' #8 : last mentors to last mentees
            .Item(L & ":" & .Count).Columns("E:G").Font.ColorIndex = K
        For R = L To .Count
            M = Application.Match(Application.Max(V(X(1))), V(X(1)), 0)
            If V(X(1))(M, 1) Then V(X(1))(M, 1) = V(X(1))(M, 1) - 1 Else Exit For
           .Item(R).Columns("C:D") = Rg(1).Parent.Rows(M).Columns("A:B").Value
        Next
    End If
       .Columns(.Columns.Count).Clear
    End With
        Application.ScreenUpdating = True
        Erase Rg, V
End Sub
You should Like it !​
 
cheq
Is that Fake data as close as possible to Your real data?
There seems to be some good matches even with Fake data.
What would You do with those about 145 seconds?
 

Attachments

  • Fake data.xlsb
    230.9 KB · Views: 7
According to post #18 attachment the below one shot Excel basics VBA demonstration needs less than seven seconds on an old slow laptop​
and by default a mentor without any mentees # has the same # than cell G3 …​
For good enough readers only so well follow the directions this time :​
• first delete Module1 as the VBA procedure is not designed to work within such module;​
paste the VBA procedure only to the result worksheet module;​
• as a reminder 'Processing Sheet' is useless as all the temporary data are located in 'Mentors' & result worksheets …​
Code:
Sub Demo1r()
  Const D = "¤"
    Dim L&, R&, Rg(1) As Range, V, C&, N&, F&, W, X
        L = 1
        UsedRange.Clear
    With Sheet1
        R = .Evaluate("IF(ISNUMBER(G3),G3,0)"):  If R < 1 Then Beep: Exit Sub
        Application.ScreenUpdating = False
       .Range("J3:K" & .UsedRange.Rows.Count).Formula = Array("=D3&""" & D & """&E3", "=J3&""" & D & """&F3")
        Set Rg(1) = .UsedRange.Columns
        V = .Evaluate(Replace("IF(ISNUMBER(#),#,IF(ISNUMBER(" & Rg(1)(1).Address & ")," & R & ",0))", "#", Rg(1)(7).Address))
    End With
        [J1:P1] = [{"Mentee ID","Mentee Name","Mentor ID","Mentor Name","Programme","Gender","Code"}]
    With Sheet2
        For R = 3 To .[A1].CurrentRegion.Rows.Count
            C = 11:  N = 3
            Set Rg(0) = Rg(1)(C).Find(Join(Application.Index(.Rows(R).Columns("D:F").Value, 1, 0), D), , xlValues)
         If Rg(0) Is Nothing Then
            C = 10:  N = 2
            Set Rg(0) = Rg(1)(C).Find(Join(Application.Index(.Rows(R).Columns("D:E").Value, 1, 0), D))
             If Rg(0) Is Nothing Then
                C = 5:  N = 1
                Set Rg(0) = Rg(1)(C).Find(.Cells(R, C))
             End If
         End If
            If Rg(0) Is Nothing Then
                L = L + 1
                Rows(L).Columns("J:K") = .Rows(R).Columns("A:B").Value
            Else
                    F = Rg(0).Row
                Do
                    L = L + 1
                    Rows(L).Columns("J:K") = .Rows(R).Columns("A:B").Value
                    Rows(L).Columns("L:M") = Rg(1).Parent.Rows(Rg(0).Row).Columns("A:B").Value
                    Cells(L, 14).Resize(, N) = "Matched"
                    Set Rg(0) = Rg(1)(C).FindNext(Rg(0))
                Loop Until Rg(0).Row = F
            End If
        Next
    End With
        Rg(1)("J:K").Clear
        Range("R2:R" & L).Formula = "=COUNTIF(J$2:J$" & L & ",J2)"
    With Sort
        .SortFields.Clear
        .Header = 1
        .MatchCase = False
        .Orientation = 1
        .SetRange Range("J1:R" & L)
        .SortFields.Add Range("P2:P" & L), 0, 1, , 0
        .SortFields.Add Range("O2:O" & L), 0, 1, , 0
        .SortFields.Add Range("N2:N" & L), 0, 1, , 0
        .SortFields.Add Range("R2:R" & L), 0, 1, , 0
        .SortMethod = 1
        .Apply
    End With
    With Application
        For R = 2 To L
               N = Cells(R, 18)
               W = .Match(Cells(R, 12).Resize(N), Rg(1)(1), 0)
            If N = 1 Then
                Cells(R, 17) = True
                If IsNumeric(W) Then If V(W, 1) Then V(W, 1) = V(W, 1) - 1 Else Rows(R).Columns("L:P").ClearContents
            Else
                X = .Index(V, W)
                C = .Match(.Max(X), X, 0)
                F = W(C, 1)
            If V(F, 1) Then
                Cells(R + C - 1, 17) = True
                V(F, 1) = V(F, 1) - 1
            Else
                Cells(R, 17) = True
                Rows(R).Columns("L:P").ClearContents
            End If
                R = R + N - 1
            End If
        Next
            Sort.Apply
            [R2].Formula = "=Q2"
            Range("J1:Q" & L).AdvancedFilter 2, [R1:R2], [A1]
            Columns("J:R").Clear
        If .CountBlank(UsedRange.Columns(3)) Then
            For Each Rg(0) In UsedRange.Columns(3).SpecialCells(4)
                F = .Match(.Max(V), V, 0)
                If V(F, 1) Then V(F, 1) = V(F, 1) - 1 Else Exit For
                Rows(Rg(0).Row).Columns("C:D") = Rg(1).Parent.Rows(F).Columns("A:B").Value
            Next
        End If
           .ScreenUpdating = True
    End With
        Erase Rg
End Sub
You should Like it !​


Unbelievable! I did not believe that it can run in just few seconds. The only problem I encountered so far was the gender logic. (Row 407 & 414 should show gender "matched" in the result sheet). Others look perfect!
 

Attachments

  • Marc L_With Fake Data v2.xlsm
    138 KB · Views: 8
Yes to be fast enough my demonstration just checks for 'Matched'​
• Programme & Gender & Code​
• Programme & Gender​
• Programme​
but not Gender alone as you wrote :​
If fulfilling all three criteria seems impossible, I hope to have at one criteria fulfilled, which is programme.
 
cheq
Is that Fake data as close as possible to Your real data?
There seems to be some good matches even with Fake data.
What would You do with those about 145 seconds?

Ops, I am such as idiot. I left some blank rows in my first few attempts and made it unsuccessful to produce the result. My bad!

Now, I successfully create the result sheets with my real data. May I know what is the difference in terms of logic when I click yes/no to the question "Matches Low > Top"?

I completed running the code in about 3 mins, which is totally good to me!
 
Last edited:
Yes to be fast enough this demonstration just checks for 'Matched'​
• Programme & Gender & Code​
• Programme & Gender​
• Programme​
but not Gender alone as you wrote :​

Just try to be greedy
• Programme & Gender & Code​
• Programme & Gender -> either 2 criteria matched​
• Programme -> either 1 criteria matched​
I can sacrifice the time, and take a longer time to run. Thanks so much!​
 
cheq
Did Your real data work with previous version?
Mentors and Mentoos -sheets data have to start from cell A3.
Headers should be same as in my sample file.
Try to compare those sheets before and after copy&paste.
Without seeing ... others could be pure guesses.
... even top rows screenshot could give some ideas for me.
 
cheq
Did Your real data work with previous version?
Mentors and Mentoos -sheets data have to start from cell A3.
Headers should be same as in my sample file.
Try to compare those sheets before and after copy&paste.
Without seeing ... others could be pure guesses.
... even top rows screenshot could give some ideas for me.

Sorry, totally my bad! I made some silly mistakes. The code works!
I found that the code matching is somehow problematic with my real data. Can it be matched with the exact numbers of the code? I guess it is matched with rough numbers for better efficiency. "For example, 30642 & 30608 are matched in Code criteria"

May I also know what is the difference in terms of logic when I click yes/no to the question "Matches Low > Top"?

Sorry for any inconvenience caused. Million thanks!!

For the real data of my "Code", it can be any no. from 10001 to 40000. (Say, 20283, 30823)

For the real data of my "Programme criteria", here are some of the examples:
A4B067
A4B068
A4B069-GS
A4B075-VA
A4B086-MA
A4B089
A5B057
A5B058
A5B059-MU
A5B060-AK
 
Last edited:
cheq
I use filtering to find matches.
What do You mean about for better efficiency?
... for me the result is more priority that few seconds quicker.
"For example, 30642 & 30608 are matched in Code criteria"
In Your sample - those kind of values seems to belong below Code.
Programme ... seems to have some letters too.
Of course, number 30642 and text 30642 could give different results.
How do You read that those are matched in Code criteria?
Of course, I have not verified the results.

"Matches Low > Top"
#1 part - it solves number of matches per criteria.
#2 part - it can solve matches from the lowest number of matches or from the highest number of matches.
 
cheq
I use filtering to find matches.
What do You mean about for better efficiency?
... for me the result is more priority that few seconds quicker.
"For example, 30642 & 30608 are matched in Code criteria"
In Your sample - those kind of values seems to belong below Code.
Programme ... seems to have some letters too.
Of course, number 30642 and text 30642 could give different results.
How do You read that those are matched in Code criteria?
Of course, I have not verified the results.

"Matches Low > Top"
#1 part - it solves number of matches per criteria.
#2 part - it can solve matches from the lowest number of matches or from the highest number of matches.

I use filtering to find matches.
What do You mean about for better efficiency?

I mean it may just search for the first few letters, (such as 306**), so that the code wont take too long to process.

... for me the result is more priority that few seconds quicker.
"For example, 30642 & 30608 are matched in Code criteria"
In Your sample - those kind of values seems to belong below Code.

Yes, I refer to "Code".

Programme ... seems to have some letters too.

Yes, will be in these two formats. (A4B075 / A5B059-MU)

Of course, number 30642 and text 30642 could give different results.
How do You read that those are matched in Code criteria?

When I look at the result page, I randomly picked a pair with code matched. Then, I manually check the code no. in both mentors and mentees sheets and found the inaccuracy.

Of course, I have not verified the results.


Sorry, I need to go to sleep now. I will get back to you tmr morning! Thanks a lot.
 
cheq
I mean it may just search ... If I 'search' those then I'll search with the whole value.

When I look at the result page ... Do You mean Mentees - Mentors -sheet?
I gotta check some results ... as I've not verified those.
... I checked ... there were mirror-effect.
I wondered ... why do You would like to see so many Code-texts?
... now - there are those common values.
 

Attachments

  • Fake data.xlsb
    232.2 KB · Views: 3
Last edited:
• Programme & Gender -> either 2 criteria matched
No it is both only as 'and' can't be 'or' thus according to your initial explanation.​
Anyway I already have a working prototype just allocating mentors by Gender after Programme only​
but the code does not suit my taste so I must compare with the old thread if I can mix something better as a last try …​
 
The only problem I encountered so far was the gender logic. (Row 407 & 414 should show gender "matched" in the result sheet).
I can sacrifice the time, and take a longer time to run.
Post #27 demonstration updated in order to add only by Gender and without 'sacrificing time' !​
 
Post #27 demonstration updated in order to add only by Gender and without 'sacrificing time' !​

Thank you for the follow-up. It is good enough to add "only by Gender".

It looks perfect with the fake data. Unfortunately, when applying it to my real data, a pop-up of "Error 13_Type mismatch" appeared and some mentees cannot be matched with a mentor.

Update:
For both mentors and mentees source sheets, I checked that they are all "in the General category".

78825

(Some mentor-mentee matached all 3 criteria successfully)
78827

(After I clicked "Enter" for Error 13)
78823
 
Last edited:
cheq
I mean it may just search ... If I 'search' those then I'll search with the whole value.

When I look at the result page ... Do You mean Mentees - Mentors -sheet?
I gotta check some results ... as I've not verified those.
... I checked ... there were mirror-effect.
I wondered ... why do You would like to see so many Code-texts?
... now - there are those common values.

I check that the "Code" should contain values only, so no need to have Code-texts. Your attached file worked properly, except the pairing of 3 criteria matched is fewer than it can be. (just 4 pairs appeared in the fake data.xlsb.

78822
 
Thank you for the follow-up. It is good enough to add "only by Gender".

It looks perfect with the fake data. Unfortunately, when applying it to my real data, a pop-up of "Error 13_Type mismatch" appeared and some mentees cannot be matched with a mentor.

Update:
For both mentors and mentees source sheets, I checked that they are all "in the General category".

View attachment 78825

(Some mentor-mentee matached all 3 criteria successfully)
View attachment 78827

(After I clicked "Enter" for Error 13)
View attachment 78823
.

I figured out the problem. It's caused because column A (Mentee ID) in the mentee list sheet is not in ascending order. The codes work entirely and I am verifying my real data. Heaps thanks!
 
cheq
Your attached file worked properly, except the pairing of 3 criteria matched is fewer than it can be. (just 4 pairs appeared in the fake data.xlsb.
... hmm? There are four 'full matched pairs' with that data. What did You mean?
... and there are still same four after take care 'Weighted' as it's in this version.
Do something need to be some specific order?
 

Attachments

  • Fake data.xlsb
    228 KB · Views: 4
cheq
Did You notice that there could add more criteria as needed?
It would work with same code.
I tested to add one more criteria.
Screenshot 2022-05-09 at 10.35.00.png
... and with some modifications
.... .. there could be possible to select which combination of criteria should use (eg only Code, Gender & Code).
 
cheq
Your attached file worked properly, except the pairing of 3 criteria matched is fewer than it can be. (just 4 pairs appeared in the fake data.xlsb.
... hmm? There are four 'full matched pairs' with that data. What did You mean?

'full matched pairs' refers to mentor-mentee with 3 criteria matched as well (Programme, gender & Code).



... and there are still same four after take care 'Weighted' as it's in this version.
Do something need to be some specific order?


Latest idea:
After I applied the code to my real data, I found that some matching did not go with what I desired. For instance, a mentor matched with a mentee (Because of gender matched), however, it can actually match with another meetee with Programme matched. Thus, sorry for letting me to refine my logic/concept.

Priority for the matching: (As many as matching with 1) & 2) & 3) below is preferred)
1) Programme & Code matched
2) Programme matched
3) Code matched
4) Gender matched
5) Remaining Mentees and Mentors just casually matched

It looks not too important for my real data to have 3 criteria matched as it wasted the quota of certain mentors. Sincerely apologize for the inconvenience caused!!



(Old concept; Please ignore)
For the specific order, I hope to have:

1) 3 criteria matched (Programme & Gender & Code) will be paired first. Thus, some mentors' quota of receiving mentees would be used to match with certain mentees.

2) either 2 criteria matched (Programme & Gender / Programme & Code / Gender & Code)

3) either 1 criteria matched (Programme / Gender / Code)

4) the remaining can be matched casually
 
Last edited:
cheq
Did You notice that there could add more criteria as needed?
It would work with same code.
I tested to add one more criteria.
View attachment 78829
... and with some modifications
.... .. there could be possible to select which combination of criteria should use (eg only Code, Gender & Code).

Wow, I did not notice the function of "add more criteria" actually. I just tried it, which does not actually make the code run longer too.
At this stage, I guess I don't need the option of selecting which combination of criteria should use (eg only Code, Gender & Code) because normally the code should consider all three criteria simultaneously to come up with the matching.
 
cheq
I hoped to get an answer about Your three ... four case.
As well as, do data need to be some specific order that You could get expected results.
About Your the specific orders:
Do those need to be in those orders eg Programme & Gender would give different results than Gender & Programme?
You seems to hope have only those three criteria.
 
cheq
I hoped to get an answer about Your three ... four case.
As well as, do data need to be some specific order that You could get expected results.
About Your the specific orders:
Do those need to be in those orders eg Programme & Gender would give different results than Gender & Programme?
You seems to hope have only those three criteria.

Thanks for helping me considering deeper.

The data "Refer to the source data of mentors & mentees", does not need specific order. I will basically just keep the data in ascending order of the "Employee/Student ID".

Programme & Gender would give different results than Gender & Programme?
From my understanding, it would not give a different value.

My concern is that the following matching could be shown, as the priority is to have as many as 3 criteria matched matching established.
(The following table is partly retrieved from applying Marc L's code with the fake data. (It seemed that 83 pairing is the maximum pairs with the fake data).


Mentee IDMentee NameMentor IDMentor NameProgrammeGenderCode
60001111​
Alleen
13456789​
HandscombMatchedMatchedMatched
60001113​
Harriett
13456791​
DayMatchedMatchedMatched
60001114​
Hewitt
13456792​
DobbsMatchedMatchedMatched
60001115​
Harbert
13456793​
EratMatchedMatchedMatched
60001117​
Ailey
13456795​
SpeekMatchedMatchedMatched
60001118​
Hadlee
13456796​
StainerMatchedMatchedMatched
60001119​
Lukas
13456797​
BrundallMatchedMatchedMatched
60001120​
Raddie
13456798​
MyrickMatchedMatchedMatched
60001121​
Stace
13456799​
HeiblMatchedMatchedMatched
60001123​
Glenna
13456801​
MacQueenMatchedMatchedMatched
60001124​
Tiebold
13456802​
CaselMatchedMatchedMatched
60001126​
Stanford
13456804​
JedrzejewskyMatchedMatchedMatched
60001128​
Joeann
13456817​
KeetonMatchedMatchedMatched
60001130​
Godfrey
13456808​
GyrgorcewicxMatchedMatchedMatched
60001132​
Jessee
13456810​
EgeMatchedMatchedMatched
60001133​
Tiffany
13456811​
OjedaMatchedMatchedMatched
60001134​
Debi
13456812​
KonzelmannMatchedMatchedMatched
60001135​
Carina
13456813​
StrettleMatchedMatchedMatched
60001138​
Moises
13456816​
SaxbyMatchedMatchedMatched
60001139​
Codie
13456817​
KeetonMatchedMatchedMatched
60001140​
Josi
13456818​
DockwraMatchedMatchedMatched
 
Unfortunately, when applying it to my real data, a pop-up of "Error 13_Type mismatch" appeared
This is what may happen when the attachment does not well reflect the real workbook …​
It's caused because column A (Mentee ID) in the mentee list sheet is not in ascending order.
'Cause of the worksheet function VLOOKUP codeline, now solved in post #27, codeline updated, no need an ascending sort anymore …​
 
Back
Top