The "mirror" sheet contains data.
Column B of the "bonus" sheet calculates the number of projects in a given month in which the specialist is involved.
=COUNTA(query(mirror!$A$2:$B, "select B where
A <= date'"&TEXT(EOMONTH($A6,0),"yyyy-mm-dd")&"'
and
A >= date'"&TEXT($A6,"yyyy-mm-dd")&"'
ORDER BY B"))
On the "mirror" there are no projects for Dec 2020 and Jan 2021.
The counts function substitutes 1 for the "bonus" in these months, although 0 is expected.
I've already broken my head, I don't know how to overcome it. I would be grateful for ideas.
Upd. Column A of the "bonus" sheet contains dates in the form of 8/1/2020, 9/1/2020, 10/1/2020, etc. beginning of the month.
In column A of the "mirror" sheet, the dates can be 10/5/2020, 10/31/2020, i.e. not necessarily the end of the month.
COUNTA counts an error as 1 (because it is "a non-null something"). So if your QUERY finds nothing, it will return an error — which will be counted as "one thing."
Try wrapping your QUERY in IFERROR, inside your COUNTA:
=COUNTA(IFERROR(QUERY(...)))
You can use SUMPRODUCT:
=SUMPRODUCT((MONTH(mirror!$A$2:$A)=MONTH(A2))*(YEAR(mirror!$A$2:$A)=YEAR(A2)))
Related
I can't figure out how to solve my issue in google spreadsheet.
I have a column with some packages we want to release on our website on specific random dates. Not all fields in these column are populated, some are empty. For the populated ones I want to assign a random number between a range (A,B) which I take from other fields and have a max number of duplicates (the number of duplicates I take from another field).
For example I have 60 packages and I need to assign them between 1 and 31 (days of current month) so that means I will have 2 duplicates/day and I will put my duplicate field value to 2. But these 60 packages are shown in 80 rows for example, 20 rows empty, so those must not have any number assigned to them.
I have tried a few solutions with RANDBETWEEN and SORT etc but I did not manage to make it work. Now I switched to writing a custom function but I have never written one in google app scripts before, so if any of you guys have experience with this I would highly appreciate.
Random dates
Use this formula to get random dates between start date and end date appended randomly and duplicated only twice.
=ArrayFormula(IF(A2:A="",,
VLOOKUP(A2:A,
{SORT({ FILTER(A2:A,A2:A<>""),
RANDARRAY(COUNTA( FILTER(A2:A,A2:A<>"")),1) },2,1),
TRANSPOSE(SPLIT(REPT(TEXTJOIN(";",1,($E$1+SEQUENCE(DATEDIF($E$1,$E$2,"D"),1,1)))&";",$E$5),";"))},3,0)))
Sort chronologically
01 - paste in G2.
=SORT(QUERY(UNIQUE(QUERY({B2:B},"Select * where Col1 is not null ")), "where Col1 is not null"),1,1)
02 - paste this formula in H2 and drag down.
=IF(G2="",,TEXTJOIN(", ",1,FILTER($A$2:$A,$B$2:$B=G2)))
I have a list of days and times in column A. Column B is a dollar value for each time value.
I want to get a specific time for each day and list the price in the next column. I have this right now:
The formula for column J is this:
=filter(A11:B,(mod(A11:A,1)*24)>=4.5,(mod(A11:A,1)*24)<=4.6)
This formula filters 4:30AM and the price associated with it.
Formula for column L is this:
=filter(A11:B,(mod(A11:A,1)*24)>=9.5,(mod(A11:A,1)*24)<=9.6)
Which filters only 9:30AM for each day and the price that goes with it.
As you can see, the dates stop matching when column J is 8/12/2021 and column L is 8/13/2021. This is because column L didn't have 9:30AM for 8/12/2021 so it skipped to 8/13/2021.
How can I make so that one of the columns skip a date if the other column doesn't match that time? I don't know if I explained that well but in the example above, column J should skip 8/12/2021 because column L didn't have 8/12/2021.
Another way of dealing with this issue is perhaps using UNIQUE and FILTER formulas but I'm not sure how that could be done. Any help would be greatly appreciated!
Here's a link to the spreadsheet: https://docs.google.com/spreadsheets/d/1TvP0_UsYJbLb5bscx2e4nTEnSkP5roBZpP8aIGdl414/edit?usp=sharing
I'm not 100% sure, but if you need to filter values so the time element is 09:30 and 04:30, then hide values where a date only occurs once (ie. no 09:30 value or no 04:30 value), you could use:
=arrayformula(filter(
filter(A11:B,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5)),
countif(int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))),int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))))>1)
)
Adjust >1 at the end to whatever logic you need (=2, <>1 etc).
You can also add sort() around everything if you need to.
Explanation:
It turns out that mod(A11,1)*24 doesn't round particularly well, so I suggest round(mod(A11:A,1)*24,2).
Therefore to filter the date/times for 9.30am and 4.30am, you can apply:
round(mod(A11:A,1)*24,2)=9.5
and
round(mod(A11:A,1)*24,2)=4.5
like this:
=arrayformula({filter(A11:B,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))})
filter is usually AND but to get OR condition it's filter(A:B,(A=1)+(A=2))
This gets the dates only:
=arrayformula(int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))))
Then this counts how many times a date appears:
=arrayformula(countif(int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5))),int(filter(A11:A,(round(mod(A11:A,1)*24,2)=9.5)+(round(mod(A11:A,1)*24,2)=4.5)))))
Combining the elements gets the solution.
I'll add a tab to your sheet.
You could filter each list on finding a match for each date (integer part of datetime) in the other list:
In J:
=filter(A11:B,(mod(A11:A,1)*24)>=4.5,(mod(A11:A,1)*24)<=4.6,isnumber(match(int(A11:A),int(filter(A11:A,(mod(A11:A,1)*24)>=9.5,(mod(A11:A,1)*24)<=9.6)),0)))
In L:
=filter(A11:B,(mod(A11:A,1)*24)>=9.5,(mod(A11:A,1)*24)<=9.6,isnumber(match(int(A11:A),int(filter(A11:A,(mod(A11:A,1)*24)>=4.5,(mod(A11:A,1)*24)<=4.6)),0)))
Note
Plz see Aresvik's answer for a possibly better approach to rounding, but note that 4:30 (3/16) actually has an exact representation as a binary decimal so rounding errors aren't an issue here.
I have 1 column of dates and 1 column of 'wins' recording 1 and -1 as wins and losses. I need a quick way to tally the score across each date (so I can graph the win-rates). Eg. 5th May 7 wins, 6th may -2 wins, etc. I have multiple entries for each date and several days to work through so I can't do it manually. What would be the simplest approach/formula to solve this issue?
I'm working in Google Sheets. If someone has a simple workaround in Excel too, the solution is welcome.
Try:
=SUMPRODUCT(($A$2:$A$12=$E$1)*($B$2:$B$12)) in cell E6
Data structure:
=QUERY(A1:B, "select A,sum(B)
where A is not null
group by A
label sum(B)''")
I have a spreadsheet which tracks weekly meeting attendance. I need to return the number of individuals who attended at least one meeting in the month, not the sum total of weekly meeting attendees. In other words, if a person attended 4 meetings in the month, the count is incremented by 1, not 4.
Names are listed in Column A, and the weeks in the month are listed in columns B-F (e.g. B2 is "Sep 2"; C2 is "Sep 9"; "D2 is "Sep 16", and so on.) When a person attends a meeting, the corresponding cell receives an "X".
So far, the only method I know I can use to return the number of unique or distinct meeting attendees is to first use a set of formulas in one column (H) to return whether an "X" is found in the corresponding rows, and then a second formula that references the range (in column H) containing the first set of formulas to return the number of TRUE results.
What I'm trying to do is use an ArrayFormula or something similar to give me the final number in just one shot. I'm currently using a COUNTIF function on values in a column range while the rows in that very range are populated using COUNTA functions.
How can I use just one formula to return the attendance count - not depending on that intermediary step/range in column H?
I can't seem to get an array formula to work correctly, and I haven't been able to find similar answers despite hours of searching. Apologies if there are similar questions already posted (I couldn't find one asking quite the same question as mine). Here's my best attempt so far:
=ArrayFormula(COUNTIF(COUNTA(B3:F17) > 0,TRUE)) ...which returns 1.
Here is an example spreadsheet with sample data.
In I22 I entered this formula
=countif(ArrayFormula(countif(if(B3:F17="X", row(B3:B17)), row(B3:B17))), ">0")
the formulas in H3:H17 are not used in this formula.
See if that works?
UPDATE: Some context: A log that is fed automatically by a IFTTT script contains all check-in and check-outs for employees that work in a factory. I need to build a report with the first check-in for each day, and the last check-out for each day (employees might check-out for lunch, but come back and only the first check-in and last check-out should count).
My current solution is to calculate a "is first checkin or last checkout?" Boolean, and then feed this log into a pivot table for reporting purposes filtering out the repeat entries
My spreadsheet will have data inserted in columns D & E by a third party application (IFTTT or google forms), and I would like to use an arrayformula to automatically calculate one column as data come ins from those applications.
(D)Date (E)Time Calc
January 6, Friday 15:06 TRUE
January 6, Friday 15:15 TRUE
January 9, Monday 8:36 TRUE
January 9, Monday 10:04 FALSE
January 9, Monday 10:37 FALSE
January 9, Monday 15:51 TRUE
The formular for Calc is
=or(MIN(filter(E:E,D:D=D2,B:B=B2))=E2,MAX(filter(E:E,D:D=D2,B:B=B2))=E2)
How can I transform this formula into an arrayformula? From my experimentations it seems that ArrayFormula doesn't mix well with Filter. Help is appreciated!
So, the goal is to determine, for each date, whether the value in column E is the highest or lowest for that date. I think this is too much logic to pack into a single formula, but can be expressed by two array formulas. The first one creates two helper columns:
=arrayformula(vlookup(filter(D:D, len(D:D)), query(D:E, "select D, min(E), max(E) group by D", 1), {2, 3}))
This is itself a combination of two formulas: the inner query gets the minimum and maximum of E for each date in D; then vlookup aligns these min-max values with the rows of the original table. The filtering by len(D:D) is for performance reasons, to avoid looking up a huge number of empty cells.
Suppose the first formula was in G1; then it formed the columns G and H, which leads to E1 being
=arrayformula(not((E:E > G:G) * (E:E < H:H)))
Note that and and or are not arrayformula-friendly, but can be replaced by * and + which result in booleans getting implicitly converted to 0-1. The not function is array-friendly, and is used here partly to get a boolean back from an integer.
Inspired by #zaq, I solved by re-engineering the spreadsheet and got the solution by using the following formula:
=query(query(Sheet1!B:E, "select D, min(E), max(E) group by D pivot C,B ", 1),"select Col1, Col3, Col10,Col4,Col11")
This formula transforms a log of employee check-in and check-outs into a summarized "hours worked" table that contains,for each day, and for every employee, the first check-in and the last check-out.