I am trying to display some data in a specific manner, but have quite some issues with my last formula.
I have created this mock file to share (the original has many more tabs), this is just for this last formula that I need.
The data needs to be displayed only on the FSF [Score] tab as seen in columns I to N. The issue there is with the proper positioning of the displayed data in the rows. In row 4, I should have no data from column H onwards.
To give a proper explanation:
A-D is extracted from Responses with a query if the value in Responses!E || F contains TSF
E is extracted from Traffic Safety (Score)
F, H, P and so one, the ones with the numbers do not need editing
I gets the values from Responses based on multiple conditions
- if the person has FSF filed, search for the corresponding row and grab the correct values from the columns: AV, AW, AX, AY, AZ, BA if the language row has EN or EP, EQ, ER, ES, ET, EU if the value in the language cell is NL
The main issue I see with the formula in cell I2 is the
"where Col1 is not null"
which makes every row fill in one after the other.
Any help and advice is appreciated.
I tried some VLookup combinations as well, but could not figure it out. As you can see in each color block there, I have multiple formulas that I am trying to juggle with.
The closest I got was with this formula, but it put put the data in the exact row it was extracted from, instead of matching the B name.
=arrayformula(query(if(
(Responses!E2:E = "First-shift Feedback (FSF)")*(--NOT(ISNA(MATCH(TO_TEXT(B2:B),TO_TEXT(Responses!C2:C),0)))),
query(Responses!CA2:CF, "select CA, CB, CC", 0),
query(Responses!FU2:FZ, "select FU, FV, FW", 0)
),
"", 0
)
)
My apologies for asking an incomplete question previously.
This is what I'm trying to accomplish.
I'm building a TTRPG sheet that automatically combines dice rolls, bonuses (additive) and penalties (subtractive) from a variety of sources. All of this data is expressed as either dice notation (D4, D6, D8, D10, D12, D20, and D100) or an Integer (1, 2, 4, 6), or both (combined). These also include negative values (-1D4, -1D6, -2, etc.). The goal isn't to generate the random numbers, but instead combine like dice together for the player to roll manually (I tried the automatic random numbers... Players were not happy about it.)
So, the goal is to combine likes, so something like:
"1D6+1D6" would become "2D6". However, because penalties could outweigh the bonus, you can't combine "1D6+1D6+-1D6" into "1D6". (Since each of the rolls could be a different number, such as "6+6-1" compared to "1+1-6").
Additionally, Integers (2, 4, 6, 8, etc.) are by necessity handled in a different part of the sheet, so the goal is to strip the integers out from the output. (The reason for stripping them out has nothing to do with formula complexity, but other game factors that require it to be viewed separately.)
Here are some examples of typical inputs and expected outputs:
1D6+1D4+1D8+-1D4+1D6+2 = 1D4+-1D4+2D6+1D8 (Notice the integer is removed)
1D6+2+0+1+8 = 1D6 (Because all integers have been stripped out)
1D20+-1D4+2D6+0+1D6+-1D6 = +-1D4+3D6+-1D6+1D20
(Yes, negative numbers will have the "+-" in front of them).
My original "mostly working" formula was 2 solid pages long when copied/pasted into MS Word. This formula will be repeated THOUSANDS of times, so smaller/faster makes a huge difference in the overall scheme of things. Two previous amazing Spreadsheet Wizards (Player0 and TheMaster) gave great answers, but I failed to disclose the integer as a part of the overall process.
The table below shows the formula that works for the first example, but not the second (gives "2D" in the output).
For original explanation, see Google Sheets Formula for combining dice rolls
After the first split by +, check if the result is a TEXT and if not, FILTER it out:
=JOIN("+",BYROW(QUERY(REDUCE({"",""},SEQUENCE(2),LAMBDA(a,c,{a;QUERY({ARRAYFORMULA(SPLIT(TRANSPOSE(LAMBDA(ar,FILTER(ar,ISTEXT(ar)))(SPLIT(B1,"+"))),"D"))}," select sum(Col1),Col2 where Col1"&IF(c=1,">","<")&"0 group by Col2 label sum(Col1) ''")})),"order by Col2"),LAMBDA(r,JOIN("D",r))))
For no negative values, add a empty array {"",""} for NA:
=JOIN("+",BYROW(QUERY(REDUCE({"",""},SEQUENCE(2),LAMBDA(a,c,{a;IFNA(QUERY({ARRAYFORMULA(SPLIT(TRANSPOSE(LAMBDA(ar,FILTER(ar,ISTEXT(ar)))(SPLIT(B1,"+"))),"D"))},"select sum(Col1),Col2 where Col1"&IF(c=1,">","<")&"0 group by Col2 label sum(Col1) ''"),{"",""})})),"where Col1 is not null order by Col2"),LAMBDA(r,JOIN("D",r))))
try:
=INDEX(REGEXREPLACE(TEXTJOIN("+", 1, FLATTEN(QUERY(TRANSPOSE(QUERY(QUERY(IFERROR(IFNA(TRANSPOSE({
REGEXEXTRACT(SPLIT(C5, "+"), "^\d+")*1; REGEXEXTRACT(SPLIT(C5, "+"), "D\d+");
REGEXEXTRACT(SPLIT(C5, "+"), "^-\d+")*1; REGEXEXTRACT(SPLIT(C5, "+"), "D\d+");
REGEXEXTRACT(SPLIT(C5, "+"), "D(\d+)")*1}), 0)),
"select sum(Col1),Col2,'+',sum(Col3),Col4,Col5
where Col2 is not null group by Col2,Col4,Col5 order by Col5"),
"select Col1,Col2,Col3,Col4,Col5 offset 1", )),,9^9))), " |\+ 0 D\d+", ))
I am trying to grab advertising expenses for the day on the basis of country groups.
The date, and country for the record are in columns I, J and G respectively.
I am doing a VLOOKUP that references a sheet called advertising,
with the search key being a date and month together, and picking up the value column based on the country.
Then in order to average it out, I am dividing this lookup, which gives me the ad spend for a set of countries by the number of records for that date, month and country.
=(IF(OR(G4="Spain",G4="Portugal"),VLOOKUP(I4&J4,Advertising!$A$3:$AK,32,0)*IF(COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Spain","Portugal"})>0,1/COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Spain","Portugal"}),0),
IF(G4="France",VLOOKUP(I4&J4,Advertising!$A$3:$AK,33,0)*IF(COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"France"})>0,1/COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"France"}),0),
IF(G4="Italy",VLOOKUP(I4&J4,Advertising!$A$3:$AK,34,0)*IF(COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Italy"})>0,1/COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Italy"}),0),
IF(OR(G4="Belgium",G4="Netherlands"),VLOOKUP(I4&J4,Advertising!$A$3:$AK,35,0)*IF(COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Belgium","Netherlands"})>0,1/COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Belgium","Netherlands"}),0),
IF(G4="Sweden",VLOOKUP(I4&J4,Advertising!$A$3:$AK,36,0)*IF(COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Sweden"})>0,1/COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Sweden"}),0),
IF(G4="United Kingdom",VLOOKUP(I4&J4,Advertising!$A$3:$AK,37,0)*IF(COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"United Kingdom"})>0,1/COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"United Kingdom"}),0),
VLOOKUP(I4&J4,Advertising!$A$3:$AK,31,0)*IF(COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Germany","Austria","Bulgaria","Croatia","Cyprus","Australia","Denmark","Estonia","Finland","Greece","Hungary","Ireland","Latvia","Lithuania","Luxembourg","Malta","Norway","Romania","Russia","Slovakia","Slovenia","Switzerland","UAE"})>0,1/COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Germany","Austria","Bulgaria","Croatia","Cyprus","Australia","Denmark","Estonia","Finland","Greece","Hungary","Ireland","Latvia","Lithuania","Luxembourg","Malta","Norway","Romania","Russia","Slovakia","Slovenia","Switzerland","UAE"}),0)
)))))))
Unfortunately, this is returning an error for me.
As you can see, I have an IF clause to avoid division by zero.
However, I have somehow convinced myself that the error is being reurned in the averaging (i.e. division with the COUNTIFS) process, not in the VLOOKUP. I do believe my COUNTIFS are illegitimately and unexplainably returning zero.
e.g. for row 4 in the main sheet, which I have posted above,
=COUNTIFS(I$4:I,I4,J$4:J,J4,G$4:G,{"Germany","Austria","Bulgaria","Croatia","Cyprus","Australia","Denmark","Estonia","Finland","Greece","Hungary","Ireland","Latvia","Lithuania","Luxembourg","Malta","Norway","Romania","Russia","Slovakia","Slovenia","Switzerland","UAE"})
returns a zero. When I test it out with fewer countries, always including Austria, sometimes it returns zero, sometimes 1.
A sample sheet is at https://docs.google.com/spreadsheets/d/1YgK_D7FaTWtKcSts2uDiG7jlTRx2_IGrJ41wZr2qyak/edit?usp=sharing
P.S. I do not have enough reputation, but I would request one of the seniors to add "countifs" tag.
try in row 4:
=INDEX(IFNA(VLOOKUP(I4:I&"×"&J4:J,
{Advertising!B3:B&"×"&Advertising!C3:C, Advertising!B3:AK},
MATCH(G4:G, Advertising!A1:1, ), )))
update:
=INDEX(IFERROR(1/(1/(IFNA(VLOOKUP(I4:I&"×"&J4:J,
{Advertising!B3:B&"×"&Advertising!C3:C, Advertising!AE3:AK}, MATCH(IFNA(VLOOKUP(G4:G,
{{"France";"Germany";"Austria";"Bulgaria";"Croatia";"Cyprus";"Australia";"Denmark";"Estonia";"Finland";"Greece";"Hungary";"Ireland";"Latvia";"Lithuania";"Luxembourg";"Malta";"Norway";"Romania";"Russia";"Slovakia";"Slovenia";"Switzerland";"UAE";"Italy";"Belgium";"Netherlands";"Spain";"Portugal";"Sweden";"United Kingdom"},
{"France";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Italy";"Netherlands";"Netherlands";"Spain";"Spain";"Sweden";"United Kingdom"}},
2, )), Advertising!AD1:AK1, 0), ))/
COUNTIFS(I4:I&"×"&J4:J&IFNA(VLOOKUP(G4:G,
{{"France";"Germany";"Austria";"Bulgaria";"Croatia";"Cyprus";"Australia";"Denmark";"Estonia";"Finland";"Greece";"Hungary";"Ireland";"Latvia";"Lithuania";"Luxembourg";"Malta";"Norway";"Romania";"Russia";"Slovakia";"Slovenia";"Switzerland";"UAE";"Italy";"Belgium";"Netherlands";"Spain";"Portugal";"Sweden";"United Kingdom"},
{"France";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Italy";"Netherlands";"Netherlands";"Spain";"Spain";"Sweden";"United Kingdom"}},
2, )), I4:I&"×"&J4:J&IFNA(VLOOKUP(G4:G,
{{"France";"Germany";"Austria";"Bulgaria";"Croatia";"Cyprus";"Australia";"Denmark";"Estonia";"Finland";"Greece";"Hungary";"Ireland";"Latvia";"Lithuania";"Luxembourg";"Malta";"Norway";"Romania";"Russia";"Slovakia";"Slovenia";"Switzerland";"UAE";"Italy";"Belgium";"Netherlands";"Spain";"Portugal";"Sweden";"United Kingdom"},
{"France";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Germany";"Italy";"Netherlands";"Netherlands";"Spain";"Spain";"Sweden";"United Kingdom"}},
2, )))))))
or like this:
=INDEX(IFERROR(1/(1/(IFNA(VLOOKUP(I4:I&"×"&J4:J,
{Advertising!B3:B&"×"&Advertising!C3:C, Advertising!AE3:AK},
MATCH(IFNA(VLOOKUP(G4:G, Sheet3!A:B, 2, )), Advertising!AD1:AK1, 0), ))/
COUNTIFS(I4:I&"×"&J4:J&IFNA(VLOOKUP(G4:G, Sheet3!A:B, 2, )),
I4:I&"×"&J4:J&IFNA(VLOOKUP(G4:G, Sheet3!A:B, 2, )))))))
Use match(), like this:
=arrayformula(
iferror(
vlookup(
I4:I & J4:J,
{ Advertising!B3:B & Advertising!C3:C, Advertising!B3:AK },
match(G4:G, Advertising!A1:AK1, 0),
false
)
)
)
See the new Solution sheet in your sample spreadsheet. The formula is in cell P4.
Note that not all the country names in your search keys are present in the data.
I have a scoring spreadsheet for a competition I'm working on. Competitors' place/rank are converted into points towards the overall series based on a chart of corresponding values. For ties, the sum of the points covered by all of the tied places are split evenly among the tied competitors (i.e. 2-way tie for 3rd; if 3rd usually gets 10 points and 4th usually gets 8, these competitors will receive (10+8)/2 (2 being the # of tied competitors), so they each receive 9 points).
I have a formula which does this exact calculation:
=IFERROR(IF(ISBLANK($A4:$A),,SUM(INDEX(SeriesPoints, E4:E):INDEX(SeriesPoints, MIN(E4:E + COUNTIF(E$4:E, E4:E) - 1, ROWS(SeriesPoints)))) / COUNTIF(E$4:E, E4:E), 0))
Where 'SeriesPoints' is a 2 column array; column 1 is the places/ranks (1:125) and column 2 is their corresponding point values. Column 'E' is the competitors' rank from the competition.
I have been unable to convert this formula to an ARRAYFORMULA() so I can avoid dragging it down the entire sheet (possibly up to 1000+ competitors over the series).
I'm mildly proficient with MMULT(), so I understood that would be a good approach for switching out SUM(), however, I haven't been able to create a matrix of the values to be summed.
INDEX():INDEX() doesn't work with ARRAYFORMULA() so I've tried switching to VLOOKUP(). With VLOOKUP() I've been able to produce the start and end values of the range of values for a tie, but not the full list. For example, if there is a 3-way tie for 4th, I can produce the respective points for 4th and 6th (the bounds of the tie).
In an attempt to list out even just the numbers from 4:6, I've hit a wall converting what would be a simple ROW() or SEQUENCE() formula to a matrix/array.
The following formula produces an array of the upper and lower bounds of ties or the single place should there be no tie, although the single place gets repeated.
=ARRAYFORMULA(IF(COUNTIF(E$4:E,E4:E)=1,E4:E,{E4:E,E4:E+COUNTIF(E$4:E,E4:E)-1}))
I'm assuming if I can get VLOOKUP({#:#}) to fill properly, I'll be where I need to be.
From here, I feel confident in my abilities to wrap a VLOOKUP() for the actual point values, an MMULT() to sum across these rows for the total, then a simple division to produce the correct point value.
Spreadsheet: https://docs.google.com/spreadsheets/d/1lpNewR3p4i7ZHmlFGLlG1tLuxgO-6onSeH8mWTeclBw/edit?usp=sharing
Currently, my workspace is off to the right. The original formula is in F4 and my test codes are working on column G instead of E.
So for sample placements of 1,1,3,3,3,6,7,8 and sample points values of 1000, 850,738,663,633,603,573,550 I expect the output to be 925 for the two 1st place tied competitors, 678 for the tied 3rd places, 603 for 6th, 573 for 7th, and 550 for 8th.
I'd appreciate any and all help!
=ARRAYFORMULA(IFERROR(IFERROR(VLOOKUP(G4:G, QUERY({INDIRECT("G4:G"&counta(A4:A)+3),
VLOOKUP(ROW(INDIRECT("A1:A"&COUNTA(A4:A))), SeriesPoints, 2, 0)},
"select Col1,sum(Col2) group by Col1 label sum(Col2)''", 0), 2, 0))/
IFERROR(VLOOKUP(G4:G, QUERY(G4:G,
"select G,count(G) where G is not NULL group by G label count(G)''", 0), 2, 0))))
Is it possible to use Google Sheets VLOOKUP to get an exact match while using the sorted==TRUE option ?
Prefer to use VLOOKUP because I'm return multiple columns.
Would like to use the sort option because the data range is very large
(20,000 rows)
I didn't find any option in while reading the docs. Asking in case, there is an option I may have missed.
EDIT; I also checked the MATCH function, but the sort option is identical to VLOOKUP - so same situation.
EDIT; an ArrayFormula spreadsheet for users to reference
EDIT; full formula for my purposes for reference using Answer (double VLOOKUP) - very fast for even 20,000 rows
ARRAYFORMULA(IF(VLOOKUP(B:B,SORT(UNIQUE(B:B)),1,TRUE)=B:B,VLOOKUP(B:B,QUERY(A:B,"select B, count(A) group by B order by B label count(A) ''"),2,TRUE),0))
The double vlookup approach is to search for the primary key itself first, and only if it's found, proceed to retrieving the values from other columns.
If A:B is already sorted by A, and the value we look for is 42, then the formula is:
=if(vlookup(42, A:B, 1, true) = 42, vlookup(42, A:B, 2, true), na())
where the first vlookup checks if 42 is in column A, and only then passes the job to the second.
If A:B is not sorted, it can be sorted on the fly as in
=if(vlookup(42, sort(A:B), 1, true) = 42, vlookup(42, sort(A:B), 2, true), na())