I have a bit of an issue. Why else would I be here? ;)
I have a table (table1) and in this table I have two columns that I would like to count if the dates differ (Task due date and Task complete date). What I want to do is calculate the task that are past due or delivered on time. (Yes I am aware that free templates are available, this is mainly to learn more on working with Excel)
In my calculation sheet, I want to count:
The amount of Task complete dates that are prior or equal (<=) then the Task due date
The amount of Task complete dates that are past (>) the Task due date
I think that the issue lays in in the COUNTIF statement because it seems to only accept one array (the count array) after that comes the criteria which does not seem to handle arrays.
I also tried =SUMPRODUCT(COUNTIF(Table1[Task complete date];"<=" & Table1[Task due date])) But this gives me a value of 8 (while I have two possible matches)
According to This tutorial, I should get a return value of 1 and 0 but looking at the calculation steps I get: SUMPRODUCT({1;1;2;2;2;0;0;0;0;0}) This would off course be where the value of 8 comes from.
Is there any way around this? Do I need to add in some kind of if statement or some kind of pre-check?
Here is a link to the excel document with some test data
Oh and by the way: the comma delimitter in my country is a ; and not an actual comma. That is why there are semicolumns where some of you would expect a comma.
Any help would be greatly appreciated. Thank you all in advance.
Tinus
You could add a date check to column M in your "Project tasks" table: =IF(COUNTBLANK(F4)+COUNTBLANK(K4)=0,IF([#[Task due date]]<=[#[Task complete date]],"On time","Past Due"),"").
Then you could use =COUNTIF(Table1[Date check],[#[on time/past due]]) in column K of your "Data" sheet.
P.S. If you need a translation of the given function you may check https://de.excel-translator.de/
The reason that you are getting values above 1 is that your COUNTIF is actually comparing each value in Table1[Task complete date] to each value in Table1[Task due date]. e.g. if the [Task complete date] is 1 Jan, it will count how many [Task due date] values are greater than or equal to 1 Jan, so that could be 2, for example. Then it moves to the next value in [Task complete date] and does the same.
So you would need to do:
The amount of Task complete dates that are prior or equal (<=) then the Task due date
=SUM(--(Table1[Task complete date]<=Table1[Task due date]))
The amount of Task complete dates that are past (>) the Task due date
=SUM(--(Table1[Task complete date]>Table1[Task due date]))
Additional Notes
For versions of Excel before 2019 or Excel 365, the formulas above must be entered as array formulas, so you have to enter them with CTRL+SHIFT+ENTER. For your Google Sheets version, these must also be array formulas, but you will also need some additional filtering to get it to ignore blank cells. You could do:
=ArrayFormula(SUM((K4:K24<=F4:F24)*(K4:K24>0)))
and
=ArrayFormula(SUM((K4:K24>F4:F24)*(K4:K24>0)))
Related
this is the another version of my first question and I hope I can best explain my problem this time.
From the Table 1, I want to auto populate Table 2 based on this conditions and criteria (below)
From the example, I basically have 3 initial criteria, ON CALL, AVAILABLE, and BREAK
Now for the conditions, I want all Agents from status ON CALL, AVAILABLE, BREAK from Table 1 to be populated on Table 2 (optional: If possible, I wanted only to show agents that HAS a duration of 4 minutes and above from each status). My problem is I always refresh TABLE 1 so I can get an updated data. My goal here is to monitor our agents their current Status and Running Duration, and from that I only need to check on the table 2 so I would see right away who has the highest running duration from each status to be called out.
I only tried MAXIFS function but my problem with it, I can only show 1 result from each status.
What I wanted is to fully populate Table 2 from the data on Table 1. If this is possible with ROW function that would be great, because what I really wanted is a clean Table, and it should only load data if the criteria is met.
Thank you
Something you may be interested in doing is utilizing HSTACK. I am not sure how you are currently obtaining the Agents name in the adjacent column to the results but this would populate both the Agent along with the Duration.
=HSTACK(INDEX(A:C,MATCH(SORT(FILTER(C:C,(C:C>=TIMEVALUE("00:04:00"))*(B:B=H2),""),1,1),C:C,0),1),TEXT(SORT(FILTER(C:C,(C:C>=TIMEVALUE("00:04:00"))*(B:B=H2),""),1,1),"[h]:mm:ss"))
This formula checks Table 1 for any Agent with the status referenced in H2 (Available) that also has a time greater than or equal to 4 mins. It then sorts the results in ascending order and populates the Agent Name that is associated with it. It is dynamic and will produce a table like the following:
Just update the formula to check for "On Call" and "BreaK" as desired for the other two.
UPDATE:
As for conditional formatting, this is utilizing the custom formula posted in the comments. If the formatting of the times are of [h]:mm:ss then you would be looking to do something like this. Notice the 2 cells are highlighted for being between 4 mins and 5 mins.
This is an array solution that spill all the results at once. We use a user LAMBDA function GET to avoid repetition of the same calculation using as input parameter the status (s). The formula works for durations in time format or in text format with a minor modification. On cell E2 put the following formula for durations in time format:
=LET(GET, LAMBDA(s, FILTER(HSTACK(A:A, C:C), (B:B=s)
* IFERROR(C:C >= TIME(0,4,0), FALSE))),
IFERROR(HSTACK(GET("ON CALL"), GET("Available"), GET("Break")),""))
Here is the output:
For durations as text in hh:mm:ss format just replace: C:C >= TIME(0,4,0) with TIMEVALUE(C:C) >= TIME(0,4,0).
The GET function is reused to generate the result for each status. The last IFERROR call is used to remove #N/A values generated by HSTACK when the column doesn't have the maximum number of rows of the output.
The first IFERROR is used to treat the case when the value is not numeric, such has the header. This is because we are using the entire column as input range. Using entire columns produce more concise formulas with less maintenance effort, but it is less efficient, unless you have a good reason to have an open range. If you want to use a specific range instead for the data of the table, then you can remove it and update the ranges accordingly.
I am searching for a formula solution that would summarize hours based on two conditions (date - column a, activity - column b). More precise, I want to summarize hours of sleep each day with array formula that would include whole column range.
The data looks like this:
When I define exact range the formula works.
{=IF(A2:A10=I$6;IF(B2:B10="Sleep";(D2:D10)-(C2:C10);0);0)}
But when I try to include whole column it returns 0.
{=IF(A:A=I$6;IF(B:B="Sleep";(D:D)-(C:C);0);0)}
Thank you!
You can use the entire column using an IF statement inside SUM or SUMPRODUCT. It ensures the time differences is only carried out on valid rows of the input data:
=SUM(IF(($A:$A=F1) * ($B:$B="Sleep"), ($D:$D + ($C:$C > $D:$D) - $C:$C),0))
Then just extend the formula to the right (notice the $-notation).
Using SUM or SUMPRODUCT directly produces an error (#VALUE!), for example:
=SUM(($A:$A=F1) * ($B:$B="Sleep") * ($D:$D + ($C:$C > $D:$D) - $C:$C))
because it doesn't filter first for valid rows where the subtract doesn't produce an error.
Here is the output:
Note: You need to try for your excel version, for O365 it works, but it has to be tested for an older version.
The calculation for time differences (the parenthesis is required):
$D:$D + ($C:$C > $D:$D) - $C:$C
Ensures that when the end date represents a time from the next day as it is in row 5, it adds 1, to consider the next day. You can achieve the same using another IF (longer but may be easier to understand):
IF($D:$D > $C:$C, $D:$D - $C:$C, (1+$D:$D) - $C:$C)
Performance: Please keep in mind #JosWoolley comments below, about performance. Usually, indicating the entire column in the formula instead of a specific range, forces Excel to check all rows (current maximum: 1,048,576). No significant impact for invoking the formula just one time, but for multiple invocations, it will be a significant impact on performance or Excel can even not respond.
Take a look at this link for some little-known insight from Microsoft. Microsoft deliberately prevents the use of entire columns in some formulas that internally use arrays:
Excel Limitations
In particular, see this paragraph.
If you designate your data as an Excel table then you could use structured referencing, as in the example below
=SUMPRODUCT(((Schedule[End]+(Schedule[Start]>Schedule[End]))-Schedule[Start])*(Schedule[Activity]="Sleep")*(Schedule[Date]=I6))
but you should recognise that the organisation of your data does not permit the (by-date) analysis you require, e.g. most of the sleep attributable to Jan 22nd is properly attributable to Jan 23rd but that can't be reflected in the summary, as you have treated the end time on Jan 22nd as being 16 hours before the start time...
(cells I7:K7 have the custom number format [hh]:mm)
I'm not too sure how to word this problem so, I apologize for the vagueness. Here is what I am trying to do though:
I have a large Excel table with a ton of values, I however, only care about 3 columns. The three columns I have are "Project Name", "Active/Planned", and "Week of Month". Here is an example of some values I would have:
Project Name
Active/Planned
Week of Month
StoreProj
Active
2021-07 Jul-Wk1
SecProj
Planned
2021-07 Jul-Wk2
StoreProj
Active
2021-07 Jul-Wk1
Now, I have used a formula to get the number of projects based on a specific week month and avoiding duplicate values for the project name. The code I used returns an integer of the number of projects. Here is what I used:
=IFERROR(ROWS(UNIQUE(FILTER(Table[Project Name],Table[Week of Month]=2021-07 Jul-Wk1))), 0)
This works as intended. Now the issue I am running into is that I need to filter through these rows as I did previously, but now I need to include the "Active/Planned" column. So, I want to be able to see how many projects I have based off of the week of the month and return a number of projects (excluding duplicate names), but be able to filter through that integer output based off of the active/planned projects. So in a perfect scenario I can choose the week of month and if the project is "Active" or "Planned" and see the amount of projects I have.
This might be an easy fix so I apologize, I am just stumped, any help would be greatly appreciated. Thanks!
Work through that step by step, you've got the FILTER function which is giving data to the UNIQUE function, to the ROWS function, and then your IFERROR. However, the data about whether each line/row is 'Active' or 'planned' isn't passed out beyond the FILTER function, so can't be used by anything further on in the above sequence.
Boring theoretical advice out the way, try this;
=COUNT(IF(UNIQUE(FILTER( Table[[Project Name]:[Active/Planned]], Table[Week of Month] = "2021-07 Jul-wk1"))= "Active", 1))
Explanation:
FILTER(...) outputs records with the relevant date filter, however it outputs Table[[Project Name]:[Active/Planned]] - both columns, to ensure all relevant data is there.
UNIQUE(...) Then narrows that down to unique values, although by this stage I'm not 100% sure you need this.
IF(... = "Active", 1) then replaces the 'Active' outputs with 1s
COUNT() returns the number of cells in the above that contain a number (the 1s from the IF())
Yes, you can't use COUNTIF on arrays (and all except that last bullet point above are outputting arrays not single values) - and no, I didn't know that before attempting to answer this question, found it over at a different question!
What I'm trying to do is give a due date based on an input date, type of review, and department.
For example if the department is ABC and the review is retrospective, the due date will be the input date + 30 days.
But if the department is ABC and the review is concurrent, then the due date will be input date + 1 day.
I know I can concatenate the department and review into the vlookup table but I'm not so sure how to get the output to be the due date that I want.
Can anyone help?
EDIT:
Per the first answer below, I hashed out an input table with concatenated columns just in case I needed them. It is a bit more complicated than I originally thought.
Input table with date logic
I'd love to simply edit the source data but the report isn't readily available in the database. Could I still use the suggestions below?
Assuming you have a lookup table for the number of days to add depending upon the department and review type similar to the one below, you can use an INDEX/MATCH/MATCH and simply add it to the input date:
=$A2+INDEX($H$4:$J$5,MATCH($B2,$G$4:$G$5,0),MATCH($C2,$H$3:$J$3,0))
SOLUTION FOR AN ALTERNATIVE LOOKUP TABLE LAYOUT
If your layout table is more like as below, you can use a MINIFS formula (or MAXIFS if you would prefer):
=$A2+MINIFS($I$3:$I$8,$G$3:$G$8,$B2,$H$3:$H$8,$C2)
I'm trying to put together a company excel sheet to keep track of the tickets we give out to senior sales to take out clients.
I put together a "Soonest Available Ticket" section to easily ID what games are coming up we still have tickets for. However, we don't give out tickets to every game and so I want to have these formulas return dates only of games that have not happened yet. Right now, they simply return the first unclaimed game which are all in the past.
I've tinkered with a few formulas, but I can't figure out how to only command it to look at dates today or later. Any ideas?
Below, in order, are my original Index formula, and then my attempts to only find upcoming games.
=IFERROR(INDEX(CubsDate,MATCH("Avail*",CubsTicketStatus,0),1),"Filled")
=IF(WhiteSoxDate>NOW(),IFERROR(INDEX(WhiteSoxDate,MATCH("Avail*",WhiteSoxTicketStatus,0),1),"Filled"),"Season Ended")
=IF(WhiteSoxDate>NOW(),INDEX(WhiteSoxDate,MATCH("Avail*",WhiteSoxTicketStatus,0),1),"Season Ended")
{=INDEX(WhiteSoxDate,(MATCH("Av*"&"*">TODAY(),WhiteSoxTicketStatus&WhiteSoxDate,0)))}
Assuming that "CubsDate" and "CubsTicketStatus" are named ranges of cells (the former containing dates and the latter the status, either "Avail" or "Filled"), then perhaps this will do what you want:
{=INDEX(CubsDate,MATCH(1,(CubsTicketStatus="Avail")*(CubsDate>TODAY()),0))}
Note that if there is no matching date after the current date, you'll get an #N/A result (which you could easily test for).
Here's a test I ran:
Note that the data here is in rows 25 - 31. Also, you'll need to format the result as a date.
Hope this helps!
Edit: Here's an explanation of how the Match function is being used. (I edited the answer so that future generations will find it more easily than if I added a comment.)
As a reminder (because I'm old and forgetful), the Match function takes three parms: Lookup Value, Lookup Array, and Match Type. So in
MATCH(1,(CubsTicketStatus="Avail")*(CubsDate>TODAY()),0)
we're looking for a value of 1 with a match type of 0 (exact match). That's the easy part. Our Lookup Array, however, is a little more complex. It consists of two tests multiplied by each other. So in each row, it looks at the value in CubsTicketStatus to see if it is "Avail" and it looks at the value in CubsDate to see if it's after today.
Each of those tests results in either TRUE or FALSE but, when you put them in the context of a mathematical calculation, they are 1 and 0. So if they're both TRUE, then you get 1 * 1, but if either (or both) is FALSE, you get zero. The Match function then returns the first row where both are TRUE -- that is, the first row where tickets are "Avail" and the date is after TODAY().