Multiple Vars for DateDiff VBA - excel

I have a VBA script at the moment that reads in 6 values as integers. 3 values for date, month, and year and 3 of the same type from a different location. I'd like to take the values and check if there has been more than a year to pass between them. DateDiff seems like the easiest way to handle this, however that function reads in the values as one DateValue (ie March 20, 2015) and my values are returned individually (08,08,2015).
I wrote a function that stores each value into a var and then using those individually I concat them into a format that DateValue can use.
This works, however I am curious if there is another(better) way to handle this problem?
Thanks in advance.

The function DateSerial(2015,3,4) will return the date for 3/4/2015, and with both of your dates in that format, you can subtract the one date from the other, and if the (absolute value of the) difference is > 365 then you know that they are over a year apart.
Dim A As Date
A = DateSerial(2015, 3, 4)
Dim B As Date
B = DateSerial(2014, 3, 2)
Dim C As Integer
C = Abs(A - B)
MsgBox C & " days between"

Related

Incorrect result for nested condition in MEDIAN-IF excel

I have a following excel spreadsheet which consist of following fields:
Col A: Timestamp
Col B: Numerical result
Col C: Time duration taken for calculation of result
Now, I'm trying to find the median value of col C (Duration) for various month and year combinations.
e.g. For the month of march in 2019, what's the median value of duration?
I could've used the MEDIANIFS, but sadly it didn't exists. I'm trying the below thing also, but it's not giving the correct result(G1 is a drop-down which consists numerical valued years i.e. 2019, 2020 and so on)
MEDIAN(IF(YEAR(A3:A100) = G1, IF(MONTH(A3:A100) = 3, C3:C100)))
I also tried ANDing the conditions but it also didn't worked:
MEDIAN(IF((YEAR(A3:A100) = G1) * (MONTH(A3:A100) = 3), C3:C100))
If I put one condition inside the Median(If()), it's working fine. But, whenever I nest or concat conditions, it's not giving the correct result.
Any help/pointers will be highly appreciated.

How to use the Resize function with the offset function in VBA code for a User Defined Function in Excel

I have 10 years worth of monthly returns of an asset. I am trying to create a function that can give me the annualised returns of this series of monthly return data. I would like to use the Offset function to go to the last monthly returns date, select an array of periods that I choose (3 months back, 6 months back, 12 months back, 24 months back etc) so that I can get the annualised return of a series of returns from the end date back to a specific period.
The goal is to calculate the monthly average monthly returns of the last 3 months, 6 months, 12 months etc.
However, the parameters for the Offset function in VBA are different to those in normal Excel functions. I think I need to use the .Resize function to resize my Offset function.
Here is how the function works in Excel
=GEOMEAN(1+OFFSET($W$4,MATCH(LARGE($V$4:$V$10485,1),$V$4:$V$10485,0)-1,0,-$AJ17,1))-1
Rewritten so that you can understand my variables
=GEOMEAN(1+OFFSET(ref,MATCH(LARGE(Dates,1),Dates,0)-1,0,-period,1))-1
Here is the code that I have written so far...
Function Returns(ref As Range, Dates As Range, Period As Integer) As Variant
With Application.WorksheetFunction
Returns = .Geomean(1 + ref.Resize(-Period, 1).Offset(.Match(.Large(Dates, 1), Dates, 0) - 1, 0))-1
End With
End Function
Please, can someone help?
Okay, so I figured out a few of my errors.
A) I declared the variables incorrectly.
B) I used a negative number for resize as I wanted the function to go to the end of the series and count back (to get 6 month. 12 month, 24 month returns). This does not work.
As an alternative, I have used LARGE to find the nth largest date and select the array below that point.
See code below.
Function AnnReturns(Ref As Variant, Dates As Variant, Period As Variant, M As Variant) As Variant
With Application.WorksheetFunction
AnnReturns = .FVSchedule(1, (Ref.Offset(.Match(.Large(Dates, Period), Dates, 0) - 1, 0).Resize(Period, 1))) ^ (1 / M) - 1
End With
End Function

compare two dates in dd/mm/yyyy format

I have a column where I store dates as dd/mm/yyyy. Then I ask user to input in a form a new date (always as dd/mm/yyyy). I want to compare the input date to the last date that is in the excel already.
If Format(data_mov, "Short Date") < Format(data_last, "Short Date") Then
is not the way to go since it will compare two strings and the test will fail since 03/10/2018 looks smaller than 23/09/2018.
What is the correct way to test them? Something like converting them into timestamps and then compare (but is there something like the unixtimestamp in excel?)
You convert the strings to date and compare them:
' dd/mm/yyyy
' 1234567890
Dim Date1: Date1 = DateSerial(Mid(data_mov, 7, 4), Mid(data_mov, 4, 2), Mid(data_mov, 1, 2))
Dim Date2: Date2 = DateSerial(Mid(data_last, 7, 4), Mid(data_last, 4, 2), Mid(data_last, 1, 2))
If Date1 < Date2 Then
' ...
End If
"What is the correct way to test them?"
IMHO, there is more than one way.
if() with value() will be straightforward.
if() with year(),month(),day(), hour().. is another.
"Something like converting them into timestamps and then compare (but
is there something like the unixtimestamp in excel?)"
The easiest (for me) is using value() function . Then build the desired if() statement on it.
Hope it helps. (:
Microsoft Excel for Windows uses the 1900 date system, by default. Which means the first date is January 1, 1900. a Date and Time function can be used to manipulate the year/date and time/hour/minutes values. The date/time in Excel is stored as a number. Where the decimal part range from 0.0 to 0.99988426 represent 0:00:00 (12:00:00 AM) to 23:59:59 (11:59:59 P.M.), and the integer part range from 0 to 9999 represent year 1900 to year 9999.

Convert dates from Excel to Matlab

I have a series of dates and some corresponding values. The format of the data in Excel is "Custom" dd/mm/yyyy hh:mm.
When I try to convert this column into an array in Matlab, in order to use it as the x axis of a plot, I use:
a = datestr(xlsread('filename.xlsx',1,'A:A'), 'dd/mm/yyyy HH:MM');
But I get a Empty string: 0-by-16.
Therefore I am not able to convert it into a date array using the function datenum.
Where do I make a mistake? Edit: passing from hh:mm to HH:MM doesn't work neither. when I try only
a = xlsread('filename.xlsx',1,'A2')
I get: a = []
According to the documentation of datestr the syntax for minutes, months and hours is as follows:
HH -> Hour in two digits
MM -> Minute in two digits
mm -> Month in two digits
Therefore you have to change the syntax in the call for datestr. Because the serial date number format between Excel and Matlab differ, you have to add an offset of 693960 to the retrieved numbers from xlsread.
dateval = xlsread('test.xls',1,'A:A') + 693960;
datestring = datestr(dateval, 'dd/mm/yyyy HH:MM');
This will read the first column (A) of the first sheet (1) in the Excel-file. For better performance you can specify the range explicitly (for example 'A1:A20').
The code converts...
... to:
datestring =
22/06/2015 16:00
Edit: The following code should work for your provided Excel-file:
% read from file
tbl = readtable('data.xls','ReadVariableNames',false);
dateval = tbl.(1);
dateval = dateval + 693960;
datestring = datestr(dateval)
% plot with dateticks as x-axis
plot(dateval,tbl.(2))
datetick('x','mmm/yy')
%datetick('x','dd/mmm/yy') % this is maybe better than only the months
Minutes need to be called with a capital M to distinguish them from months.
Use a=datestr(xlsread('filename.xlsx',1,'A:A'),'dd/mm/yyyy HH:MM')
Edit: Corrected my original answer, where I had mixed up the cases needed.
I tried with this. It works but it is slow and I am not able to plot the dates at the end. Anyway:
table= readtable ('filename.xlsx');
dates = table(:,1);
dates = table2array (dates);
dates = datenum(dates);
dates = datestr (dates);

Dates and Charting

I have three sets of data and each has two columns.
The first column is Date and second column is Price. The dates are formatted different with each data set eg. Gold's date(1951), Money Supply M2's date (1951-01), and Money Sup. M3 Date (9/01/1951)
What i need:
I want to chart these with dates on x-axis and price on y-axis
Questions:
do i need to make Gold's Date(YYYY) and Money Supply M2's Date(YYYY-MM) a date object?
if so how?
do i need to place all dates in one column and create a sub to help sort the Price with appropriate Date?
Does this make sense?
I have very little experience programming in VBA and was having a hard time finding info on using dates. I came across an Answer, given by the person who edited this (brettdj), that listed a few extremely helpful sights on VBA programming for excel. One of those had info on the DateSerial() function. I was then able to throw together some code to quickly fix my problem.
Sub CreateDates()
Dim dt As Date
Dim s As String
For Each c In Worksheets("Sheet1").Range("A7:A27080").Cells
s = Len(c.Value)
If s = 4 Then '(YYYY)
dt = DateSerial(s, 7, 1)
c.Value = dt
End If
If s = 7 Then '(YYYY-MM)
y = Left(s, 4)
m = Right(s, 2)
dt = DateSerial(y, m, 1)
c.Value = dt
End If
Next c
End Sub
I could probably spend some time and add some regular expressions and make a one-size fits most, but this will work as i want have to use it very often.

Resources