Manipulate and convert item qty data in Excel - excel

I need to calculate the quantity of a new item, given conversion factors of the original item data. the 'NewQty' column is what I'm trying to solve for. Is there a formula in Excel that would perform this entire calculation?
This might help- from another post, breaking out the UOM string columns has been solved, linked here.
The first row for example:
OrigItem has 25 CA's. You first want to convert it to its lowest Unit of Measure (EA). 'OrigUOMString' says that there are 30 EA's in a CA, so step 1:
25 (OrigQty) * 30 (OrigUOMString) = 750 EA
For the new item, there are 40 EA's in a CA, so step 2:
750 / 40 (NewUOMString) = 18.75
So the result says that qty of the new item would be 18.5 CA, which is the result that would go into 'NewQty'.
The second row for example:
13 BX's, so 12 (from OrigUOMString) * 13 (OrigQty) = 156 EA's
156 / 40 CA (NewUOMString) = 3.9 CA's (which goes into column 'NewQty')
OrigItem#
OrigUnitOfMeasure
OrigQty
OrigUOMString
NewItem#
NewUOMString
NewUOM
NewQty
111xy
CA
25
1EA/2PK/12BX/30CA
ABC123
1EA/4PK/20BX/40CA
CA
?
111xy
BX
13
1EA/2PK/12BX/30CA
ABC123
1EA/4PK/20BX/40CA
CA
?

In cell H2 you can try the following (I assume you don't have any excel version constraint per tags listed in the question)
=LET(rng, A2:G3, oUnit, INDEX(rng,,2), oQTY, INDEX(rng,,3),
oStr, INDEX(rng,,4), nStr, INDEX(rng,, 6), nUnit, INDEX(rng,,7),
GET_UNIT, LAMBDA(x,unit, 1*TEXTAFTER(TEXTBEFORE(x, unit), "/", -1)),
MAP(oUnit, oQTY, oStr, nStr, nUnit,LAMBDA(oUn,qty,oSt,nSt,nUn,
LET(m, GET_UNIT(oSt, oUn), d, GET_UNIT(nSt, nUn),
(qty * m)/d)))
)
and here is the output:
The main idea is to create a LAMBDA function (because we are going to use it more than once): GET_UNIT to extract the unit information. We extract the text before the unit via TEXTBEFORE, and then we get the sub-string after the last instance of / via TEXTAFTER. The rest is just to use MAP to iterate over all rows and then use the multiplier (m) and the divisor (d) to do the calculation.

Related

Sum of the greatest value in one column, plus the sum of the other values in another column

Consider the following sheet/table:
A B
1 90 71
2 40 25
3 60 16
4 110 13
5 87 82
I want to have a general formula in cell C1 that sums the greatest value in column A (which is 110), plus the sum of the other values in column B (which are 71, 25, 16 and 82). I would appreciate if the formula wasn't an array formula (as in requiring Ctrl + Shift + Enter). I don’t have Office 365, I have Excel 2019.
My attempt
Getting the greatest value in column A is easy, we use MAX(A1:A5).
So the formula I want in cell C1 should be something like:
=MAX(A1:A5) + SUM(array_of_values_to_be_summed)
Obtaining the values of the other rows in column B (what I called array_of_values_to_be_summed in the previous formula) is the hard part. I've read about using INDEX, MATCH, their combination, and obtaining arrays by using parenthesis and equal signs, and I've tried that, without success so far.
For example, I noticed that NOT((A1:A5 = MAX(A1:A5))) yields an array/list containing ones (or TRUEs) for the relative position of the rows to be summed, and containing a zero (or FALSE) for the relative position of the row to be omitted. Maybe this is useful, I couldn't find how.
Any ideas? Thanks.
Edit 1 (solution)
I managed to obtain what I wanted. I simply multiplied the array obtained with the NOT formula, by the range B1:B5. The final formula is:
=MAX(A1:A5) + SUM(NOT((A1:A5 = MAX(A1:A5))) * B1:B5)
Edit 2 (duplicate values)
I forgot to explain what the formula should do if there are duplicates in column A. In that case, the first term of my final formula (the term that has the MAX function) would be the one whose corresponding value in column B is smallest, and the value in column B of the other duplicates would be used in the second term (the one containing the SUM function).
For example, consider the following sheet/table:
A B
1 90 71
2 110 25
3 60 16
4 110 13
5 110 82
Based on the above table, the formula should yield 110 + (71 + 25 + 16 + 82) = 304.
Just to give context, the reason I want such a formula is because I’m writing a spreadsheet that automatically calculates the electric current rating of the short-circuit protective device of the feeder of a group of electric motors in a house or building or mall, as required by the article 430.62(A) of the US National Electrical Code. Column A is the current rating of the short-circuit protective device of the branch-circuit of each motors, and column B is the full-load current of each motor.
You can use this formula
=MAX(A1:A5)
+SUM(B1:B5)
-AGGREGATE(15,6,(B1:B5)/(A1:A5=MAX(A1:A5)),1)
Based on #Anupam Chand's hint for max-value-duplicates there could also be min-value-duplicates in column B for corresponding max-value-duplicates in column A. :) This formula would account for that
=SUM(B1:B5)
+(MAX(A1:A5)-AGGREGATE(15,6,(B1:B5)/(A1:A5=MAX(A1:A5)),1))
*SUMPRODUCT((A1:A5=MAX(A1:A5))*(B1:B5=AGGREGATE(15,6,(B1:B5)/(A1:A5=MAX(A1:A5)),1)))
Or with #Anupam Chand's shorter and better readable and overall better style :)
=SUM(B1:B5)
+(MAX(A1:A5)-MINIFS(B1:B5,A1:A5,MAX(A1:A5)))
*COUNTIFS(A1:A5,MAX(A1:A5),B1:B5,MINIFS(B1:B5,A1:A5,MAX(A1:A5)))
The explanation works for bot solutions:
The SUM-part just sums the whole list.
The second line gets the max-value for column A and the corresponding min-value of column B for the max-values in column A and adds or subtracts it respectively.
The third line counts, how many times the corresponding min-value for the max-value occurs and multiplies it with the second line.
Can you try this ?
=MAX(A1:A5)+SUM(B1:B5)-MINIFS(B1:B5,A1:A5,MAX(A1:A5))
What we're doing is adding the max of A to all rows of B and then subtracting the min value of B where A is the max.
If you have Excel 365 you can use the following LET-Formula
=LET(A,A1:A5,
B,B1:B5,
MaxA,MAX(A),
MinBExclude, MINIFS(B,A,MaxA),
sumB1,SUMPRODUCT(B*(A=MaxA)*(B<>MinBExclude)),
sumB2,SUMPRODUCT(B*(A<>MaxA)),
MaxA +sumB1+sumB2
A and B are shortcuts for the two ranges
MaxA returns the max value for A (110)
MinBExclude filters the values of column B by the MaxA-value (25, 13, 82) and returns the min-value of the filtered result (13)
sumB1 returns the sum of the other MaxA values from column B (26 + 82)
sumB2 returns the sum of the values from B where value in A <> MaxA (71 + 60)
and finally the result is returned
If you don't have Excel 365 you can add helper columns for MaxA, MinBExclude, sumB1 and sumB2 and the final result

Using Offset to get to the next instance of a variable?

I am attempting to find the next instance of a variable in order to generate a list base on another variable:
Mkt ID
10 908
15 915
15 416
25 312
25 215
32 482
Similar to the above. There are two drop downs, one for market and one for ID. I want the user to be able to select a market and in the ID drop down have the data validation filter to that list of IDs respective to the market in the first drop down.Let's say the market dropdown is $G$2. Market is Column A, and ID is column B.
Here's the formula I have so far:
OFFSET(ADDRESS(MATCH($G$2,A:A,0),1),0,1,COUNTIFS(A:A,$G$2),1)
This formula references the market, offsets by 0 rows and 1 column, counts the number of that market instance for height, and 1 row in width. I do not see why this is not working. Excel just gives the typical, are you really trying to type a formula? error code.
ADDRESS returns a string that looks like a cell reference. You need INDIRECT to turn that into a real cell reference that OFFSET can use.
=OFFSET(indirect(ADDRESS(MATCH($G$2, A:A, 0), 1)), 0, 1, COUNTIFS(A:A, $G$2), 1)

Excel ranking based on grouping priorities

Hi everyone I have an excel question on how to rank but based first on a a ranking but then next on a second priority of a group. The formula is written in column 'Final_Rank' and I just hid a bunch of rows to show the clear example. Within the column Rank is just a normal rank function. I want the priority to be within Rank first, but then to add the next rank to the next item of the same group*. So if you look at Group HYP it will supersede ranked (3 and 4) and then 5 would be given to the next newest group.
I hope this is a clear explanation, thanks.
Group Rank Final_Rank_Manual
TAM 1 1
HYP 2 2
GAB 3 5
HYO 4 8
ALO 5 9
HYP 7 3
ACO 8 12
IBU 9 13
ACO 11 14
ALO 18 10
GAB 44 6
IBU 53 15
IBU 123 16
GAB 167 7
HYP 199 4
You can do this with an extra helper column. Assuming your table currently occupies columns A-C, with one header row, put the following in C2:
=SMALL(IF($A$2:$A$6=A2,$B$2:$B$6,9999999999),1)+(B2*0.000000001)
You'll need to enter this as an array formula by using Ctrl+Shift+Enter↵. Copy it down throughout the whole column. This gives you the group's ranking, and it adds a tiny decimal indicating the individual values position within each group. (e.g. the 3rd "HYP" value is converted to something like 2.0000000199, because out of all the available values, the second lowest belongs to "HYP", and this specific "HYP" value is 199).
Next, enter the following in D2 and copy it down throughout the column:
=RANK(C2,$C$2:$C$6,1)
This will give you the "Final" rankings. There won't be any ties because of the tiny decimals we added in the previous formula. The results end up looking just like your sample.

Best method to calculate provision from a table with provision levels?

I have a table with provision levels.
Sales Provision
0 5%
20 000 22%
100 000 30%
A salesman has 5% provision on the first 20 000, 22% on the next 80 000 and 30% on everything above that.
For example a salesman who sells for 230 000 will have provision
=20 000 * 0,05 + 80 000 * 0,22 + 130 000 * 0,30
How can I express this efficiently with a formula? The formula
Needs to be easy to copy to several rows (where a salesman is described by each row)
Needs to work even if I add more provision levels
Well I can say this works (hopefully) for requirement #2:
Needs to work even if I add more provision levels
But note that I am unsure about requirement #1:
Needs to be easy to copy to several rows (where a salesman is described by each row)
Anyway, with this data:
A B C D E
------------------------------------------
0 0.05 Value 230000
20000 0.22 Total Provision 57600
100000 0.3
I used this formula in E2:
=IFERROR(SUMPRODUCT((INDIRECT("A2:A"&MATCH(E1,A:A,1))-INDIRECT("A1:A"&MATCH(E1,A:A,1)-1))*INDIRECT("B1:B"&MATCH(E1,A:A,1)-1))+(E1-INDEX(A:A,MATCH(E1,A:A,1)))*INDEX(B:B,MATCH(E1,A:A,1)),E1*B1)
If we break this formula down:
The first basic step is to find the index at which the sale value resides. This is the first lower value compared to the sale value. In your example data this is straight forward because the index is the last in the provision list. However to accommodate sale values that fall within the list range we can use:
MATCH(E1,A:A,1)
where E1 is the sale value and A:A is the sale-provision list.
Using this we can incorporate an INDIRECT to get the desired range we need to work with. In this case A1 to A & Index:
INDIRECT("A1:A"&MATCH(E1,A:A,1))
But even within this range we need to figure out two distinct values:
The provision value index lower than our sale value (i.e. 20 000 * 0.05 + 80 000 * 0.22)
The rest of the provision sale value (i.e. 130 000 * 0.30)
So to get the first value we need to set up an array like this:
(20000 - 0) * 0.05 = 20000*.05 = 1000
(100000 - 20000) * 0.22 = 80000*.22 = 17600
SUM = 18600
That can be done by using
(A2:A3 - A1:A2)*(B1:B2)
But to put that in our INDIRECT formula, that would look like
INDIRECT("A2:A"&MATCH(E1,A:A,1)) <- A2:A3
INDIRECT("A1:A"&MATCH(E1,A:A,1)-1) <- A1:A2
INDIRECT("B1:B"&MATCH(E1,A:A,1)-1) <- B1:B2
(INDIRECT("A2:A"&MATCH(E1,A:A,1))-INDIRECT("A1:A"&MATCH(E1,A:A,1)-1))*INDIRECT("B1:B"&MATCH(E1,A:A,1)-1))
Just surround that with a SUMPRODUCT to get the total:
SUMPRODUCT((INDIRECT("A2:A"&MATCH(E1,A:A,1))-INDIRECT("A1:A"&MATCH(E1,A:A,1)-1))*INDIRECT("B1:B"&MATCH(E1,A:A,1)-1))
Then the second value is just the total sale value subtracted by our index value and multiplied by the corresponding provision rate. So that would be:
(E1-A3)*B3
We actually don't need INDIRECT here, a couple INDEX - MATCH lookups will do:
E1 <- E1
INDEX(A:A,MATCH(E1,A:A,1)) <- A3
INDEX(B:B,MATCH(E1,A:A,1)) <- B3
(E1-INDEX(A:A,MATCH(E1,A:A,1)))*INDEX(B:B,MATCH(E1,A:A,1))
Then adding those to formulas together results in the derived formula I showed earlier.
The final addition however was to add an IFERROR wrapper because if the value is less than the first non-zero provision the INDEX-MATCH and INDIRECT will fail. So in the case of an error that means we just need to multiply the sale value by the first provision rate:
E1*B1
And of course if you add an additional provision row:
A B C D E
------------------------------------------
0 0.05 Value 230000
20000 0.22 Total Provision 63600
100000 0.30
200000 0.50
Or change the provision:
A B C D E
------------------------------------------
0 0.05 Value 22000
20000 0.22 Total Provision 1440
100000 0.30
The formula will index to the proper provision and calculate it properly.
Also,
Since I know I use commas and decimals in my locale and I realized you don't here is the formula for semi-colon list separator:
=IFERROR(SUMPRODUCT((INDIRECT("A2:A"&MATCH(E1;A:A;1))-INDIRECT("A1:A"&MATCH(E1;A:A;1)-1))*INDIRECT("B1:B"&MATCH(E1;A:A;1)-1))+(E1-INDEX(A:A;MATCH(E1;A:A;1)))*INDEX(B:B;MATCH(E1;A:A;1));E1*B1)

perform operations next to a string in matlab

I have my data coming back as a cell which looks like this (each trade is underneath each other in the cell ie its a 5 by 4 cell):
sell 50 FTSE 6500
buy 100 Eurostoxx 3300
buy 25 SP 1980
buy 30 FTSE 6490
sell 25 Eurostoxx 3315
Firstly because I have mixed data its coming back from my database query as a cell so not sure if thats a problem
What I'd like to do is mark these to market, so I have closing market price of each of these contracts as a variable lets call them FTSE_CLOSE, EUROSTOXX_CLOSE and SP_CLOSE.
I'd like to be able to do something that goes as follows:
where coloumn 3 = "FTSE" and column 1 = "sell" then column 5 = column2 * (column4 - FTSE_CLOSE)
where column 3 = "FTSE" and column 1 = "buy" then column 5 = column2 * (FTSE_CLOSE - column4)
and so on for the other contracts.
Basically I am struggling with the mixed use of strings and numbers
Do I need to cell2mat everything so I have several vectors and then somehow look into the string vectors and perform the calucaltion on the other relevant vectors i.e. quantity * price - close_price
Is there a simpler way of doing this
I think you are simply looking for the command str2num
Here is one idea:
input_data={"sell","50","FTSE","6500";
"buy","100","Eurostoxx","3300";
"buy","25","SP","1980",
"buy","30","FTSE","6490",
"sell","25","Eurostoxx","3315"};
closing_price.FTSE=6000;
closing_price.Eurostoxx=3000;
closing_price.SP=2000;
for i=1:size(input_data,1)
if strcmp(input_data{i,1},'sell')
diff_from_market(i)=str2num(input_data{i,2}) ...
*(str2num(input_data{i,4})-closing_price.(input_data{i,3}));
elseif strcmp(input_data{i,1},'buy')
diff_from_market(i)=str2num(input_data{i,2}) ...
*(closing_price.(input_data{i,3})-str2num(input_data{i,4}));
end
end
diff_from_market

Resources