I am looking for a formula that can perform the "COUNT" equivalent of "SUMIF". I have in 'Sheet A' running records of attendance, with column A as "Last Name," column B is "First Name," and column C is "Attendance." The attendance column has values of "P, A, L" for present, absent, or late (respectively). The sheet is automatically updated each day, as new data for the day's attendance are appended at the bottom of the sheet.
In 'Sheet B' I have each student's name, matching the syntax in the above sheet ("Last Name" "First Name"). In this sheet, I want to be able to count the number of instances of each, "P", "A", and "L".
So...I want to be able to count in Sheet A the number of times a student has a "A" in the attendance column, conditionally by student name. I know that with SUMIF you can sum a range conditionally. COUNTIF does not work to appropriately filter the values by the student name. I was not able to get DCOUNTA to work either.
Open to any suggestions, no matter how complex.
For anyone curious, I came up with my own crude solution.
I created a new sheet for each: Present, Absent Late. Within each sheet I ran a query: =QUERY({'Imported Data'!A:C}, "select * where Col3 = 'P'"). This query returned every record where an individual was marked "P". Repeat for "A" and "L" on their respective sheets.
In my main sheet, which records count totals, I used the COUNTIF: =COUNTIF(Present!D:D,C2). I had a small problem to work around in this, as I had my data imported with a "Last Name" and "First Name" column, but could not COUNTIF across two columns. So, I created an ARRAYFORMULA in each Present/Absent/Late sheet. This concatenated the name values, so I could search against that singular value in my main sheet. This was present in D:1 of Present/Absent/Late: =Arrayformula(A:A&", "&B:B).
A little duplication and I was able to create my own, automatically updated, attendance tracker.
You seem to have gone to a great deal of effort to work around a problem that does not exist. In general, where SUMIF works for adding then a very similar COUNTIF should work for counting. Because in most groups of modest size neither first names nor surnames are likely to be unique (even if the combinations are likely to be) it is generally a good idea to assign IDs to people. Concatenating Last Name with First Name is effective but other options can be more compact.
Assuming in Sheet B you have P, A and L respectively in C1:E1 (a unique set of Last Name in ColumnA and First Name in ColumnB) then in C2 the following may be adequate if copied across to E2 and C2:E2 down to suit:
=COUNTIFS('Sheet A'!$A:$A,$A2,'Sheet A'!$B:$B,$B2,'Sheet A'!$C:$C,C$1)
Sheets Imported Data and Present seem irrelevant.
Related
I have a Google Form that collects a bunch of data from dropdown questions on a Sheet with each question going to one column (as normal). On separate sheets, I want to be able to count how many times each option is selected.
Here is an example of what the response sheet might look like. A, B, and C are all questions.
I would then have separate sheets for 'Person?', 'Place?', and 'Thing?'. The 'Person?' sheet would look something like this:
I want to be able to add in the count of each time the option appears for that question. In the example, notice that 'Napoleon" is in both Col A and Col C. If I just count the number of times 'Napoleon' appears, I will get '2' even though he only appears once in the "Person?" responses.
I originally used a QUERY function like =QUERY('Input Data'!1:1000, "select count(A) where A contains '"&$A2&"'",0). BUT, I need it to be dynamic. So the "Person?" question may not always be Col A. I want the Query (or whatever formula) to search the headers and only return the count of that option for that question even if the column location changes.
Okay, I figured it out! In case someone else is curious, I used this formula:
=QUERY({'Input Data'!A1:L}, "SELECT COUNT(Col"&MATCH("Person?", 'Input Data'!1:1,0)&") WHERE Col"&MATCH("Person?", 'Input Data'!1:1,0)&" CONTAINS '"&$A2&"' label COUNT(Col"&MATCH("Person?", 'Input Data'!1:1,0)&") ''",0)
Lee, I sent you a PM about your most recent post, but in the process, I came across this one. There is no need for multiple formulas or manual entry references. One formula can produce the entire report with headers, listing and counts:
=IFERROR(QUERY(FILTER(FILTER(A:L,A:A<>""),A1:L1="Person?"),"Select Col1, COUNT(Col1) GROUP BY Col1 ORDER BY Col1 LABEL COUNT(Col1) 'Count'",1),"No Matches")
Just fill in the header your looking for between the quotes where Person? is now.
The double FILTERs mean "Start with only rows where Col A is not null and Row 1 reads 'Person?'"
Then QUERY simply returns the unique names in the left column and their counts in the right column. Because the QUERY had a final parameter of 1, any existing header will be kept (in this case, the one you were searching for); and the created column will receive a header (i.e., LABEL) of Count.
IFERROR will give a friendly error message if no matches are found (in which case check that what you entered for the search in the formula exactly matches a column header in the range).
Hello stack overflowers.
I have recently been creating a nutrition tracker to better track and control my nutrition. However I have run into an issue. So currently I have a 1 sheet in the nutrition tracker which is a "database" of foods and their macro nutrients per gram. In this sheet, I will enter all the foods that I generally eat and their associated per G nutrients.
this food "database" sheet has the following columns.
FOOD NAME, CALORIES, PROTEIN, CARBS, OF WHICH SUGARS, FAT, OF WHICH SATURATED, FIBER, SALT
This database is then used as a reference, so that when I input each meal as I eat it, I can simply select the food from a drop down list and type the number of G in that meal, and the nutrients will all be calculated for me.
I currently have it setup so that I can select food from the drop down list generated by "foods" sheet, within each meal table I have created. This is then correctly filling in the rest of the columns as expected once I input a weight for each meal. There is however a huge problem.
As soon as the FOOD NAME column of the Foods sheet had values in it below row 7 (not sure why this row is the limit) the whole thing stops working, the data grabs based on VLOOKUP just return 0 and do not act as they are meant to. The strange thing is they work absolutely fine until I enter too many foods (7 foods) into the foods sheet.
Please find below a link to my spreadsheet, maybe you can duplicate it and play around a little yourselves to better understand the issue.
https://docs.google.com/spreadsheets/d/1orwih7s_Z4ew8G1vJcR6qlxyMpX8pqK-3Ynj42qQjcQ/edit?usp=sharing
(if you help me fix it, you will have a free nutrition tracking spreadsheet to help you take control of your diet aswell)
Thanks in advance.
In the June tab, clear all formulas in the range D11:K18.
Then enter in D11
=ArrayFormula(IF(LEN(B11:B18), IFERROR(VLOOKUP(B11:B18, FOODS!A:I, {2, 3, 4, 5, 6, 7}, 0)),))
This single formula will process all values entered in B11:B18.
Note the third parameter of VLOOKUP (set to false). If it is ommitted (as in your formula) it will default to 'true'. That means vlookup expects a 'sorted order' which may not be the case for your data.
References
VLOOKUP
try:
=INDEX(IF(B11:B18="";; IFNA(VLOOKUP(B11:B18; FOODS!A:I; COLUMN(B:G); ))))
Sounded so simple! I have a sheet called "Account", containing a running balance in column "G" and I have another sheet called "Performance", with a table which lists historical dates and column "D" needs to lookup the account balance on the day stated in column "A".
"Account" Sheet
"Performance" Sheet
For example, Performance!D2 should be "210,000.00".
Performance!D7 should be "110,000.00".
Performance!D9 would be "40,000.00".
To make this slightly more difficult I like to put formulas into the heading row as arrayformulas where possible, to avoid problems when copying and pasting data or adding new rows, etc.
I've tried many different possibilities and nothing has worked. I'm currently trying to make the following formula work, which is in Performance!D1.
=ARRAYFORMULA(if(row(D1:D) = 1, "Cash", VLOOKUP(A1:A, MIN('Balance'!A4:A <= A1:A), 7, 1)))
I've also tried some solutions involving MATCH(), FILTER(), VLOOKUP() and LOOKUP() but so far no cookie!
this should work:
=ARRAYFORMULA({"Cash";if(A2:A="",,VLOOKUP(A2:A, SORT('Account'!A4:G),7,TRUE))})
VLOOKUP(...,true) returns the value associated with the closest match in the first column without going over. Provided that the range into which you're doing the vlookup is sorted by the first column of that range.
I need to extract each individual person from a list that doesn't contain a certain activity (Project). Sounds easy but I can't quite get to the end of it.
Please check the example here on Sheet 2:
https://docs.google.com/spreadsheets/d/1qjbjXFCYj1qXrVVGNnhOj11asxT_o1xHWXerRqAl1UQ/edit#gid=2105763617
Here's the logic.
First I attempted to see if the individual only occurs once and if the Activity is not "Project"
=IF(A2<>"",IF(and(COUNTIF(A:A,A2)=1,B2<>"Project"),0,1),"")
Then I just extract the name that satisfies this criteria:
=query(ARRAYFORMULA(iF(I2:I=0,A2:A,"")), "where Col1 <>'' ")
This works, except there might be multiple assignments for the same person that does not contain the activity "Project" which my formula doesn't account for nor is it a simple dynamic arrayformula.
=UNIQUE(FILTER(A2:A, B2:B<>"Project"))
=UNIQUE(QUERY(A2:B, "select A where B <>'Project'", 0))
=UNIQUE(FILTER(A2:A, B2:B<>"Project",
NOT(REGEXMATCH(A2:A, "^"&TEXTJOIN("$|^", 1, FILTER(A:A, B:B="Project"))&"$"))))
While #player0's answer solves the question, it took a big performance hit on a sheet with >1000 rows.
Instead, I extracted all names that contained "Project" and then all names that did not contain "Project", then subtracted all the names from the first array to eliminate names that were in both.
=UNIQUE(FILTER(UNIQUE(FILTER(A2:A, B2:B<>"Project")), ISNA(MATCH(UNIQUE(FILTER(A2:A, B2:B<>"Project")), UNIQUE(FILTER(A2:A, B2:B="Project")),0))))
You may try this also:
{=IFERROR(INDEX($A$2:A$25,MATCH(0,IF($C$1<>$B$2:$B$25,COUNTIF($F$1:$F1,$A$2:$A$25), ""), 0)),"")}
N.B.
Cell C1 has criteria Project, using cell reference makes the formula
dynamic rather than hard coded.
Enter this formula in cell F2, finish with Ctrl+Shift+Enter,
and fill down.
I'm trying to make a database of students using Google Sheets. It contains info about students, groups and orders; orders can change students membership in groups (taken in a group, moved up to a new group, graduated, on leave, sent down). Here are sample database sheets and here is a detailed description of my DB structure (the sheet report_Groups is slightly changed, its previous variant, described on the link, is now named old_report_Groups).
I need a query that would select a list of present members of given group on the given date. That means that for each student I have to select
the name, the latter status before given date and corresponding group. And from this result select student names, where statuses are "Taken in" or "Moved Up" and group is the same as given one.
The problem is to select the latter status. It should be MAX(status), whose "since" date ≤ given date, but there's a well-known problem of selecting more than one field together with aggregate function. Here is a question which is very close to, but query from its "best" answer gives me error "QUERY:NO_COLUMN". I've even copied the sheet Raw from there and tried to perform proposed query (with the onliest modification — replacing commas with semicolons according to my locale restrictions) on the data it was reported to work on — same error (check Raw and report_Raw sheets in my DB). Other variant (via MMULT and TRANSPOSE) works, but it's perfomance is very poor.
What can you suggest me? Thanks in advance.
Update: I've found the solution with an issue (described in my answer).
To solve the issue I need to know an answer for a different question.
Here's the solution (with an issue described below).
A. Orders_Students is filtered for selecting rows, having "since" cell value ≤ given date (report_Groups!A2):
=QUERY(Orders_Students!B:E;"select E, B, C, D where E <= date '" & TEXT(report_Groups!A2;"yyyy-MM-dd") & "'";1)
This interim result is stored at the inner_report_Groups tab (it will be referenced few times in the next query).
B. inner_report_Groups is filtered for selecting MAX("since") values and corresponding row cell values for each student:
ARRAYFORMULA(VLOOKUP(QUERY({ROW(inner_report_Groups!A$2:A)\SORT(inner_report_Groups!A$2:D)};"select max(Col1) group by Col3 label max(Col1)''";0);{ROW(inner_report_Groups!A$2:A)\SORT(inner_report_Groups!A$2:D)};{3\4\5};0)
The formula above is used as inner query in report_Groups!D2 (also in D3, D4—with appropriate indeces).
C. The second query result is filtered to get students whose status is either "Taken in" or "Moved Up" and corresponding group is equal to the given group (report_Groups!B2 (also in B3, B4—with appropriate indeces)):
=TRANSPOSE(IFERROR(QUERY(<here is the formula from step B>);"select Col1 where Col3 = '" & B2 & "' and (Col2='Taken in' or Col2='Moved Up')";0)))
The formula above is used as outer query in report_Groups!D2 (also in D3, D4—with appropriate indeces). IFERROR is intended to display nothing if query result is #N/A.
That query displays the needed results as you can see in report_Groups tab. But as the query on step B searches the whole columns of inner_report_Groups, there's only a single given date can be analysed (or the query interim results for other given dates should be placed in different columns of inner_report_Groups or at the different tab. Is there any way to give an alias for an interim result to refer it in a single cell formula instead of keeping it on different tab?