I have a problem that I would like someone to help me with.
I need to cross data from a table, the table is the following below:
Literally I want to put in the "Yellow" line the amount I want, it can be any one from 0 to 3000. If in "Yellow" put for example 190, which is up to 200, then it will select column F. If you put 1000, then will already select column H.
Then I need to cross data with the lines, which will be up to x m2. That is, if in the line where it says "Green" select for example 0.3. Then it will select line 15. The Result of the 2 questions would be 1000 in this example.
However, I've already made a few attempts, and there I arrived at a formula killer:
=IFS(AND($E$20<=$F$14;$E$21<=$E$15);$F$15;AND($E$20<=$F$14;$E$21<=$E$16);$F$16;AND($E$20<=$F$14;$E$21<=$E$17);$F$17;AND($E$20<=$F$14;$E$21<=$E$18);$F$18;AND($E$20<=$G$14;$E$21<=$E$15);$G$15)
And this formula continues until the end. It's effective, it does its job, but in addition to being huge, it also makes it difficult to edit one day. I would like to try to improve it.
Any idea?
I apologize to everyone who was confused by my earlier attempt to explain my problem. Thank you all.
Per my understanding you are looking for two match criteria. For yellow criteria you look for exact match and for green criteria, the exact match or the next upper value.
You can use INDEX/XMATCH for that as follow using LET function in cell J3:
=LET(rng, B2:G5, upper, 1*TEXTAFTER(TEXTBEFORE(A2:A5, " m2"), " ", -1),
INDEX(rng, XMATCH(J2, upper, 1), XMATCH(J1, B1:G1))
)
or without LET function:
=INDEX(B2:G5, XMATCH(J2, 1*TEXTAFTER(TEXTBEFORE(A2:A5, " m2"), " ", -1), 1),
XMATCH(J1, B1:G1))
Note: The above approach doesn't require a helper column with the upper values, if such information is provided like in the updated version of the question (column E), then use the corresponding range instead.
Here is the output:
It assumes there is a space between m2 and the number in the green column. You need to standardize it in your input. For example the last green row doesn't have a space. If that is not the case you need to cleanup it first, via SUBSTITUTE function for example or manually it seems to be a typo.
The name upper contains the number associated to m2 in the green column using TEXTBEFORE and TEXTAFTER. The first XMATCH uses the third input argument (1) to ensure if the value doesn't exist, then it finds the next upper value. The second XMATCH look for an exact match for the yellow column.
This is a well known use case: Two dimensional lookup or two way lookup. For example you can check: INDEX XMATCH XMATCH to perform 2-dimentional lookup and just to adapt it to your specific case. You can also use XLOOKUP function for similar situations.
I'm trying to do it the way you showed me. However, I don't use excel and therefore I don't have this "LET" formula.
I had to improvise.
Followed this way:
I made a new column with the intended values.
All these values would be approximate, for example, if I put 150 in quantity and say that they are 5m2, it would give me the result of 1400. This is because it is below 200 units and below 5m2. Another example, if you put 499 units and put 13m2, then the result would be 360,
Currently, with this formula, I have already achieved approximations. However, the values are not matching up and when I pass 1500 units then it gives me this error: The value of Parameter 2 of the INDEX function, 5, is out of range.
Have a good year David.
Related
given the specific set of columns, I'm looking for a way to turn red cells into blank cells either within the COUNTIF process or afterward.
formula I use to get (partially) correct answer is:
=ARRAYFORMULA(IF(A2:A="",,IF(NOT(REGEXMATCH(TO_TEXT(B2:B), "\-")),
COUNTIFS(A2:A&D2:D, A2:A&D2:D, ROW(A2:A), "<="&ROW(A2:A)), )))
here is a copy of my sheet: - CC -
consider yellow cells as RESET/TERMINATION for ID
after each reset, ID gets upgraded (E column)
E column is just a helper for better visualization - it's not part of the dataset
A column is unsorted and it may be even ungrouped
When I make a copy of your sheet (the only option provided), the negative numbers in Col B are actually all text. So I didn't backtrack into the best way of doing this from the original data in Col A. Instead, I just worked with Cols A:D as you currently have them (though I suspect that you don't need the helpers) and with your original "close" formula as you wrote it.
That said, this should work to deliver your desired result as shown:
=ArrayFormula({"DESIRED OUTPUT";IF(A2:A="",,IF(VLOOKUP(A2:A&"~"&COUNTIFS(A2:A,A2:A,ROW(A2:A),"<="&ROW(A2:A))-1,{SPLIT(UNIQUE(A2:A)&"~0|0","|");A2:A&"~"&COUNTIFS(A2:A,A2:A,ROW(A2:A),"<="&ROW(A2:A)),C2:C},2,FALSE)<>0,,IF(NOT(REGEXMATCH(TO_TEXT(B2:B), "\-")), COUNTIFS(A2:A&D2:D, A2:A&D2:D, ROW(A2:A), "<="&ROW(A2:A)), )))})
My contribution is this part:
IF(VLOOKUP(A2:A&"~"&COUNTIFS(A2:A,A2:A,ROW(A2:A),"<="&ROW(A2:A))-1,{SPLIT(UNIQUE(A2:A)&"~0|0","|");A2:A&"~"&COUNTIFS(A2:A,A2:A,ROW(A2:A),"<="&ROW(A2:A)),C2:C},2,FALSE)<>0,, [most of your previous formula])
In plain English, this looks up the last occurrence of each ID. Only if that last occurrence had a 0 value in Col C will the results of your main formula be shown.
I stacked SPLIT(UNIQUE(A2:A)&"~0|0","|") on top of the actual ID~Row, Col C values so that the first occurrence of any ID will still find a 0 and will not result in an error. (Adding IFERROR would have unnecessarily lengthened the formula.)
NOTE 1: I assumed here that you original "close" formula works as you expect. I did not test it under close scrutiny. I just plugged it into my extended formula that determines where to place results.
NOTE 2: Normally, I don't get into complex formulas on these forums, for the sheer sake of time and the fact that I stay very busy. But you help out a ton on this forum, so I was happy to invest back into your own rare inquiry here.
I’ve looked at similar questions and I think I’m close to a working solution, but it’s giving me the wrong answer. I have a spreadsheet in Google Sheets with data in all columns, but every other cell contains a dollar value and I need only the average of those cells. They start (in this version) on cell G3 and continue through most of row 3, then I intend to copy the formula to other rows with the same cells in those rows needing to be averaged as well, so if it’ll adjust as I copy that’ll be best. Here’s what I’ve worked up so far:
=AVERAGEIF(ArrayFormula(mod(column(G3:3),2)),”>0”)
It’s returning 1 as the result, when it should be about 1500. If I change the 2 to another number, the result increases with it, so I think something in mod or column is being done wrong, but I don’t have enough practice to know where I messed up.
avg of every 2nd column it's done like:
=AVERAGE(FILTER(G3:3, MOD(COLUMN(G3:3)-1, 2)=0))
TIL about the FILTER function. Thanks guys.
There is a way with ArrayFormula. I think you almost got it. I would prefer to add one more argument for AVERAGEIF to specify the range to average. I don't know if it defaults to the range in the condition.
And I would do the modulo on the difference between a column and the first column. I guess for your question it isn't needed as all column numbers are either odd or even. But using the difference is a general purpose way to apply the concept to say every nth column.
The modulo 2 of any column number with be 0 or 1. So instead of using an inequality just use 0 or 1. From your formula it looks like your dollar values must be in odd columns so the result of the modulo should be 1. But I think if you are starting at G3 then taking the column difference before applying Mod 2 changes the desired result to 0. But of course to switch to the other column change the 0 to a 1.
=AVERAGEIF(ArrayFormula(mod((COLUMN(G3:3)-COLUMN(G3)),2)),0,G3:3)
I have a chart that shows the salaries for various medical specialties by percentile (each row is a specialty and each column is a percentile).
I want to be able to take a separate chart of physicians and their salaries, and automatically fill in what percentile each of their pay is.
https://i.imgur.com/NCtHHAB.jpg
If the physicians were all in one specialty, then I could just use Index-Match like so:
=INDEX('[Percentiles Chart]'!$B$3:$F$4, 1, MATCH(K3,'[Percentile File]'!$B$4:$F$4,1))
This formula works because it's choosing the column based on just the salaries in that one row, and always returning the top row. If I wanted it to choose between different rows, how could I do that without writing an "If" formula for every single row?
In other words, I want excel to look down column A in the example picture to pick the right specialty, then compare the salaries across the row and return what's in row 2.
Thank you!
As you rightly mentioned, there is no easy way to accomplish what you are looking for since the combination of Index/Offset/Match functions will return the data from the row that is matched and not some other row. Here is a formula that I have tried and it works exactly like you want. It is slightly hacky and uses SUMPRODUCT but gets the job done.
In your spreadsheet, if you enter the below formula, you would see that it gets the correct percentile value.
=OFFSET($B$2,0,SUMPRODUCT(($A$3:$A$6=J3)*($B$3:$F$6<K3)),1,1)
Here is how it works. The first part Sumproduct basically matches the name of specialty in range A3 to A6 and returns true for a match. The second part in sumproduct checks how many values in the range B3 to F6 are less than the given value (for example K3). When these two results are multiplied, it gives the number of values less than given value in the row of matching specialty which is equivalent to the offset of the column in the range. So, the OFFSET function simply navigates to that column and returns the value of the percentile. The below screenshot should help you understand it better.
If my explanation confused you :), you may want to play around with this formula to see how exactly it works.
Note the last column that says 100 in the percentiles table. That is simply to show correct value in case salary is greater than 90 percentile value.
As you can see, I have a database table on the left. And I want to add in IF statement that allows me to lookup the [Code], [Name] and [Amount] of the top 5 of Company A ONLY. Then do a top 5 for Company B and so on. I have managed to lookup the top 5 out of ALL companies but cannot seem to add a criteria to target specific company.
Here are my formulas so far:
Formula in Column K [Company]: = INDEX(Database,MATCH(N3,sales,0),1)
Formula in Column L [Code]: = INDEX(Database,MATCH(N3,sales,0),2)
Formula in Column M [Name]: = INDEX(Database,MATCH(N3,sales,0),2)
Formula in Column N [Amount]: = LARGE(sales,ROW(1:20))
The intended result is to show the top 5 sales person in each company along with their [Code], [Name] and [Amount], feel free to suggest any edits to the worksheet.
Here's an alternative if you know the code is unique. After putting A into K3:K7
First get the highest amounts for Company A starting in N3
=AGGREGATE(14,6,Database[Amount]/(Database[Company]=K3),ROWS(N$1:N1))
Then find the code which matches the amount, but only if it hasn't been used before (this assumes that the code is unique) starting in L3
=INDEX(Database[Code],MATCH(1,INDEX((Database[Company]="A")*(Database[Amount]=N3)*ISNA(MATCH(Database[Code],L$2:L2,0)),0),0))
Then find the matching name with a normal INDEX/MATCH starting in M3
=INDEX(Database[Name],MATCH(L3,Database[Code],0))
Okay, I have achieved this with the use of a helper column which you can hide. Please nnote though that this will only work as long as there are not more than 9 identical totals for any 1 company, I don't think you should have that issue but it may occur, the digits being added by the helper column would need to be tweaked
First Helper Column:
Adds a digit to the end of the total representing the number of times that amount already exists above for that company. This formula is =CONCATENATE([#Amount],COUNTIFS($A$1:A1,A2,$D$1:D1,D2))*1
This is multiplied by 1 to keep the number format for LARGEto work with.
Second Helper Column:
This is an array formula and will need to be input by using Ctrl+Shift+Enter while still in the formula bar.
The formula for this one is:
=LARGE(IF(Company="A",Helper),ROW(1:1))
What this formula does as an array formula is produce a list of results based on the IF statement that LARGE can use. Rather than the entire column being ranked largest to smallest, we can now single out the rows that have company "A" like so:
=LARGE({20000;20001;20002;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;15000;14000;30000;FALSE;FALSE;FALSE;FALSE},ROW(1:1))
LARGE will only work with numeric values so the FALSES produced where column A does not match "A" will be ignored. Notice why I have used the helper column here to eliminate unique values but not affect the top 5.
ROW(1:1) has been used as this will automatically update when the formula is dragged down to produce the next highest result in this array.
The main formula for top 5 array
Again this is an Array formula so will need to be input by using Ctrl+Shift+Enter while still in the formula bar.
=INDEX(Database,SMALL(IF(Company="A",IF(Helper=$O3,ROW(Company))),1)-1,COLUMN(A:A))
With array formulas for some unknown reason IF(AND()) just does not work for me so I have nested two IF's instead.
Notice how I am again checking whether the first column matches "A" and then whether the last column matches the result of the second formula. What will happen is where both of these conditions match in the array (as in both produce TRUE for the same row) I wanted the row number to be returned.
IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE},IF({FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;FALSE;TRUE;FALSE;FALSE},{2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20}))
It looks like a mess I know, but the position where both TRUEs align gives us the row 16 as a result.
{FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;16;FALSE;FALSE;FALSE;FALSE}
As I know that there can only be one match possible for this, I use SMALL to grab the first smallest number to use in the INDEX formula for row and deduct 1 as we are not considering the headers in the INDEX formula so we actually want the 15th result.
Again, COLUMN(A:A) has been used for the column number to return as this will automatically update when the formula is dragged across.
If you are struggling with my explanation and want me to provide more clarity, feel free to reach out and I will try my best to explain the logic in more detail
As shown in the attached image, I need to convert A2:D10 to the format of A12:E17. The 4 tables from F1 to AB12 are my experiments using if, match, and index. Same formula gets different results and it seems to be dependent on the row position of the tables. In My previous question, I was trying to pinpoint the problem to the if function.
What am I doing wrong here?
Thanks,
Lu
enter image description here
Again, as I said in your last question: The formula has not been array entered. Array formulas need to be confirmed with Ctrl-Shift-Enter.
Without that, the first array in the IF statement does not get resolved and the Match does not return the correct result.
Make use of the Evaluate Formula tool and step through the formula.
The merged cells don't help with the cell referencing. Unmerge the cells and fill in all the labels in row 1, then use this slightly amended formula and confirm it with Ctrl-Shift-Enter. Then copy across and down.
I hope that I get the English names of the functions right:
In D14 and following cells:
=INDEX($C$1:$C$5;MATCH(1;MMULT(($B$3:$B$10=$A14)*($A$3:$A$10=B$13);1);0))
The MATCH function tells which value (by number counted from the top) matches both conditions. The INDEX function returns this value from C1:C5.