EDIT: Based on answers I was able to get min/max date from a range:
Dim dt As Date
dt = WorksheetFunction.Min(Range("D2:D300"))
But it's not enough. How do I use this function with an array instead of a range?
Original post:
I have the following columns:
The format is: DD/MM/YYYY HH:MM
I'm trying to get the soonest datetime from column one and the latest datetime from column two. In this case:
02/01/2017 6:07 (earlist datetime from the first column, 2nd of January)
02/02/2017 14:11 (latest datetime from the second column, 2nd of February)
I have a multidimensional array (myData) with the values from the cells and my functions are these ones:
Private Function GetLatestDateFromData() As String
Dim latestDate As String
Dim i As Long
latestDate = myData(1, ColumnsIndex(3) - 1)
For i = 1 To UBound(myData, 1) - 1
If latestDate < myData(i, ColumnsIndex(3) - 1) Then
latestDate = myData(i, ColumnsIndex(3) - 1)
End If
Next
GetLatestDateFromData = latestDate
End Function
Private Function GetEarliestDateFromData() As String
Dim earliestDate As String
Dim i As Long
earliestDate = myData(1, ColumnsIndex(2) - 1)
For i = 1 To UBound(myData, 1) - 1
If earliestDate > myData(i, ColumnsIndex(2) - 1) Then
earliestDate = myData(i, ColumnsIndex(2) - 1)
End If
Next
GetEarliestDateFromData = earliestDate
End Function
The problem is that my results are the following ones:
startingFrom = DateValue(GetEarliestDateFromData) 'returns 01/02/2017, 1st of February
untilDate = DateValue(GetLatestDateFromData) 'returns 01/06/2017, 1st of June
Seems I have a problem with the date formatting. Somehow, days and months are mixed. How do I fix it?
Thanks
EDIT: DateSerial (as suggested in a linked thread) does not apply here because I not only care about the date but the time as well. DateSerial only takes year-month-day as arguments.
To fix your dates use the format function, e.g.
date = Format(value, "MM\/DD\/YYYY")
More easily you could just compare the actual values (e.g. 02/01/2017 06:07 equals 42737,2548611111) which are independent of the displayed format.
Furthermore I'd suggest you use the WorksheetFunction.Max function which is the vba equvalent to excel Max-function, returning the greatest vaule in your range, something like:
date = WorksheetFunction.Max(your_used_range)
Related
I am iterating through dates in a loop to execute different snippets of code.The following piece of code in the loop gives me a
runtime error '6' Overflow
when assigning the cell's value to dateClaim:
Dim dateClaim As Date
Dim rngDateClaimeMade As Range
Set rngDateClaimeMade = dfensCSheet.Range("AC7") 'AC contains dates in format dd.mm.yyyy
dateClaim = rngDateClaimeMade.value
dateClaimMonth = Format(Month(dateClaim), "00")
dateClaimYear = Year(dateClaim)
Any ideas/ help is very much appreciated!
So that looks like 24.12.2020 is a text not a date in that cell and therefore it cannot be converted automatically.
If your dates are always in this format dd.mm.yyyy you can convert it like below:
Option Explicit
Public Sub Example()
Dim TextDate As String ' this is a text looking like a date (but is not a date just a string)
TextDate = "24.12.2020" ' instead read your cell value here
' test if the string has a format that we can convert
If Not TextDate Like "??.??.????" Then
MsgBox "Date was not in expected format dd.mm.yyyy"
Exit Sub
End If
' split text into 3 parts by dot as delimiter
Dim SplitDate() As String
SplitDate = Split(TextDate, ".")
' reorder the 3 parts to make a real numeric date
Dim NumericDate As Date
NumericDate = DateSerial(SplitDate(2), SplitDate(1), SplitDate(0))
' this numeric date is now a real date that can be formatted as desired
Debug.Print Format$(NumericDate, "yyyy-mm-dd") 'returns 2020-12-24
End Sub
You can then use
Dim dateClaim As Date
dateClaim = DateSerial(SplitDate(2), SplitDate(1), SplitDate(0))
Dim dateClaimMonth As String
dateClaimMonth = Format$(dateClaim , "mm")
Dim dateClaimYear As String
dateClaimYear = Format$(dateClaim , "yyyy")
if you need month and year as text! If you need them numeric don't use Format$()!
VBA cannot convert text dates with dots directly. So try:
dateClaim = DateValue(Replace(rngDateClaimeMade.Value, ".", "/"))
dateClaimMonth = Month(dateClaim)
dateClaimYear = Year(dateClaim)
Apply the format 00 where the month is to be displayed.
I am processing a .txt file in VBA.
Amongst other tasks, I need to read in a string representing a date and display the actual date in Excel.
A date string in the .txt file looks like "190223"
This represents 23/02/2019
My challenge is to get this done.
What I have done so far is:
' ... loop
With ActiveWorkbook.Worksheets(1)
' Other statements here
' Event date time
.Range("N" & i).Value = StrReverse(Mid(.Range(keyword.Offset(0, 4).Address), 1, 2) & _
"/" & Mid(.Range(keyword.Offset(0, 4).Address), 3, 2) & _
"/" & Mid(.Range(keyword.Offset(0, 4).Address), 5, 2))
End With
But I get the undesired output:
32/20/91 ' For a date string 190223 the desired output should be 23/02/19
Any help would be much appreciated.
Thanks in advance.
Convert it into a real date
You must extract year, month and day of that string and then convert this into a real date.
Then you can format the date to what ever date format you like. The value that is saved in the cell is then a real date value (not a string!) so you can calculate with it.
I highly recommend to read How Dates Work in Excel – The Calendar System Explained + Video to understand the background and why real dates are so important.
Here is an example:
Option Explicit
Public Sub ConvertDateExample()
Const InputStr As String = "190223"
Dim InputYear As Integer
Dim InputMonth As Integer
Dim InputDay As Integer
'extract year, month and day
InputYear = Left(InputStr, 2)
InputMonth = Mid(InputStr, 3, 2)
InputDay = Right(InputStr, 2)
'put it together to a real date
Dim RealDate As Date
RealDate = DateSerial(InputYear, InputMonth, InputDay)
'write the date into a cell
Range("A1").Value = RealDate
'format that cell to your desired format
Range("A1").NumberFormat = "dd/mm/yyyy"
End Sub
I want to run a code that transfers data from one sheet to another based on the year (eg 01/01/2018 - 31/1/2018).
The sheet contains 2 columns with dates, start_date and end_date stored as dates, so I did an If statement but it doesn't seem to "understand" the dates values that I stored previously.
'Dates columns
Dim fechaIniTarget As Variant
Dim fechaFinTarget As Variant
'Ini = start / Fin = end
Set fechaIniTarget = Range("D2")
Set fechaFinTarget = Range("E2")
If fechaIniTarget.Value = "01/01/2018" And fechaFinTarget.Value = "31/12/2018" Then
' function
MsgBox "PROCESO COMPLETO"
End If
I tried parsing the dates as integer but it still doesn't work.
You compare a date fechaIniTarget.Value against a string "01/01/2018". Use a real date with the DateSerial function instead to compare date against date.
If fechaIniTarget.Value = DateSerial(2018, 1, 1) And fechaFinTarget.Value = DateSerial(2018, 12, 31) Then
Also note that you used 2 times fechaIniTarget but I guess the second one should be fechaFinTarget.
Also don't use Variant if not necessary. Instead declare your variables As Range here:
Dim fechaIniTarget As Range
Dim fechaFinTarget As Range
I am trying to get the month and year for today's date.
Sub automation()
Dim wsheet As Worksheet
Dim month As Integer
Dim year As Integer
Set wsheet = Application.Workbooks("try").Worksheets("try")
month = Application.WorksheetFunction.month(Date)
year = Application.WorksheetFunction.year(Date)
End Sub
My expected output is 5 for month and 2017 for year if today's date is 15/5/2017.
You may have some problem because you've shadowed some existing functions Month and Year with your variable names month and year. So, use different variable names:
Dim m As Integer
Dim y As Integer
And then either:
m = DatePart("m", Date)
y = DatePart("yyyy", Date)
Or:
m = month(Date)
y = year(Date)
In my Excel 2010 (not tested in 2013) while Month is a worksheet function, it's not exposed to VBA for some reason. If you want to use the WorksheetFunction instance of these, you can technically do it using the Application.Evaluate method, like so:
m = Evaluate("MONTH(""" & Date & """)")
y = Evaluate("YEAR(""" & Date & """)")
The built-in VBA.DateTime.Month and VBA.DateTime.Year functions, however, are available and that is what would be used in the second example above.
If you must for some reason retain the month and year variable names, then you need to fully qualify the function call to avoid error:
month = VBA.DateTime.Month(Date)
year = VBA.DateTime.Year(Date)
Change in your code like this:
Sub CurrentDate()
Dim currentMonth As Long
Dim currentYear As Long
currentMonth = Month(Date)
currentYear = Year(Date)
Debug.Print currentMonth; currentYear
End Sub
Month and Year are functions of the VBA.DateTime, do not use them for variable names.
In general, Application.WorksheetFunction does not have a function, related to current date, in contrast to VBA.DateTime.Month or VBA.DateTime.Year (or at least I did not find) any in the Excel Library.
dim this as date
this = Format(Date(), "yyyy")
this = Format(Date(), "mm")
Answering late but I wanted to reference the VBA documentation from microsoft's own page.
To get Month from date:
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/month-function
Sample snippet:
Dim MyDate, MyMonth
MyDate = #February 12, 1969# ' Assign a date.
MyMonth = Month(MyDate) ' MyMonth contains 2.
To get Year from date:
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/year-function
Sample snippet:
Dim MyDate, MyYear
MyDate = #February 12, 1969# ' Assign a date.
MyYear = Year(MyDate) ' MyYear contains 1969.
I like these answers, but I needed one that would contain both the month and year in the format (my use case is as an accountant). This was my solution:
Dim today As Date
today = Date ' Get the current date
Dim period As String
period = Format(today, "MM/YYYY") ' Convert the date to MM/YYYY
I am new to VBA and am working an a macro that will help me transform call records into something useful for analysis.
Column E contains the Date of Call which is formatted YYYYMMDD. I need to convert to MM/DD/YYYY. (i.e. 20140101 convert to 1/1/2014)
Column F contains the Time of Call which is formatted HHMMSS or HMMSS depending on whether the hour has two digits or one. I need to convert to HH:MM:SS (i.e. 130101 or 90101 which needs to convert to 13:01:01 and 9:01:01, respectively). Because the hour is missing the tens digit if the value is below ten, (below) I have added a "0" to the beginning of the value so I can use the date function.
I currently enter the the following formula in Column K and autofill until the end of the range:
=DATE(LEFT(E2,4),MID(E2,5,2),RIGHT(E2,2))+TIME(LEFT(IF(LEN(F2)=5, 0&F2, F2),2),MID(IF(LEN(F2)=5, 0&F2, F2),3,2),RIGHT(IF(LEN(F2)=5, 0&F2, F2),2))
The formula results in a value like "1/1/2013 13:01:01".
Can someone help me write the VBA code to automate this process?
Thank you.
Created separate UDFs for this. Paste the following into a module.
Function MorphDate(DateRng As Range)
Dim DateStr As String: DateStr = DateRng.Value
Dim Yr As String, Mt As String, Dy As String
Yr = Left(DateStr, 4)
Mt = Mid(DateStr, 5, 2)
Dy = Right(DateStr, 2)
MorphDate = Format(DateSerial(Yr, Mt, Dy), "m/dd/yyyy")
End Function
Function MorphTime(TimeRng As Range)
Dim TimeStr As String: TimeStr = TimeRng.Value
Dim Hh As String, Mm As String, Ss As String
If Len(TimeStr) = 5 Then TimeStr = "0" & TimeStr
Hh = Left(TimeStr, 2)
Mm = Mid(TimeStr, 3, 2)
Ss = Right(TimeStr, 2)
MorphTime = Format(TimeSerial(Hh, Mm, Ss), "hh:mm:ss")
End Function
Function MorphDateTime(DateRng As Range, TimeRng As Range)
Application.Volatile
MorphDateTime = CDate(MorphDate(DateRng)) + CDate(MorphTime(TimeRng))
End Function
Now you can use the formulas MorphDate to change the date, MorphTime to change the time, and MorphDateTime for a combination of both.
Screenshot:
Let us know if this helps.
EDIT:
If you want to use it inside a subroutine, add the following code to the module:
Sub MorphingTime()
Dim DateRng As Range, Cell As Range
Set DateRng = Range("E2:E100") '--Modify as needed.
For Each Cell in DateRng
Range("K" & Cell.Row).Value = MorphDateTime(Cell, Cell.Offset(0,1))
Next Cell
End Sub
Hope this helps.