I have found the solution thought it would be good to share:
so the formula should be :
=((MAX(CT$6-$N8,0)-MAX(EOMONTH(CT$6,-1)-$N8,0))-(MAX(CT$6-$O8,0)-MAX(EOMONTH(CT$6,-1)-$O8,0))+(EOMONTH(CT$6,0)=EOMONTH($N8,0)))*1
:)
I am trying to write an excel formula which can be dragged across a row of cells to give the number of days in each month between two specified dates. E.g:
I tried using a if with sum product formula from the same website but for some reason it is not recognising the days of last month. was wondering if someone could help explain what this formula does and how to correct it.
=IFERROR(IF(AND(CS$6>=$M9,CS$6<=$N9),SUMPRODUCT(--(MONTH(ROW(INDIRECT($M9&":"&IF($N9="",TODAY(),$N9))))=MONTH(CS$6))),),"")
SECOND REVISION (R2)
Updated workbook link to capture fixed column headings
Eqn / formula also includes static view
Depending upon years spanned, R2 represents a less favourable outcome re space (will require more columns). In this case, number of additional columns required to match stacked view ~100 (!!).
FIRST REVISION (R1) etc. based upon #Charlotte.Sarah.Smith feedback
Days in each month were 1 day less than they should have been - this has been corrected (in both screenshot, linked sheet, and relevant eqns)
Also showcase a couple of sample illustrations/visual representations which may/not be of interest (included within linked sheet too)
Suppose we wanted to expand upon #Will's solution by stacking the dates by year, so that column headings can vary according to different start dates (as opposed to the very first start date that happens to appear)...
For instance, if the next row included the date range 'start = 10/02/16' through 'end = 15/03/19' - you'll appreciate that the number of columns spanning Jan-Dec ('16), Jan-Dec ('17),... up to (and incl.) the range in the first row (Jan '21 - Mar '23) becomes unwieldy.
By using a data table (see here) you can produce a 'stacked' view of the number of days per month regardless of the year (!) - see screenshot below and link to this [updated/corrected] worksheet.
R2 screenshot:
REVISION
See validation/reconciliation column at end
*Visual representations - could be useful for assessing trends etc.
Fun in 3D too!
1] Red font: first row that defines the construct of the data table: enter date range in the format '10/02/2021-15/08/2023'
Cell E3 eqn (drag to right):
=IFERROR(IF($A3>EDATE(E$2,1),0,MAX(,IFERROR(IF(MIN($B3,MIN(EDATE(E$2,1),$B3))=E$2-1,0,MIN($B3,MIN(EDATE(E$2,1),$B3))),"")-MAX($A3,E$2))),0)
(Similar to what we've seen previously)
2] Table below red font: enter any start date (as a regular date, e.g. dd/mm/yyyy) < end date (likewise, regular date) in columns A, B as desired/req.
Data Table
3] Data Table (column data): enter the following in cell c4 (drag down as req.)
=TEXT(A4,"dd/mm/yyyy")&"-"&TEXT(B4,"dd/mm/yyyy")
4] Data Table (highlight cells c3:d42, insert data table, select blank/empty cell for 'row input' and c2 for 'column input')
The data table should 'come to life' (calculate sheet, shift + F9) otherwise.
FilterXML
5] Split result by delimiter '|' using FilterXML as follows (cell E4, only drag down, not to right):
=IFERROR(TRANSPOSE(FILTERXML("<AllText><Num>"&SUBSTITUTE(LEFT(MID(D4,2,LEN(D4)-1),LEN(MID(D4,2,LEN(D4)-1))-1),"|","</Num><Num>")&"</Num></AllText>","//Num")),"")
VALIDATION
Note the check column: date difference = sum of days in table (default cell colour is otherwise RED):
REVISION 2
Here is the formula for a static version of above (i.e. no stacking by year, instead, each date in column headers are distinct re calcs) - it was already available in row with red font(!!)
=IFERROR(IF($A3>EDATE(C$2,1),0,MAX(,IFERROR(IF(MIN($B3,MIN(EDATE(C$2,1),$B3))=C$2-1,0,MIN($B3,MIN(EDATE(C$2,1),$B3))),"")-MAX($A3,C$2))),0)
Viola!
One potential solution would be to compare dates using the MIN and MAX functions like this:
=IF(MIN($B2+1,D$1)-MAX($A2,C$1)<0,"",MIN($B2+1,D$1)-MAX($A2,C$1))
screenshot
This solution uses month starting dates (e.g., Feb 1, 2021), but it could be adapted to work with month end dates instead (e.g., Feb 28, 2021).
The idea is that you take the later of the finish date or month end date minus the lesser of the start date or the month start date. For the first month and last months, this returns the number of days within that range inclusive of the first and last day. For all the months between the first and last months, it returns the number of days in the month.
The +1 on the minimum of the end dates seems a little counterintuitive, but it's necessary to include the first and last day in the count. Without it, you'd get 14 days in March 2022 instead of 15.
The "if less than zero" function makes it return a blank (or zero if you'd prefer) for any month outside the dat range.
This solution does not summarize by month (e.g., 19 days for Feb 2021 plus 28 days for 2022 to get 47 total days in February), but that's consistent with the sample you provided. The comments also indicate that you want to consider the years as well.
I have an Excel sheet with dates in the rows. A given month should be used only once in a row. How can I filter out, if there are two dates in the same row from the same month?
For example I have the following array, and I would like to have as a result, that there is a match in this row (2012-03).
2012-03-04 2012-02-05 2012-04-06 2012-03-07 2012-10-08 2012-11-09 2012-12-10
I have tried to combine aggregate and match functions, but I cannot find out how to do it properly.
One of my codes, of course it gave an error:
=aggregate(9,6,(MATCH("*"&LEFT(A8,7)&"*","*"&LEFT(b8,7)&"*",0), MATCH("*"&LEFT(b8,7)&"*","*"&LEFT(c8,7)&"*",0)))
Ok, now I have tried another way, and I could get a solution, but with a code which is like a km long...I have first created a new dataset, cutting down the days by using: =""&LEFT(A8,7)&""
Then I have compared all the cells in a given row of my new dataset. Could someone help me how to shorten the exact( ) parts? The aim is to compare all.
=if((or(exact(A2, B2), exact(A2,C2),exact(A2,D2),exact(A2,E2),exact(A2,F2),exact(A2,G2),exact(A2,H2),exact(A2,I2),exact(A2,J2),exact(A2,K2),exact(A2,L2),exact(A2,M2),exact(A2,N2),exact(A2,O2),exact(A2,P2),exact(A2,Q2),exact(A2,R2),exact(B2,C2),exact(B2,D2),exact(B2,E2),exact(B2,F2),exact(B2,G2),exact(B2,H2),exact(B2,I2),exact(B2,J2),exact(B2,K2),exact(B2,L2),exact(B2,M2),exact(B2,N2),exact(B2,O2),exact(B2,P2),exact(B2,Q2),exact(B2,R2),exact(C2,D2),exact(C2,E2),exact(C2,F2),exact(C2,G2),exact(C2,H2),exact(C2,I2),exact(C2,J2),exact(C2,K2),exact(C2,K2),exact(C2,L2),exact(C2,M2),exact(C2,N2),exact(C2,O2),exact(C2,P2),exact(C2,Q2),exact(C2,R2),exact(D2,E2),exact(D2,F2),exact(D2,G2),exact(D2,H2),exact(D2,I2),exact(D2,J2),exact(D2,K2),exact(D2,L2),exact(D2,M2),exact(D2,N2),exact(D2,O2),exact(D2,P2),exact(D2,Q2),exact(D2,R2),exact(E2,F2),exact(E2,G2),exact(E2,H2),exact(E2,I2),exact(E2,J2),exact(E2,K2),exact(E2,L2),exact(E2,M2),exact(E2,N2),exact(E2,O2),exact(E2,P2),exact(E2,Q2),exact(E2,R2),exact(F2,G2),exact(F2,H2),exact(F2,I2),exact(F2,J2),exact(F2,K2),exact(F2,L2),exact(F2,M2),exact(F2,N2),exact(F2,O2),exact(F2,P2),exact(F2,Q2),exact(F2,R2),exact(G2,H2),exact(G2,I2),exact(G2,J2),exact(G2,K2),exact(G2,L2),exact(G2,M2),exact(G2,N2),exact(G2,O2),exact(G2,P2),exact(G2,Q2),exact(G2,R2),exact(H2,I2),exact(H2,J2),exact(H2,K2),exact(H2,L2),exact(H2,M2),exact(H2,N2),exact(H2,O2),exact(H2,P2),exact(H2,Q2),exact(H2,R2),exact(I2,J2),exact(I2,K2),exact(I2,L2),exact(I2,M2),exact(I2,N2),exact(I2,O2),exact(I2,P2),exact(I2,Q2),exact(I2,R2),exact(J2,K2),exact(J2,L2),exact(J2,M2),exact(J2,N2),exact(J2,O2),exact(J2,P2),exact(J2,Q2),exact(J2,R2),exact(K2,L2),exact(K2,M2),exact(K2,N2),exact(K2,O2),exact(K2,P2),exact(K2,Q2),exact(K2,R2),exact(L2,M2),exact(L2,N2),exact(L2,O2),exact(L2,P2),exact(L2,Q2),exact(L2,R2),exact(M2,N2),exact(M2,O2),exact(M2,P2),exact(M2,Q2),exact(M2,R2),exact(N2,O2),exact(N2,P2),exact(N2,Q2),exact(N2,R2),exact(O2,P2),exact(O2,Q2),exact(O2,R2),exact(P2,Q2),exact(P2,R2),exact(Q2,R2))),"same month","ok")
Thank you in advance.
I am not sure if there is a better way, but this is how I'd tackle the problem based on my Excel knowledge:
Add data of dates above in cells A1-G1
On row below date add formulas for dates: A2=DATE(A1) ..... G2=DATE(G1)
At the end of the original row of dates add the numbers 1 thru 12:
using formula cell H1=1, I1=H1+1 ..... S1=R1+1
After the months on row 2:H2=COUNTIF($A2:$G2,H1) ..... S2=COUNTIF($A2:$G2,S1)Counting frequency for each of the 12 months
T2=MAX(H2:S2)
Then select on cell T2being more than 1.
Here it is as a Google sheet (you can download it and open in Excel if you want)
Maybe this will help. Assume that the range of dates is in $A$1:$G$1. Also assume that the entries are numerical dates; if they are instead text you can handle this by using the DATEVALUE function. Then we can get the years and months of the range with:
{=YEAR($A$1:$G$1)}
{=MONTH($A$1:$G$1))
This and all other formulas must be entered as array formulas (CrtlShiftEnter).
We next convert back to a date, but use 1 for the day, so that all dates get shifted to the first day of the month (this means that any dates from the same month are shifted to the same date):
{=DATE(YEARS,MONTHS,1)}
We can produce an NxN comparison of the shifted dates by:
{=TRANSPOSE(SHIFTED_DATES)=SHIFTED_DATES}
We can count the number of True's in this array by:
{=SUM(--(ARRAY))}
If there we no dates from the same month we'd expect this to sum to N because this method compare each date to itself as well as the other dates. The causes the N elements on the main diagonal of this array to be True. If any dates are in the same month off-diagonal elements will also be True. So to detect if there are dates from the same month we make the comparison:
{=SUM(--(ARRAY)) > N}
or more generally:
{=SUM(--(ARRAY)) > COUNT($A$1:$G$1)}
Rolling all of these up into one formula:
=IF(SUM(--(TRANSPOSE(DATE(YEAR($A$1:$G$1),MONTH($A$1:$G$1),1))=DATE(YEAR($A$1:$G$1),MONTH($A$1:$G$1),1)))>COUNT(DATE(YEAR($A$1:$G$1),MONTH($A$1:$G$1),1)),"same month","ok")
If your dates are in a range other than $A$1:$G$1 then make the appropriate substitutions.
Hope that helps.
Currently. I have it set up when someone enters information in column E (Action Taken) then the whole row will turn yellow so it is easily seen that that item is being dealt with.
Another conditional format that I have set up is that once 5 working days pass on the date entered into column F (Date Actioned) then the row will turn red alerting the user to chase up the issue again.
Every week the user will contact more suppliers on the list regarding the listed product, and fill in their action taken and date actioned.
What I am looking to do is to add up all the suppliers contacted in one week (i.e. week 1 , 05.02.18 to 09.02.18) Which I know can be done by using the formula;
=COUNTIFS(F4:F18,">=5/2/18",F4:F18,"<=9/2/2018")
HOWEVER I only want to count each company once! So even though between the date 05.02.18 to 09.02.18, 8 actions were carried out, they only contacted 4 suppliers.
Is this possible? (FYI the screenshots attached are just a quick mock-up of the real document which contains thousands of products and more in-depth information).
If you don't mind adding a couple of working columns, the following is a possible solution:
Step 1
Set up two cells to contain the min and max dates for your range that you used in your formula =COUNTIFS(F4:F18,">=5/2/18",F4:F18,"<=9/2/2018"). This will allow you to up date things without having to recopy the formula each time. I used cells E1 and G1 for min and max date respectively.
Step 2
In a new column generate a list of supplier IDs that match your criteria. I arbitrarily chose column H. I placed the following formula in H4 and copied down:
=IF(AND(F4>=$E$1,F4<=$G$1),A4,"")
Step 3
In a new column generate a list of the count of the first time a supplier ID occurs from column H and do not count blank spaces. I arbitrarily chose column I. I placed the following formula in I4 and copied down:
=--(AND(COUNTIF($H$4:H4,H4)=1,H4<>""))
Step 4
Take the sum of the results from step 3. I arbitrarily chose to place the following formula in I19:
=SUM(I4:I18)
The "cop out" route, if you were only doing the calculation for 1 week would be to have a Pivot Table, with the Company as the Rows and the Date as the Columns. Then filter your columns, and you get a row per Company that week.
The Full route means looking into Array Formulae - you type one of these like normal, but instead of pressing [Enter], you press [Ctrl]+[Shift]+[Enter], and the equation will show in curly braces. (This is why they are sometimes called "CSE Formula" for "Control, Shift, Enter")
~Warning - This is a long walk through how I calculated the final formula. Hopefully it will make sense though!~
An array formula lets you iterate through every row in a range, calculate them seperately, and then add them all together at the end. This gives us the outside term - everything goes inside a =SUM(..). Press [Ctrl]+[Shift]+[Enter], and this will display as {=SUM(..)}
Now, what calculation do we want to be doing per row? Well, for every row where column F is within date, you want 1 per company within date. Well, another was to say "per" is "divided by" (hence the "Percentage" symbol being "0 / 0" or "%", and the lesser knows "Permille" symbol being "0 / 00" or "‰")
For the sake of reproducibility, I am going to assume that your Count is being done in Cell J2, and you have the Start/End of week dates in Cells H2 and I2
The formula for Row 4 would start out as =IF(AND(F4>=$H2,F4<=$I2), 1/???, 0), where ??? is how many times the Company on row 4 appears. Unfortunately, the AND function does not work with Array Formula. Fortunately there is an easy workaround - since boolean True/False can be treated as binary 1/0, the AND operator is the same as multiplication. Converting from boolean to binary is fastest by double-negation, so AND(F4>=H2,F4<=I2) can be rewritten as --(F4>=H2)*--(F4<=I2), which will work fine with array formula, giving us =IF(--(F4>=H2)*--(F4<=I2), 1/???, 0)
Now, before we work out what ??? should be, I'm going to skip down to row 18. There is method to this madness, I promise! Following the rules laid out above, the formula for row 18 is =IF(--(F18>=H2)*--(F18<=I2), 1/???, 0) - fairly simple? Now, if we want to run this for all rows from 4 to 18, we just need to join the ranges. So, you would get =IF(--(F4:F18>=H2)*--(F4:F18<=I2), 1/???, 0) Turning this into an Array Formula would get you an array of "1/???"s and "0"s, so add it together with SUM to get a single 'flat' number: =SUM(IF(--(F4:F18>=H2)*--(F4:F18<=I2), 1/???, 0))
Remember that "method" I mentioned earlier? Well, if we were looking for a straight Count of actions taken, ignoring the Unique Companies constraint, we could make ??? = 1, to get =SUM(IF(--(F4:F18>=$H2)*--(F4:F18<=$I2), 1, 0)) and hit [Ctrl]+[Shift]+[Enter] - which would give the same result as =COUNTIF(F4:F18, ">="&H2, F4:F18, "<="&I2) - and changing the 1 to D4:D18 would be a SUMIF on Products. (Incidentally, you can remove the IF statement from the CountIf, since the Condition returns 1 or 0 already)
So, last step! What is ??? Well, it's a Count of rows where Date Actioned is within our date bounds, and Company is the same as the current row. So, for Row 4 you have COUNTIFS(B4:B18, B4, F4:F18, ">="&H2, F4:F18, "<="&I2), and for Row 18 you get COUNTIFS(B4:B18, B18, F4:F18, ">="&H2, F4:F18, "<="&I2), making the final ??? become COUNTIFS(B4:B18, B4:B18, F4:F18, ">="&H2, F4:F18, "<="&I2) (The trick here is that the Range arguments are treated as all the cells at once, but the Condition arguments are treated as an array of each cell one-at-a-time)
Now, some people might argue that you need to put your 1/COUNTIFS(B4:B18, B4:B18, F4:F18, ">="&H2, F4:F18, "<="&I2) inside an IFERROR to be safe - however, this is in the TRUE part of an IF statement referrring to the same row, so we know that if the COUNTIF is being evaluated then there will always be at least 1 row that matches.
So, if we stick it all together, and add a load of $ symbols to lock the rows/columns in place (so that you can drag down column J to calculate for different weeks/dates in columns H and I) you get the (slightly unwieldy) formula as follows:
=SUM(IF(--($F$4:$F$18>=$H2)*--($F$4:$F$18<=$I2), 1/COUNTIFS($B$4:$B$18, $B$4:$B$18, $F$4:$F$18, ">=" & $H2, $F$4:$F$18, "<=" & $I2), 0))
And, one last time - Don't forget to press [Ctrl]+[Shift]+[Enter]
(The 2 Date cells, $H2 and $I2 are the only terms I have left 'unlocked', and even then only on the Row)
I would like to find the row at which running summed value has reached a specified amount and several criteria have been met (similar to sumifs).
I can't just add a cumulative row, as suggested here:
Count rows until the sum value of the rows is greater than a value
....because I have other criteria to meet in the data, and therefore can't have a running total.
In the following dummy example, I'd like to find the date at which the "Design" project has spent or exceeded $30,000
A late answer, but one that doesn't use a Helper Column.
By using Matrix Multiplication (MMULT) on a TRANSPOSEd array of whether the Row is larger than itself and the list itself, we can produce an array of the Running Total.
MMULT(--(TRANSPOSE(ROW(D2:D21))<=ROW(D2:D21)), D2:D21)
If we shrink this to just the first 3 rows, to demonstrate, then you are making this calculation:
[[--(2<=2)][--(3<=2)][--(4<=2] [[10,000]
[--(2<=3)][--(3<=3)][--(4<=3] ∙ [ 8,000]
[--(2<=4)][--(3<=4)][--(4<=4]] [ 6,000]]
Which gives us this:
[[1][0][0] [[10,000] [[10,000]
[1][1][0] ∙ [ 8,000] = [18,000]
[1][1][1]] [ 6,000]] [24,000]]
We can then compare that against the target value as a condition and divide by the result to eliminate values with #DIV0! errors, and use AGGREGATE to get the smallest non-error value
=AGGREGATE(15, 6, Row(D2:D21) / (MMULT(--(TRANSPOSE(ROW(D2:D21))<=ROW(D2:D21)), D2:D21)<30000), 1)
This will give us the first row where the Running Total is >= $30,000
make a cumulative row, only adding up if column B equals 'Design'
If you want to be able to do a vlookup, you should make an extra column that checks if amount exceeded 30k, and then output anything that will be your key for the vlookup.
Ok, for anyone who is interested, here is what I ended up doing. I created a separate table that had all of my possible weeks (10/17, 10/24, 10/31, etc.) in one column, and corresponding sequential numbers in the next column. I ended up with 54 in my actual project.
Then, I ended up having to insert one column into my dataset for the purposes of looking up that "Week No", for each "Week" in all rows. Then on my other sheet where I was solving, I had a cell be my decision variable for the week #. I had another be my target $. I created a formula that took my target amount minus the SUMIFS for all of my criteria (Project, Name, etc.) with the last criteria being that the week number had to be "<=" & (decision cell). I then used Solver to minimize the output by changing the target week with constraints that the target week had to be integer, >=1, <=54, and that the output had to be >=0. That got me to the week prior to where the funding went negative. I then had a cell lookup that week number +1 on my weeks table to find the week at which my target amount would be met.
Sorry, had to explain it that way, vs. the actual formula, as my actual formula has a lot of SUMIFS criteria and cell references that wouldn't make any sense here.