In my example:
https://docs.google.com/spreadsheets/d/1QQNTw_r9-q-FqVNwUoYklup73niZCFyO0VDUYImP5fo/edit?usp=sharing
I'm using Google Forms as an eBay clone to sell rare items. Each bid is outputted from the form to the "Data" worksheet and then I have ArrayFormulas set up inside the "Processed" worksheet. The idea is that I want to process the bids so that we filter everything except the items with the highest bids. All data should be automatically updated, hence why I want to use ArrayFormulas.
My strategy is that in colum A, I first filter all unique items (=unique(filter(Data!A2:A,Data!A2:A<>""))) and end up with:
Jurassic Park 6-Pog Hologram Set
Princess the Bear TY Beanie Baby
Holographic 1st Ed Charizard
However, then in column B, we have to find the highest bid that corresponds to that unique item, e.g.:
=IF(ISBLANK(A2),,ArrayFormula(MAX(IF(Data!A2:A=A2,Data!B2:B))))
However, I don't want to have A2 be a single cell (A2) but an array (A2:A) so that it doesn't have to be manually copied down the rows. Similarly, I also want columns D and E to be automatic as well. Is there any way to achieve this?
Not sure if it would be considered easier than the previously posted answer, but in case this thread is found in the future, I think that this is a slightly simpler way to solve these kinds of problems:
Try this on a fresh tab in cell A1:
=FILTER(Data!A:D,COUNTIFS(Data!A:A,Data!A:A,Data!B:B,">"&Data!B:B)=0)
I did some research and found an answer very similar to what you were looking for. After rearranging the formula slightly to match your sheet, I was able to get this to work:
=ArrayFormula(vlookup(query({row(Data!A2:A),sort(Data!A2:C)},"select max(Col1) where Col2 <> '' group by Col2 label max(Col1)''",0),{row(Data!A2:A),sort(Data!A2:D)},{2,3,4,5},0))
This formula automatically populates product name, highest bid, username, and timestamp. I ran some tests, adding my own random names and values into the data sheet, and the formula worked great.
Reference: https://webapps.stackexchange.com/a/75637
use:
={A1:D1; SORTN(SORT(A2:D, 1, , 2, ), 9^9, 2, 1, )}
translated:
{A1:D1} - headers
SORT(A2:D, 1, , 2, ) - sort 1st column then 2nd column descending
9^9 - output all possible rows
2 - use 2nd mode of sortn which will group selected column
1 - selected column to be marged based on unique values
Related
I'm using this formula =IF(B24="","",IFERROR(INDEX(Sheet3!$C$3:$EE$3,,MIN(IF(Sheet3!$C$4:$EE$23=(Sheet2!C24&$K$18),COLUMN(Sheet3!$C:$EE)))-2),"NF")) to return a cell value in the top row of an array - a date in this case.
The search criteria is a combination of a unique project number and a 2 digit status alphanumerical code for the project. The array consists of 23 rows where combinations of the unique numbers are found, each with different status codes.
So essentially, I'm building a FILTERED project status dashboard that returns dates linked to the relevant project status.
The code above is inspired from ( LINK ) that uses a very similar layout, but it uses town suburbs linked to postal codes instead of project numbers and status codes. The formula works well (though, not entered as an array formula), but I don't have a single formula in the sheet, I have 3 300 occurrences of this formula.
The problem comes in when the user changes the FILTER - Excel recalculates the entire dashboard and that takes anywhere from 2 to 5 minutes to run. You hit the escape button and cancel the calculation after setting the filter, but Excel just starts calculating again after a few seconds. After that, Excel's response is sluggish and almost unusable. Yes - our hardware is pretty weak ...
I tried XLOOKUP as well, but can't set the "lookup_array" to an array ( Sheet3!$C$4:$EE$23 ) because it doesn't match the "return-array" ( Sheet3!$C$3:$EE$3 ) Concatenating the lookup arrays with & works, but then you'd have to do that for all 23 rows, and again, multiply that by 3 300.
I thought of creating a UDF, but the function will still be called every time Excel recalculates after filtering... 3 300 calls ...
Any ideas on how to make the INDEX version run faster, or make the XLOOKUP accept the lookup_array as Sheet3!$C$4:$EE$23 in the hopes that it'll run faster?
Thank you!
Not really an elegant solution, but it works.
I imported the dataset into a helper sheet, where I combined the cell value with the corresponding value in Column A for each row ( a name in this case ) and the date from row 1 for each column, using underscore as a delimiter.
This new data range was then given a unique name, EE in this case.
On a second helper sheet, using this formula =INDEX(Filtered,1+INT((ROW('Sheet1'!C3)-1)/COLUMNS(Filtered)),MOD(ROW('Sheet1'!C3)-1+COLUMNS(Filtered),COLUMNS(Filtered))+1) and drag it down till it returns an REF! error and going back one row before the error.
This transposes all the data into a single column G. Using =UNIQUE(SORT(FILTER(B3:B3240,B3:B3240<> "",""))) then gives me a filtered list of unique values in column H that I then run
=IF(H3="","",LEFT(H3, SEARCH("_",H3,1)-1)) for the first data value in I, and
=IF(H3="","",MID(H3, SEARCH("_",H3) + 1, SEARCH("_",H3,SEARCH("_",H3)+1) - SEARCH("_",H3) - 1)) for the middle data value in J, and
=IF(H3="","",IFERROR(TEXT(RIGHT(H3,5),"yyyy-mm-dd"),"NF")) for the last data value in K.
Then just run XLOOPUP across columns I, J and K.
Runs quick and easy and solves a few of the other issue I had as well.
The second data set has just over 35 000 rows - still works well and fast.
I have an attendance tracker in which I'm trying to account for each employee type per day.
I have a summary page (sheet1) in which I want the count of each type (A,B,C,D,E) based on the day in cell C2 whether or not they have an X on sheet2 for that day.
Using =COUNTIF(FILTER(Sheet2!$A$5:$GG$969,Sheet2!$A$5:$GG$5=$C$2),"X") I am able to get a total of "X" based on the date in cell C2.
However, I'm having trouble getting the formula to work counting each employee type.
=COUNTIFS(Sheet2!A5:AM31,A7,(FILTER(Sheet2!A5:AM31=C2)),"X")
This gives me an error "Array arguments to COUNTIFS are of different size."
I'm not sure how else to configure this. Below is a link to my sample sheet:
Appreciate any help!
https://docs.google.com/spreadsheets/d/1OdJTwbFsNcR1hO1qzMBGUY4iXcWgDwIAJmBAVE9cs0k/edit?usp=sharing
I think this would work, dragged down for the other groups.
=COUNTIFS(Sheet2!A$6:A$31,A7,FILTER(Sheet2!$6:$31,Sheet2!$5:$5=C$2),"X")
However, I would encourage you to look at this sample sheet (a copy of yours) where I've added a new tab called MK.Help, designed to be hidden, but used as a sort of helper tab to make all sorts of things you might like to do easier. Including the count you asked about.
It has one single formula in cell A2 where you can see what it does.
=ARRAYFORMULA(QUERY(SPLIT(FLATTEN(Sheet2!C5:5&"|"&Sheet2!A6:A31&"|"&Sheet2!B6:B31&"|"&Sheet2!C6:31),"|",0,0),"where Col3<>'' order by Col1"))
try:
={"", ""; QUERY(FILTER(Sheet2!A6:A31, FILTER(Sheet2!6:31, Sheet2!5:5=C2)="X"),
"select Col1,count(Col1) where Col1 is not null group by Col1 label count(Col1)''");
"Total", COUNTA(IFNA(FILTER(Sheet2!A6:A31, FILTER(Sheet2!6:31, Sheet2!5:5=C2)="X")))}
I am building a Sheet that will be taking imported data from other tabs and combining it in a summary sheet, for me to use elsewhere. The problem is, the tabs will be imported monthly, so there will be dozens of them very quickly, and I don't want to edit the query function every month. They will all have the same naming format, but I'm wondering if anyone has an idea about how to formulate the query with variables for the sheet name that I can pull from another cell. For example, I could import the tab names into another row, and have the query pull the sheet names from that row, but I am not familiar with how to do this. Here is an example of the query formula I'm using in a similar sheet:
=QUERY({'2019 TEAM SALES'!A2:ZY; '2020 TEAM SALES'!A2:ZY}, "select * Where Col1 is not null",1)
With this one, updated once a year isn't a big deal. But this new sheet will be monthly, so it will be unwieldy in just a few months. Is there a way using query to take the sheet names via cell info? Like if in row 1, I concatanate the sheet names with the range, so that A1 contains "'2019 TEAM SALES'!A2:ZY" and the next in B1 and so on, and then the query formula is:
=QUERY(A1:ZZ1, "select * Where Col1 is not null",1)
This way, it will always pull in all the current tabs necessary to combine.
Incidentally, I'm open to using other formulas or even a script to get this done, as it's the result I'm after, not the method.
I have seen a lot of answers similar to what's here, but this still forces extremely long formulas that I don't think are very efficient, given that this sheet will eventually have 50 or more tabs in it.
Thanks for any insights!
to generate list of sheets from start date to today's date +3 months in advance:
=ARRAYFORMULA(UNIQUE(TEXT(ROW(INDIRECT(
DATEVALUE("2020-4-1")&":"&
DATEVALUE(TODAY()+90))), "yyyy mmmm")))
converting it into ranges for query:
=ARRAYFORMULA("INDIRECT("""&UNIQUE(TEXT(ROW(INDIRECT(
DATEVALUE("2020-4-1")&":"&
DATEVALUE(TODAY()+90))), "yyyy mmmm"))&"!A:C"")")
to avoid possible errors for sheets that do not exist yet:
=ARRAYFORMULA("IFERROR(INDIRECT("""&UNIQUE(TEXT(ROW(INDIRECT(
DATEVALUE("2020-4-1")&":"&
DATEVALUE(TODAY()+90))), "yyyy mmmm"))&"!A:C""), {"&
TEXTJOIN(",", 1, SPLIT(REPT("""""♥", COLUMNS(A:C)), "♥"))&"})")
next we join it to create one single reference for query:
=ARRAYFORMULA("{"&TEXTJOIN("; ", 1,
"IFERROR(INDIRECT("""&UNIQUE(TEXT(ROW(INDIRECT(
DATEVALUE("2020-4-1")&":"&
DATEVALUE(TODAY()+90))), "yyyy mmmm"))&"!A:C""), {"&
TEXTJOIN(",", 1, SPLIT(REPT("""""♥", COLUMNS(A:C)), "♥"))&"})")&"}")
then we can build our query:
={""; ARRAYFORMULA("=QUERY({"&TEXTJOIN("; ", 1,
"IFERROR(INDIRECT("""&UNIQUE(TEXT(ROW(INDIRECT(
DATEVALUE("2020-4-1")&":"&
DATEVALUE(TODAY()+90))), "yyyy mmmm"))&"!A:C""), {"&
TEXTJOIN(",", 1, SPLIT(REPT("""""♥", COLUMNS(A:C)), "♥"))&"})")
&"}, ""select Col1,Col2 where Col3 is not null"", 0)")}
this way we generated our query formula as a string in G2 so the next step is either manually copy-paste this each month where you need it or you can use script which will auto-copy content of G2 and auto-paste it where you need it on any change so you dont need to touch it anymore
function onEdit() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1'); // sheet name
var src = sheet.getRange("G2"); // cell which holds the formula
var str = src.getValue();
var cell = sheet.getRange("G10"); // cell where I want the results
cell.setFormula(str);
}
spreadsheet demo
Solution
In order to use cell values (your variables) in your formula in order to automate the whole thing you can use the formula indirect which lets you use cell values in formulas. Therefore, you would end up with something like this:
=QUERY({INDIRECT(A1);INDIRECT(A1)}, "select * Where Col1 is not null",1)
where A1 is the cell containing 2019 TEAM SALES!A2:Y2
I hope this has helped you. Let me know if you need anything else or if you did not understood something. :)
I have two sheets: flight control and total hours control. Link to sheets.
Flight Control:
Total Hours:
What I want: On Total Hours, Sum the Flight Time if:
Column Name(L.D.1) matches row on Line; row Pilot matches row Pilot; cell has a value of 1.
I'm using this for cell C2, and it works:
=SUMIFS('Flight Time'!B:B;'Flight Time'!A:A;B2;'Flight Time'!C:C;"1")
And it works, giving me this:
However, this isn't very practical. I have to redo the formula every time a new pilot is introduced. And if I move columns around, it stops working.
What I need: To base my conditions on a text search. Something like:
If column name in {Flight Time!C:F} matches string on {row in col Line}, and Pilot = Pilot, and cell value = 1, SUM
In other words, I need to scale this. The final product will have dozens of pilots and L.D.s, so I need to be able to move things around.
My answer is similar to player0's but it anticipates a Flight Time tab that expands infinitely sideways as well as down.
You would start a new tab and place this formula in cell A1.
=ARRAYFORMULA(QUERY(SPLIT(TRANSPOSE(TRIM(SPLIT(QUERY(TRANSPOSE(QUERY('Flight Time'!C1:1&"|"&'Flight Time'!A2:A&"|"&OFFSET('Flight Time'!C2;;;ROWS('Flight Time'!C2:C);COLUMNS('Flight Time'!C2:2))*'Flight Time'!B2:B&CHAR(10);;9^99));;9^99);CHAR(10);0;0)));"|";0;0);"select Col1,Col2, SUM(Col3) where Col3>0 group by Col1,Col2 label Col1'Line',Col2'Pilot',SUM(Col3)'Total Hours'"))
Sometimes in complicated formulas like this, it can be difficult to translate to your real sheet if you haven't placed the sample data in exactly the same layout on the sample as it is on your real sheet. If that is the case here, change the layout of the sample so that it better matches your real data, and I can try to update the formula.
use:
=ARRAYFORMULA(SPLIT(
TRANSPOSE(QUERY(TRANSPOSE(QUERY(SPLIT(TRANSPOSE(SPLIT(QUERY(TRANSPOSE(QUERY(
IF(C2:F="",,"♠"&C1:F1&"♦"&A2:A&"♣♥"&B2:B),,999^99)),,999^99), "♠")), "♥"),
"select Col1,sum(Col2) group by Col1 label sum(Col2)''")),,999^99)), "♦♣"))
I'm using the below array formula to count the unique occurrences of text in column C using the agent name in column G as the reference. This is giving me multiple issues.
=SUM( --(FREQUENCY(IF(G3:G100000 = J5,MATCH(C3:C100000,C3:C100000,0)),ROW(C3:C100000) - ROW(C3) + 1) > 0))
Depending on the data set I'm using multiple agents will return a #N/A result and I can't figure out why.
Each dataset I'm using is 20k to 30k lines, so the formulas take a long time to process.
Any ideas how I could do this faster or better? Also any ideas why some agents get bad returns?
I am assuming that you are looking for the number of unique combinations of columns C and G.
Create a pivot table and check the box to add this data to the data model.
Drag both column headers to the Rows section, also drag one (of those same two) into the the values section.
click on the the field in the values section > value field settings > summarize values by > choose Distinct Count. This removes all duplicates.
Click the Row Labels filter and uncheck the blanks.
You can drop in new data then right-click on the pivot and refresh to see the new results. See the image.