Questions involving VBA date comparisons - excel

I need to write some code that compares dates in an excel file and then high lights those rows of data based on the data evaluations. Essentially there are 3 columns in this file that have a standard Month/day/year format. I need to compare the day of all three columns to see if they are within a 3 day date difference "don't care about the month". If they are not within the 3 day date difference I want to high light them. An example of an OK comparison would be (10/1/2015,12/2/2015, 8/3/2015) I would not want to do anything with this row of data. Here is what I consider to be a "bad" date comparison (10/1/15, 11/3/2015, 8/5/2015). All the dates have to be within 3 days and as you can see there is a 4 day date difference between 10/1 and 8/5. How can I write something up like this to evaluate this?

You can just compare the Max() of the days to the Min() of the days with the Array Formula:
=IF(MAX(DAY(A1:C1))-MIN(DAY(A1:C1))>3,"fail","Close enough")
Array formulas must be entered with Ctrl + Shift + Enter rather than just the Enter key.
You can do the same functionality with VBA if that is needed.

Related

Counting the matches of a date in time periods in Excel

I am trying to find a (reasonably elegant) formula to find out how often a date appears in a list of date ranges.
In my example I have 4 date ranges, defined by a start date (A2:A5) and by an end date (B2:B5). Below I have a list of dates for which I would like to know how often a date appears in any of those 4 ranges. The only solution I came up with was to check for each range if the date is in there. The formula becomes quite lengthy with the number of periods and is not flexible if more periods are added later.
Here the time periods:
And here where I try to retrieve the number of matches given a date:
My formula is here for B11 (yielding 3 given the input of 10/Sep/2021):
=IF(AND($A11>=$A$2,$A11<=$B$2),1,0)+IF(AND($A11>=$A$3,$A11<=$B$3),1,0)+IF(AND($A11>=$A$4,$A11<=$B$4),1,0)+IF(AND($A11>=$A$5,$A11<=$B$5),1,0)
Any ideas appreciated!
Using COUNTIFS:
=COUNTIFS($A$2:$A$5,"<="&A11,$B$2:$B$5,">="&A11)

Sum the number of days in one date range which fall within a second date range

I have two columns of dates. One is the move in date and the other the move out date. I want to figure out how many days the tenant was there during a second date range. for example: how many total "bed days" did we have in the month of July? 7/1/2016-7/31/2016
This function calculates the number of days each tenant was there each month but I would like it if I could get the entire calculation into one cell without creating a dummy column for each month.
=MAX(0,MIN(EOMONTH($B$2,0),I14)-MAX($B$2,H14))
I tried to change a few things and use it as an array function but it is not working. I am very new to array functions so I may be doing it completely wrong.
=SUM(MAX(0,MIN(EOMONTH($B$2,0),I:I)-MAX($B$2,H:H)))
any help is much appreciated! Let me know if you need more info too.
Bad news - you can't use MAX and MIN in an array formula like this because instead of treating H and I as two arrays it just treats them as one big long array and you only get one value out of them.
You also need to add 1 to your original formula because if they moved in on the last day of the month (say) it should still count as one day.
If you replace the MAX and MIN with IF statements you get something like this
=SUM(IF(IF(EOMONTH($B$2,0)<IF(I2:I10="Active",TODAY(),I2:I10),EOMONTH($B$2,0),IF(I2:I10="Active",TODAY(),I2:I10))-IF($B$2>H2:H10,$B$2,H2:H10)<0,0,
IF(EOMONTH($B$2,0)<IF(I2:I10="Active",TODAY(),I2:I10),EOMONTH($B$2,0),IF(I2:I10="Active",TODAY(),I2:I10))-IF($B$2>H2:H10,$B$2,H2:H10)+1))
which has to be entered using CtrlShiftEnter
A useful tip if you are new to arrays is not to include more rows in an array formula than you need to because it will be slow, and test it first on a small number of rows so that you can step through it using Evaluate Formula if you run into trouble.

Counting the number of occurences of a value dynamically

Not sure if I've worded the question correctly... but, I have a spreadsheet that imports data across with a 'transaction date' and on day 1 there may be 15 transactions, day 2 there may be 30 etc.
Now I already have a formula that is counting how MANY are imported each day
=SUMPRODUCT((MONTH('Further Evidence'!$A$2:$A$5000)=MONTH(DATEVALUE(Configuration!H2&" 1")))*('Further Evidence'!$A$2:$A$5000<>""))
That shows how many have come in that particular month, what I need to work out now is what the highest intake was during that month (and if possible, which day it was).
Rather than list 365 days of the year and doing a countif in every cell next to them, is there an intuitive way to only count values that exist in the list?
It will be simple for one of you, but I can't quite figure it out or what to google :)
edit -
=MAX(FREQUENCY('New Appeals'!A2:A5000,MONTH('New Appeals'!A2:A5000)))
This works for the whole list of dates, but how can I make it check months specifically, or pinpoint the specific day?
To find the max value within a given month you can use an array formula like below
I've used a sample range of rows 36 to 48. I've assumed that date is in column I and that transactions is in column J
=MAX(IF(TEXT($I$36:$I$48, "mmm")="jan", $J$36:$J$48, ""))
(To enter an array formula you have to press ctrl + shift + enter when you are in the cell)
This is restricting the MAX function to the month of jan.
You can then find the day associated to this max value by using another array formula that is a mix of first MATCH then INDEX. The MATCH first looks for the max value within the range of cells associated to the given month, then returns this position. This position is then used in the INDEX to return the date
=INDEX($I$36:$I$48, MATCH(K34, IF(TEXT($I$36:$I$48, "mmm")="jan", $J$36:$J$48, "")))
Please note that if you have two days within a month with the same max then it will just bring back the first one
Hope this helps

Excel: Counting how many rows fall within a time period

I have an excel sheet with 2 columns
Column A = "CA", "CR" or "IN"
Column B = Date & time format DD/MM/YYYY HH:MM
I want to make a count at the bottom of a column for each row that has this criteria:
i) Row 1-8 = "CA"
ii) Row 1-8 needs to check for a time range, namely > "17:00" and < "04:59"
This is what I've come up with so far:
=COUNTIFS(A2:A8,"CA",B2:B8,RIGHT(TEXT(B2:B8,"hh:mm"),5)>"04:59"), B2:B8,RIGHT(TEXT(B2:B8,"hh:mm"),5)<"17:00")
I presume using a range within a the text function is wrong, but don't know how to resolve this.
Because Column B is in a date and time format, I'm having to change it to a string within the function so I can make a test on just the time - Maybe there's a better way?)
Thanks
The problem with COUNTIFS is that you can't manipulate the conditions a lot. You could insert a column containing the time only, in which case you could use COUNTIFS but if you cannot, you can use SUMPRODUCT for substitute:
=SUMPRODUCT((A1:A6="CA")*(((TEXT(B1:B6,"hh:mm")*1>TIME(17,0,0))+(TEXT(B1:B6,"hh:mm")*1<TIME(5,0,0)))>0))
This applies a few conditions on an example range A1:B6:
(A1:A6="CA") that ensures that the row has CA,
(TEXT(B1:B6,"hh:mm")*1>TIME(17,0,0)) that ensures that the time is above 17:00
(TEXT(B1:B6,"hh:mm")*1<TIME(5,0,0)) that ensures that the time is before 05:00 (You have 4:59 in your question, if you really meant less than 4:59 then change this part).
The + for the last two conditions 'OR's the two conditions, then the whole thing is 'AND'ed with the first condition.
This is difficult to do with COUNTIFS because you can't modify ranges with functions.....but you can do that with SUMPRODUCT - try this
=SUMPRODUCT((A2:A8="CA")*(MOD(B2:B8,1)<"17:00"+0)*(MOD(B2:B8,1)>"04:59"+0))
I'm assuming that you want between 04:59 and 17:00 - in your point ii) you show it the opposite way to what you have in your formula
MOD extracts the time from the date/time so it can be compared against a time range. If you are counting within a range including whole hours, e.g. 5 to 16 inclusive you can use HOUR function without MOD, i.e.
=SUMPRODUCT((A2:A8="CA")*(HOUR(B2:B8)>=5)*(HOUR(B2:B8)<=16))
You do not need to deal with strings at all for the time. Excel provides with quite a few date&time functions, enough in your case.
A concise formula is
=SUMPRODUCT((A1:A8="CA")*(MOD(B1:B8,1)<=TIME(17,0,0))*(MOD(B1:B8,1)>TIME(4,59,0)))
Notes:
I assume you meant <=17:00, instead of <17:00. It is easy to modify the formula if I was wrong.
You used A2:A8, but you probably wanted A1:A8, as per the text. It is easy to modify the formula if I was wrong.
COUNTIFS is usually much less flexible than SUMPRODUCT (combined with other functions as MATCH, INDEX, SUM, etc.)
PS: as barry houdini points out, the OP asks for two opposite time ranges. I have chosen here one of them.

Trying to calculate a renewal date in excel

Have a few different items with different rental periods ( 1,3,6 months to 1,3,5 years). As it stands I have a column with the last renewal date and a column indicating what is the renewal period. I wanted excel to calculate what the Renewal date would be based on the selected type of renewal. My first attempt was to convert the renewal types to some kinda of similar denomination but i got stuck trying to figure out what value/format to use.
Last renewal date Renewal Type Renewal Date
11/11/2013 1 Year
2/14/2014 2 Years
8/28/2011 5 Years
11/27/2013 3 Months
[Excel stores dates as floating point numbers. They advance by 1 each day and the fractional part holds the day fraction, e.g. 0.5 is midday. The exact value is user-configurable between 1900 and 1904 origins which can complicate things. Note that in the 1900 origin, date 60 (corresponding to the non-existent date 29-Feb-1900) is defined. Leap seconds are not implemented.]
If you can tolerate the second column being integral months, then use the EDATE function.
For example, if your table is orientated on cell A1, use
=EDATE(A2, B2) in cell C2 and copy downwards.
I would use a Vlookup in the third column which should point to a table which has conversion of 1 year/6mos into days. (365,180, ect). Then just add that vlookup to the original date.
So
`TblDate
Lookup Days
1mo 30
.. ..`
=VLOOKUP(B1,TblDate,2,FALSE)+A1
Maybe try:
=IF(ISERROR(FIND("year",B2)),DATE(YEAR(A2),MONTH(A2)+LEFT(B2,1),DAY(A2)),DATE(YEAR(A2)+LEFT(B2,1),MONTH(A2),DAY(A2)))
In D2 enter:
=--MID(B2,1,FIND(" ",B2))
and copy down
In E2 enter:
=MID(B2,FIND(" ",B2)+1,1)
and copy down
Finally in C2 enter:
=IF(E2="Y",DATE(YEAR(A2)+D2,MONTH(A2),DAY(A2)),DATE(YEAR(A2),MONTH(A2)+D2,DAY(A2)))
Format C2 as Date and copy down. For example:
.
.
There is a way to convert your second column into pure month format, using Excel:
=IF(COUNTIF(B2,"*Year*"),(TRIM(LEFT(B2,2)))*12,IF(COUNTIF(B2,"*Month*"),TRIM(LEFT(B2,2)),NA()))
This can then be used with EDATE(). For example, lets say that the above code is in cell C2, it would produce 12. Then, you could in cell D2, you could put
EDATE(A2,C2)
in there. The code works for anything between 1 month and 99 years and doesn't care whether the first number is one or two digits and whether the word is month, months, year or years - it will work with all of it, as TRIM() removes whitespace (thus allowing for one character and a space or two characters) and * is a wildcard (hence allowing x years or xz year).
For EDATE to work you need to make sure the number format is set to date type.
Note: an extra cell for the months will be needed - so it might require a little rearranging, but using CTRL+C or copy cells tool in the bottom right of a selected cell will easily copy it, and for each one it will automatically convert it.
create a new column and type in the formaula box
=B2+1095
to get your renewal date
1 year is 365
2 years is 730
3 years is 1095
and so on and so forth.
this was the most simple way and worked for me!

Resources