Stock Balance Inventory ArrayFormula in Google Sheets - google-sheets

How to create an Inventory Stock Balance for each row in Sheets with the help of array-formulas.
Sample:
Item
Operation
Quantity
Balance (Formula)
a
buy
500
500
b
buy
100
100
a
sell
110
390
a
buy
1000
1390
a
sell
800
590
b
buy
200
300
a
sell
390
200
b
sell
50
250
b
sell
150
100
The desired result is the balance for each row, the balance for the current stock item.

Try this formula-
=INDEX(BYROW(A2:A,LAMBDA(x,IF(x="",,SUM(FILTER(C2:C,A2:A=x,B2:B="buy",ROW(A2:A)<=ROW(x))))))-BYROW(A2:A,LAMBDA(x,IF(x="",,SUM(IFERROR(FILTER(C2:C,A2:A=x,B2:B="sell",ROW(A2:A)<=ROW(X))),0)))))
If you want to omit zero 0 values then use-
=BYROW(A2:A,LAMBDA(z,IF(z="",,INDEX(BYROW(A2:A,LAMBDA(x,IF(x="",,SUM(FILTER(C2:C,A2:A=x,B2:B="buy",ROW(A2:A)<=ROW(x))))))-BYROW(A2:A,LAMBDA(x,IF(x="",,SUM(IFERROR(FILTER(C2:C,A2:A=x,B2:B="sell",ROW(A2:A)<=ROW(X))),0)))),ROW(z)-1))))

Please see πŸ‘€sample file.
You can use the new functions:
LAMBDA + SCAN + BYROW
Here's the function to get inventory for all items as a string:
=SCAN("",lambda(item,op,s,mbuy, INDEX(if(item="",,SUBSTITUTE(item," ","_")&"🦊"& IF(op=mbuy,1,-1)*s)))(A4:A12,B4:B12,C4:C12,"buy"),LAMBDA(ini,s,if(s="",ini,
SUBSTITUTE(QUERY(BYROW(QUERY({if(ini="",{"",""}, INDEX(SPLIT(TRANSPOSE(SPLIT(ini,"🐺")),"🦊"))) ; split(s,"🦊")},"select Col1, sum(Col2) group by Col1 label sum(Col2) ''"),LAMBDA(a,join("🦊",a)&"🐺")),,2^99)," ",""))))
The output is:
a🦊500🐺
a🦊500🐺b🦊100🐺
a🦊390🐺b🦊100🐺
a🦊1390🐺b🦊100🐺
a🦊590🐺b🦊100🐺
a🦊590🐺b🦊300🐺
a🦊200🐺b🦊300🐺
a🦊200🐺b🦊250🐺
a🦊200🐺b🦊100🐺
It is a string representation of the balance
Next step is to count the balanse for adjacent item:
=LAMBDA(items,operations,quantities,buy_key,BYROW({items,SCAN("",lambda(item,op,s,mbuy, INDEX(if(item="",,SUBSTITUTE(item," ","_")&"🦊"& IF(op=mbuy,1,-1)*s)))(items,operations,quantities,buy_key),LAMBDA(ini,s,if(s="",ini,
SUBSTITUTE(QUERY(BYROW(QUERY({if(ini="",{"",""}, INDEX(SPLIT(TRANSPOSE(SPLIT(ini,"🐺")),"🦊"))) ; split(s,"🦊")},"select Col1, sum(Col2) group by Col1 label sum(Col2) ''"),LAMBDA(a,join("🦊",a)&"🐺")),,2^99)," ",""))))},LAMBDA(r,if(index(r,1)="",,VLOOKUP(substitute(index(r,1)," ","_") , if(index(r,2)="",{"",""}, INDEX(SPLIT(TRANSPOSE(SPLIT(index(r,2),"🐺")),"🦊"))) , 2, )))))(A4:A12,B4:B12,C4:C12,"buy")
The parameters are in the end. They are:
items,
operations,
quantities,
buy_key
buy_key is text "buy" in our case.
You can also build a Named Funtion:
The formula will show tips like this:
Notes
Please think of it as a great opportunity and I'm sure we'll be also able to calculate other comlicated things like FIFO/LIFO prices for each item.

Related

SUMIFS With Text and Date Comparison

theoretically I want to sum the total income each employee made for all the businesses.
Like this:
Employee 1 = Biz 1 income + Biz 2 income + Biz 3 income, etc...
Employee 2 = Biz 1 income + Biz 2 income + Biz 3 income, etc...
Technically and based on the table below, I want to sum a range in column R starting from cell R14 where the text in column W starting from W14 is the same in column P starting from cell P14 AND the name of the month in column V starting from cell V14 is equal to a month in date in column N starting from cell N14.
*
(I included the date because this is part of a budget planner so I need to categorize the data based on months.)*
I used this formula:
=SUMIFS(R14:R1013, P14:P1013, U14:U1013, TEXT(N14:N1013,"MMMM"),"="&T14:T1013)
But it prompts me with the error: Array arguments to sumifs are of different size
What could be wrong here? Does someone have any idea?
Thanks for your help in advance!
Try wrapping the text formula into ARRAYFORMULA to get the full column:
=SUMIFS(R14:R1013, P14:P1013, U14:U1013, ARRAYFORMULA(TEXT(N14:N1013,"MMMM")),"="&T14:T1013)
You can get the totals for all months and all employees with query(), like this:
=arrayformula(
query(
{ text(N13:N, "yyyy-MM"), O13:R },
"select Col1, Col3, sum(Col5)
where Col3 is not not null
group by Col1, Col3",
1
)
)

Google Sheet sum and multiply numbers based on dates

I am trying to sum the packages(B) if dates are equal, then compare this sum with the Orders per Day column(C) and multiply by the Rate Per Package(D) depending where the sum falls within the Orders per Day number.
I would like to return just the total number if possible.
DEMO:
https://docs.google.com/spreadsheets/d/1oSFnjogyXYybsqIYgQW2m45bbyAVBTKr3EVgxcGWFQo/edit?usp=sharing
You can try the following 2 formulas
In cell F2 place
=QUERY({A2:D},"select Col1, sum(Col2)
where Col1 is not null
group by Col1 label sum(Col2)''",0)
Then in cell H2 use
=ArrayFormula(IFS(G2:G>=80,G2:G*D9,
G2:G>=59,G2:G*D8,
G2:G>=39,G2:G*D7,
G2:G>=19,G2:G*D6,
G2:G>=14,G2:G*D5,
G2:G>=9,G2:G*D4,
G2:G>=4,G2:G*D3,
G2:G=1,G2:G*D2,
G2:G="",""))
(You can adjust ranges to your needs)
Functions used:
QUERY
ArrayFormula
IFS

QUERY: sum two columns and order by one in Google Sheets

I have the following data set:
Country Points Bonus_Points
---------------------------------------
United States 1 50
Brazil 3 50
France 7 30
United States 2 25
And now would like to query that data set and create a list with the following outcome where bonus points and points get summed up and the list is getting ordered by bonus points.
Country Points Bonus_Points
---------------------------------------
United States 3 75
Brazil 3 50
France 7 30
With
=QUERY(A1:C,"select A, B, sum(C) group by A, B order by sum(C) desc", 1)
I'm able to sum one column but somehow unable to manage to get the sum for B/points as well.
Any ideas?
See if this helps
=QUERY(A1:C,"select A, sum(B), sum(C) group by A order by sum(C) desc label sum(B) 'Points', sum(C) 'Bonus_Points'", 1)

How to dynamically create a string based on a range of values in Google Sheets

In Google Sheets, have a list of customers (col A) who bought a product, and they paid different prices (col B) depending on when they bought it and if they used a discount code.
I need to generate a string to show the number of people who bought the product at each price. So the string should look like this, showing that 1 customer paid Β£30, 4 customers paid Β£33.50, etc.
1#30 + 4#33.5 + 24#34 + 1#34.5 + 23*35 + 17#37 + 12#37.5
If price was a fixed amount then I could use COUNTIF and SUMIF and hard-code the price into the formula. But the price is constantly changing and the list is growing. So I need a formula that can create as long a string as necessary. How can this be done?
Here's the Google Sheet with the list of customers who purchased the product at different prices, and an example of the desired result:
https://docs.google.com/spreadsheets/d/1WmIXmkKmZOVcJ4dXxzy0CXbRCMya3uAdWk8yKhA50rw/edit?usp=sharing
Tim, nested QUERYs should do it. Try this (assuming your prices are in Column B as stated in the post):
=ArrayFormula(JOIN(" + ",QUERY(QUERY(B:B,"Select COUNT(B), B Where B Is Not Null Group By B Order By B Asc Label COUNT(B) ''",0),"Select Col1")&"#"&QUERY(QUERY(B:B,"Select COUNT(B), B Where B Is Not Null Group By B Order By B Asc Label COUNT(B) ''",0),"Select Col2")))
I encourage you to look at what the central QUERY does on its own:
QUERY(B:B,"Select COUNT(B), B Where B Is Not Null Group By B Order By B Asc Label COUNT(B) ''",0)
The other two outer QUERYs act on that data to concatenate the first column plus "#" plus the second column.
Then JOIN just takes that virtual vertical list and forms one string with " + " between each element.

What is the formula to calculate the average value by using sum product with condition?

In Google-Sheet, suppose I have this table:
Name Number Price
Item1 10 $400
Item2 10 $100
Item1 500 $50
Item3 5 $200
How can I calculate the average price of all item? For example, item1: (10*$400+500*$50)/510. I tried SUMPRODUCT, but it does not check the condition.
Assuming your data starts in A2 try
=ArrayFormula(query({A2:A5, B2:B5*C2:C5, B2:B5}, "Select Col1, sum(Col2)/sum(Col3) group by Col1 label sum(Col2)/sum(Col3)'' ", 0))
Meanwhile thanks to this video https://youtu.be/V-Tsa6NnxNY , I can solve my issue.
The formula is by adding a condition array using -- as the first argument in the SUMPRODUCT:
=SUMPRODUCT($A$2:$A$5=A2;$B$2:$B$5;$C$2:$C$5)/SUMIF($A$2:$A$5;A2;$B$2:$B$5)
Edit: Thanks to #JPV for the hint that -- does not necessary.

Resources