Pick multiple values from list and ignore empty cells - excel

I have the following Excel spreadsheet:
A B C D E F G
1 USER1 USER2 MICHAEL SANDRA JAMES CAITLIN
2 Product A Michael James Michael James
3 Product B Sandra Caitlin Sandra Caitlin
4 Product C James Caitlin James Caitlin
5 Product D Michael Sandra Michael Sandra
In Columns D:G 4 users of a product are listed. If a product is used by a User his/her name appears in Cells D2:G5. If he/she does not use the product the cell remains empty.
In Columns B:C I want to achieve now that the emtpy cells are eliminated and the maximum 2 Users are listed.
Do you know any formula that can go through the Cells D2:G5 to pick the 2 Users and show them in Columns B:C?

I don't know of any quick formula that you can use.
You are probably best off using VBA. You could write something compact and concise in there. VBA is definitely the way to go if your matrix is going to grow in size.
However, if you insist on doing it in Excel with available formulas, AND the matrix remains relatively small, here is one way to do it:
You will need column H and I for "Mask" information. You can hide these columns in the finished worksheet.
A B C D E F G H I
1 USER1 USER2 MICHAEL SANDRA JAMES CAITLIN MASK1 MASK2
2 Product A Michael James Michael James 1010 10
3 Product B Sandra Caitlin Sandra Caitlin 101 1
4 Product C James Caitlin James Caitlin 11 1
5 Product D Michael Sandra Michael Sandra 1100 100
In cell H2, You can create the first Mask:
=IF(D2 <> "",1000,0)+IF(E2 <> "",100,0)+IF(F2 <> "",10,0)+IF(G2 <> "",1,0)
This is a positional Mask which puts a 1 in each numeral column where data exists.
In cell B2 for USER1, you can put the nested IF formula:
=IF(H2>=1000,D2,IF(H2>=100,E2,IF(H2>=10,F2,IF(H2>=1,G2,""))))
This uses the Mask to find the first occurrence of data and place it in the USER1 column.
Finding the second user is a little more tricky. But all we have to do is create a second Mask in column I. In cell I2 you can use this formula:
=IF(LEN(TEXT(H2,0))>1,VALUE(RIGHT(TEXT(H2,0),LEN(TEXT(H2,0))-1)),0)
Let me break that formula down for you. We want to convert the first Mask in H2 to text so that we can trim off the first character (which corresponds to USER1) because, we don't need USER1 data anymore. Using TEXT(H2,0)
=IF(LEN(TEXT(H2,0))>1,VALUE(RIGHT(TEXT(H2,0),LEN(TEXT(H2,0))-1)),0)
^^^^^^^^^^
But to do a right trim that removes the right most character, we need the length of the same text string minus 1. LEN(TEXT(H2,0))-1
=IF(LEN(TEXT(H2,0))>1,VALUE(RIGHT(TEXT(H2,0),LEN(TEXT(H2,0))-1)),0)
^^^^^^^^^^^^^^^^^
Using those in a RIGHT function gives us our new Mask which removes USER1.
=IF(LEN(TEXT(H2,0))>1,VALUE(RIGHT(TEXT(H2,0),LEN(TEXT(H2,0))-1)),0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
But we can't do math on a text string, so we have to convert it back to a number using the Value function.
=IF(LEN(TEXT(H2,0))>1,VALUE(RIGHT(TEXT(H2,0),LEN(TEXT(H2,0))-1)),0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
That's our new Second Mask that we can use to find USER2. However, we need to test for error values as well. If all the cells are blank, it will have an error since you can't have a length of 0 in a Right function. So we need to test if the length of the text is greater than 1. LEN(TEXT(H2,0))>1
=IF(LEN(TEXT(H2,0))>1,VALUE(RIGHT(TEXT(H2,0),LEN(TEXT(H2,0))-1)),0)
^^^^^^^^^^^^^^^^^
Encase that all in an If statement and you now have your new Mask for USER2.
Now it's a simple nested IF formula for cell C2 by using the Mask in cell I2:
=IF(I2>=100,E2,IF(I2>=10,F2,IF(I2>=1,G2,"")))
We were able the toss out the test for 1000 since we know that would have been caught for USER1.
Now just copy the cells B2, C2, H2, and I2 down three more rows and all of your data will appear.
You can hide columns H and I if you'd like.
So, all in all, it's not that difficult (if your matrix remains small). There are only 4 formulas needed to make this work. And they are only of moderate complexity.
But once again, if your matrix is eventually going to grow in size, it will definitely be better to write this all in VBA.
Hope this helped. :)

It is possible without a formula though might be a bit tedious without VBA or similar (though not tagged that way):
Insert enough extra columns between C and D to be able to copy all of D:G into C.
Copy what was D:G into C and move what was the content of D:G out of the way (to other rows or other sheet/book).
Select the populated rows in C:F (or equivalent), HOME > Editing > Find & Select, Go To Special..., Blanks (only) OK.
Right click one of the selected cells and Delete..., Shift Cells left, OK.
Copy what was D:G back to E2.
The chosen two will be those furthest to the left.

Related

Distributing students across classes based on marks

Name
Marks
Rank
Class
Eddie
20
6
C
Tom
10
10
A
Jenny
30
4
A
Riva
40
3
C
Andy
50
2
B
Mark
5
11
B
Sally
78
1
A
Jack
15
8
B
Dick
15
8
C
Harry
20
6
A
Dom
30
4
B
The students are expected to be distributed across classes A, B and C, based on their marks in the above picture.
The student with the highest marks goes in A. The one with the next highest goes in B. The next highest goes in C. The next goes again to A and so on.
What should be the formula to be used in Excel 2013 and above for calculating the Class?
Sort the table by either Marks descending or Rank ascending.
D2: =CHOOSE(MOD(ROWS($1:1)-1,3)+1,"A","B","C")
If you are using Excel 365, you can use the SORTBY function to solve the question.
Assume the Name column is in a named range called List_Name, the Marks column is in a named range called List_Marks, your example dataset is in range A1:D12, and you want to return the class code in column D.
In cell D2, enter any one of the following formulas and drag it down:
=CHOOSE(MOD(MATCH(A2,SORTBY(List_Name,List_Marks,-1),0),3)+1,"C","A","B")
Alternatively, you can use the following in cell D2 instead:
=INDEX({"C";"A";"B"},MOD(MATCH(A2,SORTBY(List_Name,List_Marks,-1),0),3)+1)
If you cannot use the SORTBY function, then the answer provided by Ron Rosenfeld should do the job quite well.
Let me know if you have any questions.
Assuming that the chart you provided is in cells A1-D11
Try making a 2x3 chart on the side (I’m using F2-G4 with 1...A 2...B 0...C
and then put the formula in D1 as follows: =vlookup(mod(C2,3),F2:G4, false)
You could even skip out the whole C column if you wanted, writing =vlookup(mod(rank(A2,B:B),3),F2:G4, false)
But then you might have an issue of 2 people going to the same class if they rank the same.

Lookup Function Excel

I am working on a lookup function and I cant seem to make it work. I am looking up a value from one worksheet into another. The issue I am having is that some names in the excel sheet iI am looking up are not spaced at the same as the other sheet.
For example instead of John Davis, the lookup sheet might have the name as JohnDavis. Or Peter Lee Thomas might be Peter LeeThomas. So my looking function is failing because of this.
=IF(B2="AD Non Chargeable","Internal",INDEX(Sheet3!B:B,MATCH('Raw Data'!B2,Sheet3!A:A,0)))
Can you please advice on the best way around this? My Lookup sheet is Sheet3
Okay, if for example your data looked like this:
A B C D
Some Text 1 2 SomeText3
Som e Text 2 3 Some Text 2
So meText 3 4 SomeTex t1
Lookup formula in column D would be:
=INDEX($B$1:$B$3,MATCH(SUBSTITUTE(C1," ",""),SUBSTITUTE($A$1:$A$3," ",""),0))
Make sure to apply this formula with Ctrl + Shift + Enter.
The result will look as expected:
A B C D
Some Text 1 2 SomeText3 4
Som e Text 2 3 Some Text 2 3
So meText 3 4 SomeTex t1 2
One solution would be to create another column Sheet3, in this example B, to remove all spaces, like this:
In cell B2 (and copied down): =substitute(A2,"","")
Then alter your lookup to alter its data similarly and to search in this space eliminated row B:
=IF(B2="AD Non Chargeable","Internal",INDEX(Sheet3!B:B,MATCH(substitute('Raw Data'!B2," ",""),Sheet3!A:A,0)))

Sumproduct matching values in excel

I have two excel tables:
A B C D E
1 John 10 Mark 2
2 Tommy 20 Tommy 3
3 Jane 15 John 4
4 Kate 2
5 Jane 1
Is there a function to sumproduct values in colum B with those values in column E which match by name, i.e. 10*4 + 20*3 + 15*1 ?
You can use sumif for this and just sum up the results when you are done:
=B1 * sumif(D:D, A1, E:E)
Copy that down your sheet, and then add up the totals.
If you don't want a ton of formulas hanging out on your sheet, you could convert this to a CSE/Array formula:
=SUM($B$1:$B$3*SUMIF(D:D, $A$1:$A$3,E:E ))
Just enter that in and hit Ctrl+Shift+Enter to enter it. It will get curly braces around it, which means it's an Array formula.
Since you asked about sumproduct, we could use SUMPRODUCT
=SUMPRODUCT(($A$1:$A$5=A1)*$B$1:$B$5)*SUMPRODUCT(($D$1:$D$5=A1)*$E$1:$E$5)
Now that is assuming there are no repeats (all names are unique). In the event that names are not unique you will have those numbers added together then multiplied.
After you apply that to a column and copied down appropriately, lets say F1 to F3, in F5 you could get your final answer using:
=SUM(F1:F3)

Excel Column Sorting

Im using Excel 2010... This problem has been plaguing me for hours and would save me a lot of time, I have really tried searching for the answer but dont know what I am looking for without explaining in detail.
Basically I have 5 columns of data. Column A contains a list of selected names, Column B contains a list of all names and Columns C to E contain data relating to all names:
A B C D E
steve adam 54 london car
doug andrew 25 essex walk
adam bert 31 newcastle walk
omar barry 47 london car
chuck 23 herts cycle
(columns continue)
I need to be able to sort the data so that the names in column A are in order and the other data in columns B to E match what is in column A with any non matches at the bottom of each list. So the result would look like:
A B C D E
adam adam 54 london car
doug doug 37 norfolk walk
omar omar 31 dudley jog
steve steve 74 london cycle
andrew 25 essex walk
(columns continue)
In real terms I have a list of thousands of names and need to match hundreds of names to them. If any one can help with this it would save me hours of work. I have tried searching and have watched many youtube vids on vlookup but nothing seems to be specific to what im after.
Thanks in advance
George
Excel might not be the best tool for the job but try this:
Order column A by itself
In cell F1, use this formula: =IFERROR(VLOOKUP(B1, A$1:A$4,1,FALSE), CHAR(142)). Replace the "4" in A$4 with the number of your last row of data (in both columns A and B).
Copy that down column F to the last row of data. You will see a Ž in rows where there isn't a match between A and B.
Select the data in columns B to F (leave A out) and sort using columns F as the first level and B as the second level (a single sort operation).
The data in A and B should align with the extra rows in B at the end.
If it doesn't align it means you have values in A that are not in B. Select the values in F, copy and paste special (values only) over the values in A. Delete all the Žs from the end.
Delete column F

Return value of last match

I need a formula to return the value of Data for the last match of "Text". Row number is also acceptable. Macro is NOT acceptable. Name column is unsorted and cannot be sorted!
Only column "Name" is used as lookup value. I would rather use a/multiple helper column(s) instead of an array formula.
Row Name Data
1 Joe 10
2 Tom 20
3 Eva 30
4 Adam 40
5 Tom 21
LARGE only works with numbers, and VLOOKUP only returns the first match. LOOKUP only works sometimes, so its out too.
So if I wanted the last match for "Tom" then it should return "21".
Array formulas could be avoided with a helper column.
Suppose to have in F1 the name to match (i.e. Tom)
In the helper column row C2 enter
=IF(A2<>$F$1,0,row())
Then copy the formulas along your data.
Now the column C contains 0 for the unmatched names and the row number for the matched ones. Maxing the column yield the row of the solution.
Now the result is simple a matter of using the correct offset with the function offset:
=OFFSET(B1,max(C:C)-1,0)
PS: my copy of excel is in italian, so I can't test this english translaction of the formulas.
I think it's the easiest way to make it.
=LOOKUP("Tom";A2:B7)
Create a column with an array formula (enter it with Ctrl+Shift+Enter):
=VLOOKUP(MAX(IF($B$2:$B$6=B2, $A$2:A$6, 0)), $A$2:$C$6, 3, FALSE)
To make sure you did it right, click on the cell, and the formula should be shown encased in curly brackets ({}).
Note: This assumes that "Row" is in A1.
I have come up with a solution, but it requires that numbers in Data are concurrent, like so
Name Data
Joe 1
Tom 1
Eva 1
Adam 1
Tom 2
Tom 3
Eva 2
But thats okay, since that my data looks like that anyway. So if Name is used before then it must be the old highest +1 aka concurrent.
Name is A1 and Data is B1, and this formula goes into C2:
FLOOR(SQRT(2*SUMIF(A2:A7,A2,B2:B7)),1)

Resources