GAS - Concatenate Unique List + Sumifs - google-sheets

I am really struggling with this to come up with an easy way to do this in Google Sheets.
I need a unique list with filter.
Fairly straight forward:
Unique(Filter(UniqueRange,FilterRange,Criteria)
I need to sumifs that list. If i do it one row at a time, its fairly straight forward pointing one of my criterias to the result of #1 and copy it downward:
sumifs(SumRange, Criteria1Range, Criteria1, Criteria2Range, Criteria2))
What i am struggling with is, i do not know how far that unique list will go. So i do not know how far down to copy #2's formula. Its no big deal if i had unlimited rows but i need to output the results of the above to all show up in a single cell with a character between the results because i am trying to make all this fit in a "calendar" for a dashboard. Can this even be done?
Sample Data:
Apple | 2
Orange | 3
Red | 1
Green | 4
Orange | 5
Red | 2
Simple result i have now by letting the uniques list grow as needed on the left column and copying formula #2 downward on the right hand column:
Apple | 2
Orange | 8
Red | 3
Green | 4
My question again is, is there a way to have the below result all show up in a single cell and toss in a hyphen between the results?
Apple - 2
Orange - 8
Red - 3
Green - 4
EDIT:
Thank you all for the help.
#theMayer
You pointed me in the right direction and ended up solving my issue. Thank you!
#I'-'I
Helper columns will just not work for my needs.
What i ended up doing is modifying the solution a little. I modified it to have a " _ " between the data because the data had hyphens in it and it was confusing. As for the number formatting, ill just leave it out for now. Here is my final code along with an additional date filter in the select query:
ARRAYFORMULA(TRIM(CONCATENATE(QUERY({CHAR(10)&$G$3:$G,$F$3:$F,$A$3:$A},"select Col1,' _ ',sum(Col2) where Col3 = date '" & text(C3,"yyyy-MM-dd") & "' group by Col1 label sum(Col2) ''"))))

=ARRAYFORMULA(TRIM(CONCATENATE(QUERY({CHAR(10)&A1:A6,--("-"&B1:B6)},"select Col1,sum(Col2) group by Col1 label sum(Col2) ''"))))

Related

How do I code a formula to apply to an entire column in Google sheets, even when you insert a new row?

I have a basic cash flow Google Sheet that I use to track my personal finances, cash in and out of my checking account.
Here's basically what it looks like:
Column A Column B Column C
Row 1 | Water bill | -50.00 | 400.00
Row 2 | Credit card | -300.00 | 100.00 >> the formula here is =sum(C1,B2)
Row 3 | Paycheck | 2000.00 | 2100.00 >> the formula here is =sum(C2,B3)
I project this out a full year. Anytime I want to add a row, I have to manually apply the formula in column C, and then I also have to fix the formula in the row just below it, which then fixes the problem for the rest of the sheet.
In Google Sheets, Is there a way for me to hard-code a formula for Column C that would allow me to insert a new row and always have it math perfectly without having to manually add the formula, and fix the formula in the row below it?
Let me know if there would be an easier way to do this by making fundamental changes to how it's setup - this is just how I've done it for so long, and I'm looking for a way to automate this going forward.
I've heard array formula might be helpful, but I'm not sure how to set it up.
There are many kinds of ArrayFormulas and LAMBDA functions. I suggest you look into them for different cases and uses. There is one kind in particular that would serve to your purposes:
=SCAN(0,B2:B,LAMBDA(a,v,a+v))
If you put this in C2 you'll have a cumulative sum row by row. Try it and let me know!
If you want to hide the results if column B is empty you can use another ARRAYFORMULA to check if B is empty it returns empty, either way returns the SCAN result:
=ARRAYFORMULA(IF(B2:B="","",SCAN(0,B2:B,LAMBDA(a,v,a+v))))
If you need to insert a new row in between then it's quite tedious as it will mess up the formulas below it, but if you just keep appending a new entry on the bottom row, then the formula will smartly mimic the behavior above it. Then you can simply do this:
Select the current last row, then click the small dot at the end and drag it down to as much as you want
OR, Ctrl+C (Copy) the last row, then select as much empty rows beneath it as you want, then Ctrl+V (Paste)

Data in Google sheet

I tried following formula for getting pcr data...
=importxml("https://niftyinvest.com/put-call-ratio/MARUTI?expiry=30JUN2022","//span[#class='white-text red darken-1']"
For different stocks the values are in 3 different colours red/blue/green depending on their values predefined.
How to get the common formula so that it can retrieve data in whatever colour plz ????
Other Data Links...
1- https://niftyinvest.com/put-call-ratio/indigo?expiry=30jun2022
2- https://niftyinvest.com/put-call-ratio/britannia?expiry=30jun2022
3- https://niftyinvest.com/put-call-ratio/MARUTI?expiry=30JUN2022
for Pcr:
=INDEX(IMPORTXML(A2,
"//span[#class='white-text red darken-1'] |
//span[#class='white-text light-blue lighten-1'] |
//span[#class='white-text green darken-1']"), 1)
for Intraday Pcr:
=INDEX(IMPORTXML(A2,
"//span[#class='white-text red darken-1'] |
//span[#class='white-text light-blue lighten-1'] |
//span[#class='white-text green darken-1']"), 2)
Try to use this generic xpath //h5//span[#class[contains(.,'white-text ')]]
=transpose(importxml(A2,"//h5//span[#class[contains(.,'white-text ')]]"))
edit: you can use queries to reorder columns and select by specific criteria.
=QUERY(IMPORTHTML("https://niftyinvest.com/put-call-ratio/indigo?expiry=30jun2022","table",1),"select Col1,Col2,Col3,Col4,Col5,Col6,Col7 where Col4>0.6 and Col7>0.7 and Col1 <> 'IOC' and Col1 <> 'POWERGRID ' ")

Getting Google sheets to give me the mode of a text for a specific user?

So I play an air combat simulator with a group on Digital Combat Simulator AKA DCS, for fun. I was asked to create a spreadsheet on google to help keep track of a bunch of statistics, to better understand stuff like: what kills us the most? What weapon are we the most accurate with? What weapon are we the least accurate with, so and so...
What I have and tried so far.
My issue right now is trying to get the spreadsheet to count up all the misses inputted into the spreadsheet for a certain person, in this case, Schmidt in aircraft 103, figure out which misses occur the most, in his case, the type of miss that occurs the most is "Energy Defeated" and then display it in the column that says "missile Defeat mode". This is specific to a person, so that's an additinal condition that I am having trouble programming for.
Thank you for your time and help.
https://docs.google.com/spreadsheets/d/1Cz1o06slDFuOCYnp8qlzF4icpscgEblHuJff7HAOXnY/edit?usp=sharing
here is a dummy spreadsheet if you want to look into the details.
Because you are matching the Pilot column, you need to use QUERY statements to gather the dataset, then ARRAY_CONSTRAIN to limit to what you want to display.
Formula
=iferror(
ARRAY_CONSTRAIN(
query(
query(
{$A$21:$A$33,$L$21:$L$33},
"select Col2, count(Col2) where Col1='"&A4&"'
group by Col2 order by count(Col2) desc limit 1"
,)
,"offset 1",)
,1,1)
,"")
Breaking this down:
The first thing that happens is you run a query against the Pilot and Outcome columns (A21:A33,L21:L33) based on the Pilot (A4) to find the outcomes (Col2), count each, then sort them in descending order so that the most common is listed first. Limit the return to just the top reason. This will produce a 2x2 array of results.
| | count |
| ---------------- | ----- |
| Sensor Defeated | 2 |
So we run the second query to remove the first row:
| Sensor Defeated | 2 |
Then, Array_Constrain lets us lop off the second column (containing the count of times that outcome was found), leaving just the most-found outcome:
Sensor Defeated
It's all wrapped up in a nice iferror statement so you can have blanks if the pilot isn't found in the query range.
Just copy that formula into each cell in G2 - G16 and you're good to go.
Example
Here is the formula in action on a copy of your sheet.

Count numbers in text field

I have a spreadsheet that contains cells similar to this:
AAA Up 3
AAA Down 2
BBB Up 1
BBB Down 3
CCC Up 5
CCC Down 2
So it's always some sort of text, followed by Up or Down, and then how often it went up or down. I'd like to count how many times went up or down. In this example the total of Up would be 9, and Down 7. How do I do that in Excel/Google Sheets? I couldn't find a combination of functions that would help me get this problem solved.
I forgot to mention that each row here is one cell. Or in other words, all of the text above is one column only.
Thank you.
It's straightforward in Google Sheets:
=ArrayFormula(query(split(A:A," "),"select Col2,sum(Col3) where Col3 is not null group by Col2"))
Here is another suggestion.
A single formula, shorter than the one by Erik and more robust than the one by Tom.
=QUERY(INDEX(SPLIT(REGEXEXTRACT(A:A,"\w+ \d+$")," ")),
"select Col1, sum(Col2) where Col2 is not null group by Col1")
Functions used:
QUERY
INDEX
SPLIT
REGEXEXTRACT
If we can assume only 1 or 2 digits in the number field then for Up use:
=SUMPRODUCT(--(RIGHT(A1:A6,2))*ISNUMBER(SEARCH(" Up ",A1:A6)))
and for Down use:
=SUMPRODUCT(--(RIGHT(A1:A6,2))*ISNUMBER(SEARCH(" Down ",A1:A6)))
There are many replies here. I'll suggest another and then tell you why it may be different:
=ArrayFormula(QUERY(SPLIT(REGEXEXTRACT(FILTER(A2:A,A2:A<>"")," ([UpDown]+ \d+)$")," ",0),"Select Col1, SUM(Col2) GROUP BY Col1 Label SUM(Col2) ''"))
It's not clear from your post whether "AAA," "BBB," etc. will be solid blocks of alpha-numeric information in your real application. I can imagine that the opening text might actually be strings with spaces (e.g., "Joe Schmoe from Idaho UP 3"). If so, some of the other formulas I see here will fail; but this formula will account for that.
Though a bit crude, but it'll work. Let us assume your data is in A2:A7 like this
AAAAAA Up 300
AAA Down 2
BBB Up 10
BBB Down 3
CCC Up 5
CCC Down 2
Enter this array formula in cell B2 (and copy downwards) [don't forget to use ctrl+shift+enter)
=VALUE(RIGHT(A2,LEN(A2)-MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},A2&"0123456789"))+1))
Enter Up in C1 , Down in D1 and then enter this formula in C2 (and copy downwards and then rightwards so that cells C2:D7 are filled with this formula)
=--NOT(ISERROR(FIND(C$1,$A2)))
Now to sum Up values - use this formula
=SUMPRODUCT(C2:C7,B2:B7)
and for Down use this
=SUMPRODUCT(D2:D7,B2:B7)
You'll get desired sums
I see that a game of "whose is shorter" has begun. First (for those who don't know), a shorter formula doesn't necessary hold any advantages over a longer one as far as processing ability or speed. In fact, a formula that is a bit longer may hold benefits in terms of ease of understanding, getting rid of superfluous elements, etc.
That said, it seems to be, as I say, a sort of game for people who write formulas often to cut characters. So with only fun in mind, I toss this into the hat as well:
={"Up",SUM(FILTER(SPLIT(A2:A," "),FIND(" Up",A2:A)));"Down",SUM(FILTER(SPLIT(A2:A," "),FIND(" Down",A2:A)))}
It's shorter than the one by marikamitsos and gets rid of the "sum" header, which may or may not be wanted. It also allows for "Up" to be at the top without extra code (or by switching the clauses around, it gains no length and allows for "Down" to be at the top if desired).

Is there a multiple-and-add formula in Google's spreadsheet?

What I want is to easily multiply a number by another number for each column and add them up at the end in Google Sheets. For example:
User | Points 1 | Points 2 | Points 3 | Total
| 5 | 1 | 4 |
-----+----------+----------+----------+------
Jane | 2 | 3 | 0 | 13 (2*5 + 3*1 + 0*4)
John | 1 | 11 | 4 | 32 (1*5 + 11*1 + 4*4)
So it's easy enough to make this formula for the total:
= B3*$B$2 + C3*$C$2 + D3*$D$2
The problem is I frequently need to insert additional columns or even remove some columns. So then I have to mess with all the formulas. It's a pain... we have many spreadsheets with these formulas. I wish there was a formula like SUM(B3:D3) where I could just specify a range. Is there anything like MULTIPLY_AND_SUM(B2:D2, B3:D3) that would do this? Then I could insert columns in the middle and the range would still work.
There is a built in function in Google Sheets that does exactly what you are looking for: SUMPRODUCT.
In your example the formula would be:
=sumproduct(B$2:D$2,B3:D3)
Click here for more information about this function.
You can accomplish that without requiring a special-purpose function.
In E3, try this (and copy it to the rest of your rows):
=sum(arrayformula(B3:D3*B$2:D$2))
You can read about arrayformula here.
As long as you introduce new columns between B and D, this formula will automatically adjust. If you add new columns outside of that range, you'll need to edit (and cut & paste).
On it's own, arrayformula(B3:D3*B$2:D$2) operates over each value in B3:D3 in turn, multiplying it by the corresponding value in B$2:D$2. (Note the use of absolute references to 'lock down' to row 2.) The result in this case is three values, [10,3,0], arranged horizontally in three rows because that matches the dimensions of the ranges.
The enveloping sum() function adds up the values of the array produced by arrayformula, which is 13 in this case.
As you copy that formula to other rows, the relative range references get updated for the new row.

Resources