I need to summarize some info depending on the date. I mean, I need to sum some info if the date correspondig to that info is within an interval.
Is there anyway to do it?
I have seen "DATEDIFF", but what I need would be something like:
'If the data evaluted is whitin the next interval sum the value.
Hope you understood my question.
Thanks in advance.
EDITED: I added a pic to make it more understandable
This will do it. I don't know where you want to use total, so now you just get a messagebox.
Sub SumBetweenTwoDates()
Dim total As Integer
total = 0
Dim firstDate As Date, secondDate As Date
firstDate = DateValue("20/11/2012")
secondDate = DateValue("20/12/2012")
For i = 1 To 5
If Range("A" & i).Value >= firstDate And Range("A" & i).Value <= secondDate Then
total = Range("B" & i).Value + total
End If
Next i
MsgBox total
End Sub
Use one formula in the cell you want the sum in:
Assuming the value is in A1:A100 and the dates are in B1:B100
=SUMPRODUCT((B1:B100>=DATEVALUE("1/1/2004"))*(B1:B100<=DATEVALUE("31/1/2004")),A1:A100)
will return the sum of the values fro January 2004
Related
I currently have a spreadsheet that has the dates (excluding weekends and holidays) for the past 10 years in column A. For example, A1 contains "7/19/2007" and A2520 contains "7/19/2017"
Column E contains the closing price for the stock SPY on those corresponding dates.
I am trying to figure out the standard deviation for the past 5 years. In order to do so, my idea was to write a VBA code that would select today's date and the previous five years, and then use that to calculate the standard deviation.
This list is updated everyday, meaning tomorrow, it will contain 7/20/2017 and the closing price for that day. My issue is that I cannot figure out how to make it so it will select today's date and the past five years, so then I can calculate the standard deviation.
Thank you guys for all your help! Sorry if this seems simple, I have just started learning VBA last week!
How's this? I make a few assumptions, like your dates are contiguous, and there's no empty cell in your Date column. I also assume your dates are in order, ascending. (So your day 10 years ago is in say row 10, and today is in row 1000).
Sub get_difference()
Dim dateRng As Range, cel As Range, priceRng As Range
Dim dateCol As Long, stockCol As Long, lastDate As Range
Dim tdyDate As Date, decadeAgo As Date
dateCol = 1 ' column A has your dates
stockCol = 5
tdyDate = WorksheetFunction.Text(Now(), "mm/dd/yyyy")
decadeAgo = get_Previous_Date(tdyDate)
Debug.Print decadeAgo
With Sheets("Stock Prices") ' change name as necessary
With .Columns(dateCol)
Set lastDate = .Find(what:=tdyDate) ' Assuming no break in data from A1
'lastDate.Select
Set cel = .Find(what:=decadeAgo)
'cel.Select
End With
Set rng = .Range(.Cells(cel.Row, dateCol), .Cells(lastDate.Row, dateCol))
'rng.Select
Set priceRng = rng.Offset(0, stockCol - dateCol)
'priceRng.Select
'priceRng.Offset(0, 1).Select
priceRng.Offset(0, 1).FormulaR1C1 = "=IFERROR((RC[-1]/R[-1]C[-1])-1,"""")"
End With
End Sub
Function get_Previous_Date(Dt As Date) As Date
' https://www.mrexcel.com/forum/excel-questions/37667-how-subtract-year-date-2.html
Dim numYearsBefore as Long, numDaysBefore as Long, numMonthsBefore as Long
numYearsBefore = 10 ' Change this to any amount of years
numDaysBefore = 0
numMonthsBefore = 0
get_Previous_Date = DateSerial(Year(Dt) - numYearsBefore, Month(Dt) - numMonthsBefore, Day(Dt) - numDaysBefore)
End Function
Make changes as needed, i.e. sheet name (I called mine "Stock Prices"), and the columns. It's also a little verbose, and could be made more compact, but I figured it'd help you learn to keep it like that. I suggest stepping through with F8 to see what happens, and uncommenting the .select lines so you can visually see what it's doing.
Column A is StartDate
Column B is EndDate
When I run the Macro it returns the answer 1 for all my dates as I am adding 1 to my DateDiff, then DateDiff must be 0.
What is wrong with my DateDiff ?
Sub CalculateDays()
Dim LastRow As Long
Dim StartDate As Date
Dim EndDate As Date
Dim Days As Single
With Worksheets("Sheet1")
'Determine last Row in Column A
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
'Calculate Difference between Start Date And End Date in Days
For i = 2 To LastRow
StartDate = .Cells(i, 1)
EndDate = .Cells(i, 2)
Days = DateDiff("d", StartDate, EndDate)
.Cells(i, 3) = Days + 1
Days = 0
Next i
End With
End Sub
Sample data:
Start Date | End Date
=========================
13-Feb-17 | 28-Feb-17
14-Feb-17 | 28-Feb-17
02-Mar-17 | 04-Mar-17
13-Feb-17 | 15-Feb-17
13-Feb-17 | 13-Feb-17
15-Jan-17 | 15-Feb-17
01-Feb-17 | 12-Feb-17
Your code actually runs fine for me - but I am sure that the values in columns A and B are actually dates. If you are not sure about this then use the CDate function to ensure that the value in the cells is converted to a date before passing to the DateDiff function e.g.
StartDate = CDate(.Cells(i, 1).Value)
Your code with this added in:
Option Explicit
Sub CalculateDays()
Dim LastRow As Long
Dim StartDate As Date
Dim EndDate As Date
Dim Days As Single
Dim i As Long
With Worksheets("Sheet1")
'Determine last Row in Column A
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
'Calculate Difference between Start Date And End Date in Days
For i = 2 To LastRow
StartDate = CDate(.Cells(i, 1).Value)
EndDate = CDate(.Cells(i, 2).Value)
Days = DateDiff("d", StartDate, EndDate)
.Cells(i, 3) = Days + 1
Days = 0
Next i
End With
End Sub
Edit
I just read this where it states a problem with South African date formats:
.. my region was "English (South Africa)") and I had the date separator as "/", however Excel kept changing this to a "-". ...
So maybe it's worth checking on your regional settings and maybe reformat your dates as dd/mmm/yyyy instead of dd-mmm-yyyy and checking the output.
Maybe the CDATE function will not be required after all (as I mentioned your code ran fine for me in an Australian English regional setting context).
Alternatively, instead of a function just write a formula:
=ROUND(B2-A2+1,0)
why do you need datediff function. to get the days difference use
days=enddays - startdate
your code is working fine in excel 2016 in widows. As mentioned by #RobinMackenzie you have some problem with regional date settings.
I currently have an input box for a variable that changes everymonth:
r_mo = Application.InputBox(prompt:="Enter the reporting month as YYYYMM (Eg:201604). Errors in this entry will result in errors in the results.")
This prompts an input box which one has to manually enter into... However, I want to automate this process and eliminate the need for an input box. Isn't there a now function in vba that will automatically generate today's date.
From a now, or system function all I want to do is extract the year in four digits and the month in two digits.
So for example, if we're in decemeber 2016
Sub asasdas ()
"Now function"
r_mo = YYYYMM ' automatically updated from "now function"
End Sub
I appreciate any help you can give me and thank you so much all.
Sub GetMonthYear
GetMonthYear = Year(Now) & Right("00" & Month(Now), 2)
End Sub
That'll do it. Returns the Year portion of Now() and concatenates it to the Month portion of Now(). Since Month will return a single digit for January to September, we wrap this by adding "00" to the Month and take the last two characters from the Right. For "9" we create "009" and take the last two characters for "09". For "10", we would create "0010" and take the last two characters for "10".
Sub GetYearMonthDay()
Dim GetYearMonthDay As String
GetYearMonthDay = Year(Now) & "-" & Right("00" & Month(Now), 2) & "-" & Right("00" & Day(Now), 2)
MsgBox GetYearMonthDay
End Sub
Please refer my answer given below
Sub UsingTheDateFunction()
'this is the standard 6/3/2021 format
Dim theDate As Date
theDate = Date
MsgBox theDate
End Sub
In my worksheet, I have 2 cells that serve to denote the minimum date and maximum date. Also in the worksheet, I have a table structure. What I'd like to achieve, is to have extra columns appended to the end of the table showing each month in between those 2 dates, inclusive.
For example, minimum date is 7/31/2014 and maximum is 6/30/2015. I would like a macro to populate the column headers 7/31/2014, 8/31/2014, ..., 6/30/2015 to the end of my table.
Unfortunately, Excel tables can't have dynamic headers. I then thought of using VBA by having an array of dates, and then setting the Range.Value to the array, but couldn't quite figure out how to code it.
Thank you.
You want DateAdd()
Assuming you want to get the last date of every month you should instead use DateSerial()
Public Sub test()
Dim startDate As Date
Dim endDate As Date
Dim currentDate As Date
startDate = CDate("7/31/2014")
endDate = CDate("6/30/2015")
currentDate = startDate
Do While currentDate <= endDate
MsgBox currentDate
'currentDate = DateAdd("m", 1, currentDate)
currentDate = DateSerial(Year(currentDate), Month(currentDate) + 2, 0)
Loop
End Sub
You don't really need VBA. A pretty simple Excel formula will do the trick.
In the example below, cell C5 has =$C$2. Cell C6 has this formula:
=IF(C5>=$C$2,"",DATE(YEAR(C5),MONTH(C5)+2,DAY(0)))
and, for the purposes of this example, it is copied down to cell C23. You would just have to copy it as far down as you would need in your longest conceivable table.
Explanation: the formula adds 2 months to the previous date, but then takes "day 0" of that month which is equivalent the last day of the month before (which I think is what you want based on your example). If the previous date has reached the max, then it just writes an empty string "" from then on.
Maybe you want this in a row, not a column; the idea is the same.
Here is a small example based on:
Here is the code:
Sub MAIN()
Dim d1 As Date, d2 As Date, Tbl As Range
d1 = Range("A1").Value
d2 = Range("A2").Value
Set Tbl = Range("B3:E9")
Call setLabels(d1, d2, Tbl)
End Sub
Sub setLabels(dt1 As Date, dt2 As Date, rng As Range)
Dim rToFill As Range, r As Range
Set rToFill = Intersect(rng(1).EntireRow, rng).Offset(-1, 0)
For Each r In rToFill
dv = dt1 + i
r.Value = dv
i = i + 1
If dt1 + i > dt2 Then Exit Sub
Next r
End Sub
This is based on 1 day increments. If you want 1 month increments, then use this for dv
dv = DateSerial(Year(dt1), Month(dt1) + i, Day(dt1))
VBA has functions that handle dates. If you look at the link:
http://software-solutions-online.com/2014/02/21/excel-vba-working-with-dates/
It will show you how to make variables of data type Date using VBA, which will make adding and subtracting months very easy for you.
After that, add methods to create the columns you want and the .Name property to name the columns.
What I am trying to do is check column AJ for each date that occurs during a year determined by variable "Año". For the dates that are I would like to see how far into the year they are (that is how many days after the first January each date occurs); this is the part that is giving me the error (indicated in my code). What I need is a function to give how many days into the year a date occurs or a better way of writing that line of code.
For Each cl In Workbooks(WbkA).Worksheets("Sheet1").Range("AJ2:AJ1000")
If (cl.Value - ("01/01/" & Año)) > 0 And (cl.Value - ("01/01/" & Año)) < 366 Then 'if it´s in this year
ValueA = ValueA + (cl.Value * ((cl.Offset(0, -13).Value - ("01/01/" & Año)) / 365)) ' this part is giving me the error
End If
End If
Next cl
You are complicating things too much. DateDiff can perform the calculations you want:
Dim iniDate As Date, curDate As Date
Dim ValueA As Integer, Año As Integer
Año = 2010
iniDate = Format(CDate("01/01/" & Año), "MM/dd/yyyy") 'You can change the Format
curDate = Format(CDate("01/05/" & Año), "MM/dd/yyyy")
ValueA = DateDiff("d", iniDate, curDate) 'RESULT -> 4
Dates are stored as the number of days since 1/1/1900, so you can just subtract two dates to get the number of days.
Dim lAno As Long
Dim rCell As Range
Dim dValueA As Double
lAno = 2010
For Each rCell In Sheet1.Range("AJ2:AJ100").Cells
If Year(rCell.Value) = lAno Then 'if it's in the year
'+= some value * the number of days
dValueA = dValueA + (rCell.Offset(0, -13).Value * (rCell.Value - DateSerial(lAno, 1, 1)))
End If
Next rCell