I have the following problem I need to address:
I have quotations from multiple vendors for multiple types of products. I need to find the product wise minimum and 2nd lowest quotations. The sheet looks somewhat like this:
I want the output in the following format:
Now, the problem is that the number of vendors is 300, and using the regular formula: min(number1,number2,number3,...) is very tedious and error prone as I have to manually click each entry for each vendor like min(B3,F3,I3,... 300 entries) for product 1.
Another problem is for 2nd Lowest Quote Here, excel does not accept discontinuous array like min function. Which means I cannot enter the formula small(B3,F3,I3,2) as it gives you have entered too many arguments error in this case.
I need to find some way to get around this problem. Please help me out with this problem.
Another option in non-array formula solution
Assume your data put in A1:P5
"Minimum quote" in K3, copied across to M3, and all copied down :
=AGGREGATE(15,6,$B3:$J3/($B$2:$J$2=K$2),1)
"2nd lowest quote" in N3, copied across to P3, and all copied down :
=AGGREGATE(15,6,$B3:$J3/($B$2:$J$2=N$2),2)
Data
You could try an array formula like so:
=MIN(IF($B$2:$J$2=K$2,$B3:$J3))
Make sure you hit Ctrl+Shift+Enter. What it does is it only extracts values corresponding to the specific product using the if statement, min then finds the minimum value out of that range.
Same applies to the SMALL function, it can take a range but we must filter that range using the IF function to get only the columns we want for that product, this also requires to be an array formula by entering it with Ctrl+Shift+Enter
=SMALL(IF($B$2:$M$2=N$2,$B3:$M3),2)
Related
I want to create a named dynamic array formula that will give me a spill showing a cumulative (running) total of another array. I want one that I can enter into any cell in my workbook and get the same results.
I have the following named formulas:
twelve: =ROW(OFFSET('CSM'!$A$1,0,0,12,1)) [EDIT: I realised later it's simpler just to define it as =SEQUENCE(12)] This generates an array of whole numbers from 1 to 12; I use it for a number of purposes, such as producing a list of months (=TEXT(DATE(2023,twelve,1),"mmm-yy").
FTE: ='CSM'!$B$3/12*(--(twelve=twelve)) This shows FTE's monthly salary (with cell B3 on sheet CSM providing the annual salary) over 12 months.
Now, if I enter =FTE on any cell, I'll get a 12-cell spill that shows the FTE's salary for each month. That's fine, but what I really need is a named formula that when it spills will show the FTE's cumulative salary (a running total).
I can do this with a formula that links to a specific cell...for example, if I want my display to start in row 2 I use:
=SUM((--(twelve<=ROW()-1))*FTE), and then drag the formula down the remaining 11 rows. But I have to adjust this formula if I use it somewhere else--for instance, if I want to start my spill on row 10 I have to write =SUM((--(twelve<=ROW()-9))*FTE). I really want a named formula that I can use anywhere on the sheet without modification, that will give me a spill showing cumulative monthly salary.
I see you can do this using the MMULT function when the data are all on a worksheet (see here), even when those data are a dynamic spilled array (see =MMULT(ROW(A1#)>=TRANSPOSE(ROW(A1#)),A1#), here). But when I use this approach on a named formula, I get a #VALUE error. I think the error actually comes from the ROW() function--it looks like I can use =ROWS(FTE) (returns 12), but not =ROW(FTE) (which returns the error).
So my question is: is there any way I can create a named formula that will give me a 12-month spill of FTE's cumulative salary by month? Maybe using SEQUENCE() or MMULT() or something else...(We haven't got Lambda yet, by the way.)
EDIT (in response to comments):
For example, if B3=$75,000, putting =FTE into any cell will produce this (spilling over into cells below):
$6,369.86
$5,753.42
$6,369.86
$6,164.38
$6,369.86
$6,164.38
$6,369.86
$6,369.86
$6,164.38
$6,369.86
$6,164.38
$6,369.86
What I want is a cumulative sum (running total) of the above; that is:
$6,369.86
$12,123.29
$18,493.15
$24,657.53
$31,027.40
$37,191.78
$43,561.64
$49,931.51
$56,095.89
$62,465.75
$68,630.14
$75,000.00
As I mentioned, we haven't got Lamda at this point, or any of those newer formulae.
OK, I've figured out a solution. For whatever reason, it seems you can't use ROW() with named dynamic array formulas, but it turns out I don't need to. I can simply use: =MMULT((--(twelve>=TRANSPOSE(twelve))),FTE) and I'll get the desired result (with 75000 being the value in B3):
6369.86
12123.29
18493.15
24657.53
31027.40
37191.78
43561.64
49931.51
56095.89
62465.75
68630.14
75000.00
I also found it useful to assign the above formula to a name, so I can conveniently enter it into any cell on the sheet and get the same output.
One more thing: I realised I can define the named formula twelve more simply by using =SEQUENCE(12), though the OFFSET approach still works. (Still getting used to some of there 'new' Excel formulas--not so new anymore, I guess.) I edited original question to mention this.
I have array of numbers in a single column like this:
I want only that numbers for which corresponding negative numbers exist. If number exist 2 times, but negative number exist only one time, then I wanted to retain one positive and one negative number. Similarly, if number exists 3 times, and negative number appears only two times, then I want 2 set of numbers including positive and negative. In this case, I wanted to get output:
5 2 -2 -5
Orders of numbers are not relevant for me. Please do not use VBA. You can create multiple column and apply filter at the end.
Thank you for the response, but I wanted to get the data in column next to the values. Like:
5
2
-2
-5
Please help.
Here's another Office 365 solution:
Name the data range DATA
Put this formula anywhere: =CONCAT(REPT(-ROW(A1:A100)&" "&ROW(A1:A100)&" ",COUNTIF(DATA,"="&ROW(A1:A100)*IF(COUNTIF(DATA,"="&-ROW(A1:A100))<COUNTIF(DATA,"="&ROW(A1:A100)),-1,1))))
That will output the pairs into one cell.
Here's a slightly modified Step 2, which excludes duplicates: =CONCAT(IF((COUNTIF(DATA,"="&-ROW(A1:A100))>0)*(COUNTIF(DATA,"="&ROW(A1:A100))>0),-ROW(A1:A100)&" "&ROW(A1:A100)&" ",""))
Looks like this:
The data doesn't need to be sorted. Both methods work up to 100, but you can easily expand that by changing A100 to A1000 or whatever you need.
Use the vlookup formula to identify the rows, and you can use the Filter & Unique formula to get the list, or a pivot table.
First, immediately next to your data use the formula:
=vlookup(A1*-1,$A$1:$A$1,1,0)
For non-365:
This will produce an error for each instance that doesn't have a match. You can filter at this point to get your list from the existing table. You can also create a pivot table under the Data tab of your ribbon and inserting a pivot table. Filter the #N/A from there to get an exclusive list without hidden rows.
For 365:
You can use the following combination of formulas to get the exclusive list as well.
=UNIQUE(FILTER(B1:B8,ISNUMBER(B1:B8)),0,0) or =UNIQUE(FILTER($B$1:$B$8,ISNUMBER($B$1:$B$8)),0,0) should yield the same results
As ScottCraner mentioned, you can circumvent the helper column in 365 by modifying the formula a bit more:
=UNIQUE(FILTER(A1:A8,ISNUMBER(MATCH(-A1:A8,A1:A8,0)),"")
The Match here is doing something similar to the Vlookup, but housing that logic within the formula, so it's a cleaner solution in my opinion.
Using your data the result was { -5,-2,2,5 }
These are spill formulas so you only need to put it in one spot and it will expand the formula over the adjacent cells below where it's entered for however many cells needed to list all the unique numbers that occur. It takes into account the negatives and so on. This may be a 365 formula, so if you're on another version of excel it may not work.
Edit: Adjusted the instructions to fully address the question.
I'm working on data from a population of people with allergies. Each person has a unique ExceptionID, and each allergen has a unique AllergenID (451 in total).
I have a data table with 2 columns (ExceptionID and AllergenID), where each person's allergies are listed row by row. This means that the ExceptionID column has repeated values for people with multiple allergies, and the AllergenID column has repeated values for the different people who have that allergy.
I am trying to count how many times each pair of allergies is present in this population (e.g. Allergen#107 & Allergen#108, Allergen#107 & Allergen#109,etc). To keep it simple I've created a matrix of 451 rows X 451 columns, representing every pair (twice actually because A/B and B/A are equivalent).
I somehow need to use the row name (allergenID) to lookup the ExceptionID in my data table, and count the cases where that matches the ExceptionIDs from the column name (also AllergenID). I have no problem using Vlookup or Index/Match, but I'm struggling with the correct combination of a lookup and Sumproduct or Countif formula.
Any help is greatly appreciated!
Mike
PS I'm using Excel 2016 if that changes anything.
-=UPDATE=-
So the methods suggested by Dirk and MacroMarc both worked, though I couldn't apply the latter to my full data set (17,000+ rows) because it was taking a long time.
I've since decided to turn this into a VBA macro because we now want to see the counts of triplets instead of pairs.
With the 2 columns you start with, it is as good as impossible... You would need to check every ExceptionID to have 2 different specific AllergenID. Better use a helper-table with ExceptionID as rows and AllergenID as columns (or the opposite... whatever you like). The helper table needs a formula like:
=COUNTIFS($A:$A,$D2,$B:$B,E$1)
Which then can be auto-filled. (The ranges are from my example, you need to change them to your needs).
With this helper-matrix you can easily go for your bigger matrix like this:
=COUNTIFS(E:E,1,INDEX($E:$G,,MATCH($I2,$E$1:$G$1,0)),1)
Again, you can auto-fill with this formula, but you need to change it, so it fits your needs.
Because the columns have the same ID2 (would be your AllergenID), there is no need to lookup them because E:E changes automatically with the auto-fill.
Most important part of the formulas are the $ which should not be messed up, or you can not auto-fill it.
Picture of my self-made example (formulas are from the upper left cell in each table):
If you still have any questions, just ask :)
It can be done straight from your original set-up with array formulas:
Please note that array formulas MUST be entered with Ctrl-Shift-Enter, before copying across and down:
In the example pic, I have NAMED the data ranges $A$2:$A$21 as 'People' and $B$2:$B$21 as 'Allergens' to make it a nicer set-up. You can see in the formula bar how that looks as a formula. However you could use the standard references like this in your first matrix cell:
EDIT: silly me, N function is not needed to turn the booleans into 1's and 0's, since multiplying booleans will do the trick. Below formula works...
SUM(IF(MATCH($A$2:$A$21,$A$2:$A$21,0)=ROW($A$2:$A$21)-1, NOT(ISERROR(MATCH($A$2:$A$21&$E2,$A$2:$A$21&$B$2:$B$21,0)))*NOT(ISERROR(MATCH($A$2:$A$21&F$1, $A$2:$A$21&$B$2:$B$21,0))), 0))
Then copy from F2 across and down. It can be perhaps improved in technique with sumproduct or whatever, but it's just a rough example of the technique....
I am looking to get some help with a function that I am sure is an option but I sadly have no clue on how to implement.
Basically, I'd like a formula to go from C21:C50 and look for the top two values. Based upon which two are the top, it would reference the name in B column and populate that value in the another cell (the cell the formula resides in)
If you look at the image, in the primary field, we'd have Steve. Secondary would be Alan.
Is this something anyone can help with? I simply am lost :(
Try
=INDEX($B$3:$B$7,MATCH(LARGE($C$3:$C$7,ROW(A1)),$C$3:$C$7,0))
with Bob in cell B3 and the "primary" formula in cell C9. Copy down to cell C10.
If dealing with integers, you can simply add +1/ROW([range]) to avoid doubles:
=INDEX($B$3:$B$7,MATCH(LARGE($C$3:$C$7+1/ROW($C$3:$C$7),ROW(A1)),$C$3:$C$7+1/ROW($C$3:$C$7),0))
This is an array-formula and must be confirmed with ctrl+shift+enter!
However, this may fail for numbers like 5.01 or 4.99. For that case just use it in combination with RANK.EQ:
=INDEX($B$3:$B$7,MATCH(LARGE(RANK.EQ($C$3:$C$7,$C$3:$C$7,1)+1/ROW($C$3:$C$7),ROW(A1)),RANK.EQ($C$3:$C$7,$C$3:$C$7,1)+1/ROW($C$3:$C$7),0))
This is an array-formula and must be confirmed with ctrl+shift+enter!
The steps as picture:
The first table shows the direct adding of 1/ROW which is used for LARGE and MATCH to get the row if doubles exist (so INDEX can pick the correct one)
The second table shows how the values get replaced by their rank with RANK.EQ and then are treated the same like the first table.
The third (grey) table shows, what would happen if the first formula is applied to the second table (to demonstrate how the ranks get messed up).
For Excel 2007 just replace the RANK.EQ($C$3:$C$7,$C$3:$C$7,1) with RANK($C$3:$C$7,$C$3:$C$7,1).
If you still have any questions, just ask :)
I would like to create a succinct Excel formula that SUMS a column based on a set of AND conditions, plus a set of OR conditions.
My Excel table contains the following data and I used defined names for the columns.
Quote_Value (Worksheet!$A:$A) holds an accounting value.
Days_To_Close (Worksheet!$B:$B) contains a formula that results in a number.
Salesman (Worksheet!$C:$C) contains text and is a name.
Quote_Month (Worksheet!$D:$D) contains a formula (=TEXT(Worksheet!$E:$E,"mmm-yy"))to convert a date/time number from another column into a text based month reference.
I want to SUM Quote_Value if Salesman equals JBloggs and Days_To_Close is equal to or less than 90 and Quote_Month is equal to one of the following (Oct-13, Nov-13, or Dec-13).
At the moment, I've got this to work but it includes a lot of repetition, which I don't think I need.
=SUM(SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Oct-13")+SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Nov-13")+SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Dec-13"))
What I'd like to do is something more like the following but I can't work out the correct syntax:
=SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,OR(Quote_Month="Oct-13",Quote_Month="Nov-13",Quote_Month="Dec-13"))
That formula doesn't error, it just returns a 0 value. Yet if I manually examine the data, that's not correct. I even tried using TRIM(Quote_Month) to make sure that spaces hadn't crept into the data but the fact that my extended SUM formula works indicates that the data is OK and that it's a syntax issue. Can anybody steer me in the right direction?
You can use SUMIFS like this
=SUM(SUMIFS(Quote_Value,Salesman,"JBloggs",Days_To_Close,"<=90",Quote_Month,{"Oct-13","Nov-13","Dec-13"}))
The SUMIFS function will return an "array" of 3 values (one total each for "Oct-13", "Nov-13" and "Dec-13"), so you need SUM to sum that array and give you the final result.
Be careful with this syntax, you can only have at most two criteria within the formula with "OR" conditions...and if there are two then in one you must separate the criteria with commas, in the other with semi-colons.
If you need more you might use SUMPRODUCT with MATCH, e.g. in your case
=SUMPRODUCT(Quote_Value,(Salesman="JBloggs")*(Days_To_Close<=90)*ISNUMBER(MATCH(Quote_Month,{"Oct-13","Nov-13","Dec-13"},0)))
In that version you can add any number of "OR" criteria using ISNUMBER/MATCH
You can use DSUM, which will be more flexible. Like if you want to change the name of Salesman or the Quote Month, you need not change the formula, but only some criteria cells. Please see the link below for details...Even the criteria can be formula to copied from other sheets
http://office.microsoft.com/en-us/excel-help/dsum-function-HP010342460.aspx?CTT=1
You might consider referencing the actual date/time in the source column for Quote_Month, then you could transform your OR into a couple of ANDs, something like (assuing the date's in something I've chosen to call Quote_Date)
=SUMIFS(Quote_Value,"<=90",Quote_Date,">="&DATE(2013,11,1),Quote_Date,"<="&DATE(2013,12,31),Salesman,"=JBloggs",Days_To_Close)
(I moved the interesting conditions to the front).
This approach works here because that "OR" condition is actually specifying a date range - it might not work in other cases.
Quote_Month (Worksheet!$D:$D) contains a formula (=TEXT(Worksheet!$E:$E,"mmm-yy"))to convert a date/time number from another column into a text based month reference.
You can use OR by adding + in Sumproduct. See this
=SUMPRODUCT((Quote_Value)*(Salesman="JBloggs")*(Days_To_Close<=90)*((Quote_Month="Cond1")+(Quote_Month="Cond2")+(Quote_Month="Cond3")))
ScreenShot
Speed
SUMPRODUCT is faster than SUM arrays, i.e. having {} arrays in the SUM function. SUMIFS is 30% faster than SUMPRODUCT.
{SUM(SUMIFS({}))} vs SUMPRODUCT(SUMIFS({})) both works fine, but SUMPRODUCT feels a bit easier to write without the CTRL-SHIFT-ENTER to create the {}.
Preference
I personally prefer writing SUMPRODUCT(--(ISNUMBER(MATCH(...)))) over SUMPRODUCT(SUMIFS({})) for multiple criteria.
However, if you have a drop-down menu where you want to select specific characteristics or all, SUMPRODUCT(SUMIFS()), is the only way to go. (as for selecting "all", the value should enter in "<>" + "Whatever word you want as long as it's not part of the specific characteristics".
In order to get the formula to work place the cursor inside the formula and press ctr+shift+enter and then it will work!
With the following, it is easy to link the Cell address...
=SUM(SUMIFS(FAGLL03!$I$4:$I$1048576,FAGLL03!$A$4:$A$1048576,">="&INDIRECT("A"&ROW()),FAGLL03!$A$4:$A$1048576,"<="&INDIRECT("B"&ROW()),FAGLL03!$Q$4:$Q$1048576,E$2))
Can use address / substitute / Column functions as required to use Cell addresses in full DYNAMIC.