Forum Discussion
ShellarC
May 29, 2025Copper Contributor
Excel Sumifs
I need a formula to return how many shares of each stock I still own; Subtract # Sold from # Bought for each ticker and return the number remaining of each stock sorted by ticker. No return if the result is “0”. The result should be:
AFRM | 15 |
BBCP | 50 |
FRME | 10 |
GILL | 20 |
PLTR | 20 |
STAF | 150 |
TSLA | 10 |
Ticker | Trans | Units |
AFRM | Bought | 15 |
TSLA | Bought | 10 |
UPS | Bought | 10 |
BBCP | Bought | 100 |
GIII | Bought | 30 |
STAF | Bought | 2 |
BOXL | Bought | 500 |
STAF | Bought | 298 |
PLTR | Bought | 20 |
FRME | Bought | 19 |
FRME | Bought | 1 |
GIII | Sold | 10 |
FRME | Sold | 10 |
STAF | Sold | 6 |
STAF | Sold | 142 |
STAF | Sold | 2 |
BBCP | Sold | 50 |
BOXL | Sold | 500 |
The only issue was, in your sample table, all "Units" amounts were entered as positive numbers, so all solutions were written to subtract "Sold" from "Bought"; however, in your actual Stocks.xlsx data table, "Sold" amounts were entered as negative numbers. Simply modify any one of the suggested formulas to add "Sold" to "Bought" instead of subtracting.
The GROUPBY method also becomes significantly easier:
=LET( grp, GROUPBY(M[Ticker],M[Units],SUM,0,0), FILTER(grp,TAKE(grp,,-1)>0) )
Or, to include stocks with a negative balance:
=LET( grp, GROUPBY(M[Ticker],M[Units],SUM,0,0), FILTER(grp,TAKE(grp,,-1)) )
Also, I noticed the "Trans" column contains some "Dividend" entries (aside from just "Bought" and "Sold"). If these entries were to have amounts in the "Units" column that needed to be excluded, you can filter them out using the optional [filter_array] argument:
=LET( grp, GROUPBY(M[Ticker],M[Units],SUM,0,0,,M[Trans]<>"Dividend"), FILTER(grp,TAKE(grp,,-1)>0) )
Cheers!
16 Replies
Sort By
- ShellarCCopper Contributor
With everyones help I was able to use a supplied formula to extract stocks I own from all “Bought” and “Sold”. I have added more information and now would like to set up some charts to see the results. Here are my column headings. It would be fun to have, for instance, a pie chart showing the % or # of stocks in each Industry and or the Total Gain % by Stock or industry.
If you have signed into my file before, I updated the “Dashboard” and renamed the sheet with all the formulas to “Formulas” I would like the charts to appear on the “Dashboard” sheet. Or, I can try with some formatting and formula help. Thanks again to all and if I am overstepping my bounds by asking for more help, please let me know.
- ShellarCCopper Contributor
Thanks so much to everyone who contributed. There were several different formulas offered and they all returned the correct results. This was very helpful and will give me lots to study and learn as it is all new to me and, needless to say, a bit overwhelming. BRAVO
- ShellarCCopper Contributor
HansVogelaar, Patrick2788 and DJclements have all put a different formula on the “Dashboard” sheet in my file, each with the same results. Thank you all for your time. A study of this will teach me a lot. The problem is each result shows all stocks bought and sold and does not subtract sold from bought for each individual stock returning only the stocks still owned. There are only 10 stocks still owned (see Dashboard2). Thanks again to all of you.
- djclementsBronze Contributor
The only issue was, in your sample table, all "Units" amounts were entered as positive numbers, so all solutions were written to subtract "Sold" from "Bought"; however, in your actual Stocks.xlsx data table, "Sold" amounts were entered as negative numbers. Simply modify any one of the suggested formulas to add "Sold" to "Bought" instead of subtracting.
The GROUPBY method also becomes significantly easier:
=LET( grp, GROUPBY(M[Ticker],M[Units],SUM,0,0), FILTER(grp,TAKE(grp,,-1)>0) )
Or, to include stocks with a negative balance:
=LET( grp, GROUPBY(M[Ticker],M[Units],SUM,0,0), FILTER(grp,TAKE(grp,,-1)) )
Also, I noticed the "Trans" column contains some "Dividend" entries (aside from just "Bought" and "Sold"). If these entries were to have amounts in the "Units" column that needed to be excluded, you can filter them out using the optional [filter_array] argument:
=LET( grp, GROUPBY(M[Ticker],M[Units],SUM,0,0,,M[Trans]<>"Dividend"), FILTER(grp,TAKE(grp,,-1)>0) )
Cheers!
- Patrick2788Silver Contributor
I've added a solution with PIVOTBY. The total I'm getting is 9 stocks:
=LET( agg, PIVOTBY(M[Ticker], M[Trans], M[Units], SUM, 0, 0), ticker, CHOOSECOLS(agg, 1, 5), keep, TAKE(agg, , -1), return, FILTER(ticker, keep > 0), return )
I believe Apple is the 10th stock. The formula returns a 0 for that stock.
- ShellarCCopper Contributor
YES!! You did it!! Thanks so much. I don’t know why Apple is returning as a 0, but otherwise it is perfect!! You have no idea how much I have been through to get to this point. I am new at all of this and beginning to think it was an impossible project. 😄
- djclementsBronze Contributor
This is just a variation of what's already been shared:
=LET( tkr, UNIQUE(SORT(M[Ticker])), amt, LAMBDA(trn,SUMIFS(M[Units],M[Ticker],tkr,M[Trans],trn)), net, amt("Bought")-amt("Sold"), FILTER(HSTACK(tkr,net),net) )
Adjust the table/field names as needed. (EDIT: I already adjusted the table name to "M", so it will work with your Stocks.xlsx file.)
A couple of tips/comments:
- the UNIQUE function is significantly faster when the array is sorted first, so it's best to use UNIQUE-SORT instead of SORT-UNIQUE.
- to remove zeros from an array of numeric values, just pass the array to the include argument of the FILTER function... there is no need to perform a logical comparison, such as net<>0, because zeros are already interpreted as FALSE, and all other numeric values are interpreted as TRUE.
- PeterBartholomew1Silver Contributor
I am not sure which option I prefer
=LET( holding, GROUPBY( DemoTbl[Ticker], IF(DemoTbl[Transaction] = "Bought", 1, -1) * DemoTbl[Units], SUM, , 0 ), FILTER(holding, TAKE(holding, , -1) > 0) )
or
=LET( ticker, SORT(UNIQUE(DemoTbl[Ticker])), subtotals, SUMIFS( DemoTbl[Units], DemoTbl[Ticker], ticker, DemoTbl[Transaction], {"Bought", "Sold"} ), holding, BYROW({1, -1} * subtotals, SUM), FILTER(HSTACK(ticker, holding), holding > 0) )
- Patrick2788Silver Contributor
You can use GROUPBY to rollup the totals. The formula would be a bit shorter if there was no need to remove entries with 0:
=LET( values, IF(DemoTbl[Transaction] = "Sold", -DemoTbl[Units], DemoTbl[Units]), agg, GROUPBY(DemoTbl[Ticker], values, SUM, , 0), FILTER(agg, TAKE(agg, , -1) <> 0) )
- ShellarCCopper Contributor
Patrick, this looks like exactly what I want but when I copied and pasted the formula in my file, all it shows in the cell is the formula. It does not calculate or return as yours did. I’m very new at this and using the Excel 365 for business online. Thanks for your effort. Do you know where I can find someone who can work on my file online and fix the problem for me?
Make sure that
- The cell with the formula is not formatted as Text.
- The 'Show Formulas' button on the Formulas tab of the ribbon is not highlighted.
Could you attach a small sample workbook demonstrating the problem (without sensitive data), or if that is not possible, make it available through OneDrive, Google Drive, Dropbox or similar?
- m_tarlerBronze Contributor
there are a few options
you could use SUMIFS
=SUMIFS( [units], [Ticker], A1, [Trans], "Bought" ) - SUMIFS( [units], [Ticker], A1, [Trans], "Sold" )
you could do a direct calculation using SUMPRODUCT or something similar like:
=SUMPRODUCT ( [units]* IF([Trans]="Bought", 1, -1)*([Ticker]=A1) )
you could also just create a helper column that converts the units to +/- values and then do a single SUMIF or even a pivot table.
Try
=LET(tickers, SORT(UNIQUE(A2:A19)), remaining, SUMIFS($C$2:$C$19, $A$2:$A$19, tickers, $B$2:$B$19, "Bought")-SUMIFS($C$2:$C$19, $A$2:$A$19, tickers, $B$2:$B$19, "Sold"), combined, HSTACK(tickers, remaining), FILTER(combined, remaining>0))
- ShellarCCopper Contributor
The Transaction information (units bought and sold) is on the “Master” sheet. I would like the results on the “Dashboard”. Your formula works on the sample sheet but not the actual file.