Excel coding gurus, i'd like someone to land me a hand in a following problem:
What I have:
I have an Excel 2019. Not the 365 edition.
And I have an Excel table with 2 columns. Column I contains list of people. And each person in the I column has the country of his/her origin denoted in the correspondent cell of H column.
For a better view check this picture, plz.
And I have two drop-down enabled cells (K4 and L4).
K4 holds the list of all countries, presented in H col.
And L4 is supposed to have a list of people, avaliable in the col I
Now, the question is:
How can I code those K4 and L4 cells, so that when in K4 cell I select a country, then in the drop down list of L4 cell I'd get the list of only those people from the I column that have their country of origin equal to the one in K4?
I feel like it is possible to be done with those array-returning functions but I just can't wrap my head around it all.
I have it working like this so far.
The functions necessary for this are INDEX, MATCH, IF, IFERROR, and COUNTIF, which are all available in Excel 2019.
The only thing I'm struggling with (without 365) is that I can't figure out how to remove the white space for the dynamic range.
The formula in column 'E' is to make a unique list of the 'Country' column:
=IFERROR(INDEX($H$2:$H$20,MATCH(0,COUNTIF($E$1:$E1,$H$2:$H$20),0)),"")
This formula must begin at least in row 2, as it needs an empty space above it.
Column F is a similarly unique list of column I, but is dynamic based on the value in K4: *Now updated, see edit below
=IFERROR(INDEX($I$2:$I$20,MATCH(0,IF($K$4=$H$2:$H$20,COUNTIF($F$1:$F1,$I$2:$I$20),""),0)),"")
The validation in K4 is based on column E, and the validation in L4 is based on column F.
As I said, without O365 I can't figure out how to remove the white space, but this should at least work for you.
EDIT: I have had another look at this and figured out the whitespace issue:
Data validation for L4:
=INDIRECT("F2:"&"F"&(COUNTA(F:F)-COUNTIF(F:F," ")+1))
As a bonus, the data validation for K4 can be similar, in case you want to expand column H to include more entries:
=INDIRECT("E2:"&"E"&(COUNTA(E:E)-COUNTIF(E:E," ")+1))
This creates a list from F2 (which will always be our first value) and will expand dynamically as far down as column F has data, given that we change the formula in F2 to be:
=IFERROR(INDEX($I$2:$I$20,MATCH(0,IF($K$4=$H$2:$H$20,COUNTIF($F$1:$F1,$I$2:$I$20),""),0))," ")
Note that the character in the IFERROR of this formula and the COUNTIF of the previous is not a space, it's the character from Alt+255.
As a final nicety, adding some conditional formatting to cell L4 will make it so that selecting data in L4, and then changing the value of K4 (so that L4 is no longer valid) will return whitespace - which is really white text on a white background.
Conditional format formula for L4:
=NOT(IFERROR(ISNUMBER(SEARCH($L$4,TEXTJOIN(" ",1,F:F))),FALSE))
The following is my elaboration on #RGilchrist's answer that he presented above. His was the main idea thus all the credit goes to him too.
The functions, needed for this are INDEX, MATCH, IF, IFERROR, and COUNTIF, which are all available in Excel 2019.
The formula in column 'E' is to make a unique list of the 'Country' column:
=IFERROR(INDEX($H$2:$H$17;MATCH(0;COUNTIF($E$1:$E1;$H$2:$H$17);0));"")
For example, on the pic you can see a formula of the cell E2.
Some comments on this formula:
it should be entered into the cell by Ctrl+Shift+Enter as it is an array formula. And you can see that it is wrapped into curly brackets {}.
the formula needs to have at least 1 cell above it. In this case it is E1.
As you see on the picture - I've deliberately made my dataset sparce, not dence (it has empty rows). To work around having zero in the resultset one has to place 0 to the E1 cell.
on the picture my dataset is colored. That hints the fact that I've announced the dataset as a table. This would allow for some neat features like auto extending of the table should I add more rows to it. And that provides for some functionally neat addressing of the column in the dataset. In my locale the table-addressed following formula would be this:
=IFERROR(INDEX(Tab_1[Стовпець1];MATCH(0;COUNTIF($E$1:$E2;Tab_1[Стовпець1]);0));"") where Tab_1 is the name of the table I've announced. And [Стовпець1] is a name of the column in the table.
Column F is a similarly unique list of column I, but is dynamic based on the value in K4: =IFERROR(INDEX($I$2:$I$20,MATCH(0,IF($K$4=$H$2:$H$20,COUNTIF($F$1:$F1,$I$2:$I$20),""),0)),"")
All comments to previous formula are applicable to this one as well.
The data validation in K4 is based on column E, and the validation in L4 is based on column F. But in order to overcome empty space problem in resulting dropdown list the data validation should be based on a formula that uses OFFSET function.
So the data validation source for K4 would be
=OFFSET($E$2;;;COUNTIF($E$2:$E$10;"?*"))
The relevant screenshot is in my locale but the general interface should be familiar.
Related
I am building an excel sheet that returns the three highest values from a column in another sheet (sheet2, column B) along with their corresponding company (sheet2, column a). Ultimately, in sheet 1, I want to have a table that will display the company with those values.
This is what I am trying to achieve:
AWS ($280.9m), Google ($241.9m), Meta ($168.7m)
I was trying to use the large formula, but this does not help me with referencing the corresponding company so I’m unsure how to return both.
You can use LARGE to get your top-n, and then wrap with INDEX/MATCH and OFFSET to get the company name.
Cell E3 formula:
=LARGE($B$2:$B$7,ROW(E1))
Cell D3 formula, which returns the column to the left of the Large value:
=OFFSET(INDEX($B$2:$B$7,MATCH(LARGE($B$2:$B$7,ROW(D1)),$B$2:$B$7,0)),,-1)
or remove offset and use....
=INDEX($A$2:$A$7,MATCH(LARGE($B$2:$B$7,ROW(D1)),$B$2:$B$7,0))
Drag down your formulas as far as you would like.
The above solution is good but kinda oldschool. I would use =SORT() function instead:
=INDEX(SORT(A46:B56;2;-1);{1;2;3})
Translation to human language:
=INDEX(SORT(MyArray;ColumnToSortBy;Descending);{get first three rows}, [column])
*note: depending on your windows settings your Array row separator may differ. The easiest way to check your it is to select any range with more than one row, then get to formula bar and click F9 to see result preview.
where [column] is an optional argument, by default it takes 1st column.
I have two columns in my sheet (P and Q).
I created a column (AK) with two values in AK2 and AK3, and a column (AL) with two values. One in AL2 and one in AL3.
I am looking to match text in any row of P with one of the two in AK, then pull AL from the same row as the match in AK and populate Q with AL. I hope that makes sense.
This works to do what I want, but when I drag the formula down, it changes the value of each cell in the formula.
=VLOOKUP(P2,AK2:AL3,2,FALSE)
If I drag that down to Q3 it changes to
=VLOOKUP(P3,AK3:AL4,2,FALSE)
The only thing that should change for this formula to work, in my case, is P3.
Appreciate the assistance!
You need to freeze the rows with '$'. Something like =VLOOKUP(P2,$AK$2:$AL$3,2,FALSE).
You should look into relative vs. absolute references (see for example here), as they are pretty important when using Excel.
For example, The C column 'Person' in the screenshot below, which will be randomly sorted. The formula on the right, where I need the SUM has to first match the keyword 'A' with C3:C14 (as in E7) and then add the scores from the B (B3:B14) column at all the occurrences in the adjacent C(C3:C14) column if the match with keyword at E7 is found.
I tried using Sum Index match to do the summation of all the values as you can see in the example below, but only finds the first one. I manually typed the output in G7 which is the desired output.
Formula used in H7 is this, which doesn't work-
SUM(INDEX(B3:B14,MATCH(E7,C3:C14,0)),0)
In F7 use
=Sumifs(B:B,C:C,E7)
Copy down.
For a more dynamic approach consider using a pivot table. Then you don't have to manually create the list of people in column E.
Or use the new Dynamic array functions to create a unique list. In E7 use
=UNIQUE(C3:C14)
in F7 use
=SUMIFS(B3:B14,C3:C14,E7#)
No need to copy down. The formulas will "spill" automatically. This approach is only available in Excel with an Office 354 license.
Not really an Excel user, but what seemed simple has turned out to be very difficult for me. I am in trouble as I can't come up with a nice and clean (or any) way to get it working.
What I have here:
I need to create a new columnn that would tell the amount of employees in each occupation while ignoring the duplicates (highlighted).
The amount of names formula is working, so maybe this can be used ? Or maybe it's just in the way and should be cleared.
It's just:
=COUNTIFS(A:A;A2)
Tried searching for quite a while did not find anything suitable. Any help or advice would be much appreciated. I hope I explained it in clear manner.
Thank you
Without helper columns:
Two options, D2:
{=SUM(--(FREQUENCY(IF($B$2:$B$9=C2,MATCH($A$2:$A$9,$A$2:$A$9,0)),ROW($A$2:$A$9)-ROW($D$1)+1)>0))}
Or put in E2:
{=SUMPRODUCT((($B$2:$B$9=C2))/COUNTIFS($B$2:$B$9,$B$2:$B$9&"",$A$2:$A$9,$A$2:$A$9&""))}
Notice both are array formulas and should be entered through CtrlShiftEnter
SUMPRODUCT 'Deals' in Arrays 3
You might have employees with the same name (David, Michael) in different occupations (Tech & Worker, Tech & Economy). To distinguish those from each other, in B2 you can use:
=SUMPRODUCT((A$2:A$21=A2)*(C$2:C$21=C2))
In D2 you can use:
=SUMPRODUCT((1/B$2:B$21)*(C$2:C$21=C2))
Distinct Employees Occupation Count
with a helper column
Unique and Distinct values are tricky. Using a helper column is beneficial for identifying either one of these when coupled with an expanding range:
=SUMPRODUCT((A2=$A$1:$A1)*(C2=$C$1:$C1))
Relative Rows: ^ ^
Paste to cell E2.
Copy Drag the formula down from the where pasted.
The relative row numbers identified above well increase as the formula is copy dragged down. This creates a larger and larger range for comparison. An expanding range.
In this case the range that is expanding is the range of already checked values. Many times the result range is expanded and tested against to eliminate posting duplicates of already posted results in subsequent rows of the results list.
The helper column's value is how many times the name and occupation pair has previously appeared. Zero previous appearances tells us this is the first occurance. We will only count the zeros (first occurance) in the main formula.
The main formula for counting distinct employees in each occupation:
=COUNTIFS( $C$2:$C$9, C2, $E$2:$E$9, 0)
Paste to cell D2.
Copy Drag the formula down from the where pasted.
Here we count all the rows for this row's occupation where the occupation matches the range of listed occupations and for that particular row in the list of occupations, the helper column row value is zero.
Add a final column which is the concatenation of the prior 3 columns then use
=SUMPRODUCT(1/COUNTIF(D2:D9,D2:D9))
There is a good explanation of this formula here. Basically, values that appear once will count as 1. Values that appear more than once will appear as fractions of their total occurrence count and be summed to 1.
If you convert your data to an Excel table by selecting a populated cell in the range and pressing Ctrl+T, then formulas will auto-populate down last column. You can then reference the table columns in the formula and you won't need to amend the formula as you add rows.
Ex.
column A is a formula that outputs an 8 digit ID from a prior delimited calculation. I want to vlookup that ID to a separate set of data, but it is not finding the ID when the lookup value is part of a formula.
Is there a way to paste the formula result as a value in column b?
I have a list of 3000+ IDs, so using the F2, F9 trick won't work, since I would have to do that cell by cell.
Would prefer not to use VBA, but if that is the only way, can someone help simplify that process (new to using VBA)
If you have data in column A based on a left function of a bunch of numbers, and just want that result in column B, all you have to do is put:
=Value(ColRow)
in Column B. Then you can look up the value in Column B via VLookUp.
I am an avid Excel user and personally tested this solution. Though it appears #Scott beat me to it in the comment section.