Excel VBA not reading Date data the way I want - excel

I have a program that is supposed to read the date from a cell. In that cell, I have given it the value of =NOW() just by typing it into the cell outside of VBA. The cell is formatted as a date and the format is: dd-month (for example; 28-Jan). When VBA reads the cell, it reads it as mm/dd/yyy 00:00:00 AM/PM. Is there a way to make my code read the month from the format I set? A section of my code is below:
dashpos = InStr(1, ThisWorkbook.Worksheets("Main").Cells(2, 15), "-")
curmonth = Right(ThisWorkbook.Worksheets("Main").Cells(2, 15).Value, dashpos + 1)
The cell containing the date is Cell(2,15). I then go on to use the three letters on the month to determine the following month using a Select Case curmonth.

If your format is mm/dd/yyy 00:00:00 AM/PM in the worksheet, then the month will always have two digits. Therefor:
curmonth = CLng(Left(ThisWorkbook.Worksheets("Main").Cells(2, 15).Text, 2))

Sub testDateExtraction()
'Next day in the format you use in the sheet (no matter, in fact...):
Debug.Print Format(ThisWorkbook.Worksheets("Main").Cells(2, 15).Value + 1, "dd-mmm")
'Next month
Debug.Print MonthName(Month(ThisWorkbook.Worksheets("Main").Cells(2, 15).Value) + 1, True)
'If you insists to use the string type data:
Dim strDate As String, strMonth As String
strDate = CStr(Format(ThisWorkbook.Worksheets("Main").Cells(2, 15).Value + 1, "dd-mmm"))
strMonth = Right(strDate, 3)
Debug.Print MonthName(Month(DateValue(Day(Date) & "-" & strMonth & "-2020")) + 1, True)
End Sub

I then go on to use the three letters on the month to determine the following month
If you want to determine the next month, you can just use DateAdd and Month. The cell format is irrelevant.
The following returns the month number:
Month(DateAdd("m", 1, Cells(2,15)))
If you want it as a three letter string, for some reason, then
Format(DateAdd("m", 1, Cells(2,15)), "mmm")

Related

How to turn a file name into a date time code? (11-25-21 1530 to 11/25/21 15:30)

I use a macro to load an Excel file, pull data, and paste it into a log file. Each of the source Excel files are named by the sample date time it was created.
For instance, a sample created November 25th, 2021 at 3:30 PM would have the file name "11-25-21 1530". I want to pull the file name, assign it to a variable, and format that string into the date time format recognized by Excel for plotting (11/25/21 15:30). I cannot change the file names to include the "/" or ":" since these are not valid in file names.
I have something similar using a userform for time only where it autoformats into a 24hr time variable:
Private Sub TextBox2_AfterUpdate()
'Input would be HHMM or HMM
Dim a As String
a = Len(Me.TextBox2)
If a <= 2 Then 'This is for cases with H or HH
On Error Resume Next
Me.TextBox2 = Left(Me.TextBox2, a) & ":" & 0
ElseIf a = 3 Then
Me.TextBox2 = Left(Me.TextBox2, 1) & ":" & Right(Me.TextBox2, 2) 'This is for cases with HMM
Else
If Me.TextBox2.Value >= 2400 Then
MsgBox ("Incorrect Value")
Call CommandButton1_Click
Else
Me.TextBox2 = Left(Me.TextBox2, 2) & ":" & Right(Me.TextBox2, 2) 'This is for cases with HHMM
End If
End If
Me.TextBox2 = Format(Me.TextBox2, "HH:MM")
End Sub
How do I take the file name and split it into a date and then a time, format both to the proper Excel date time format, then combine them again for MM/DD/YY HH:MM output to log the results?
Use simple string handling to split the name into it's pieces. Then use DateSerial and TimeSerial to create a real Date out if it.
Once that is done, you can do whatever you want with the Date. I don't understand your request "into the date time format recognized by excel for plotting (11/25/21 15:30)", I do know that my Excel will have a hard time to understand 11/25/21 correctly (I am not located in the US...). When you write the date into a cell, write it as date and format the cell. If you need it in your code as string, use the Format-command.
The following function will split a filename, just note that there is no error handling or plausability test.
Function FilenameToDate(filename As String) As Date
Dim fileYear As Long, fileMonth As Long, fileDay As Long, fileHour As Long, fileMinute As Long
fileDay = Val(Mid(filename, 4, 2))
fileMonth = Val(Mid(filename, 1, 2))
fileYear = Val(Mid(filename, 7, 2))
fileHour = Val(Mid(filename, 10, 2))
fileMinute = Val(Mid(filename, 13, 2))
FilenameToDate = DateSerial(fileYear, fileMonth, fileDay) + TimeSerial(fileHour, fileMinute, 0)
End Function

Excel VBA - when subtracting two dates VBA sees them as numbers

I use Excel 2013.
When I subtract two dates in excel "1.11.2019" and "1.10.2019" I get the result 31 as you should.
But when I do the same thing in VBA I get 10000. So it sees them as regular numbers "1112019" and "1102019". How can I get the same result in VBA too?
Use DateDiff() function with d interval to get days difference between two date. Try like below.
Sub DateSubstract()
MsgBox DateDiff("d", Range("B1"), Range("A1"))
End Sub
You may have to format the string into a Date format
Dim diff As Long
Dim strDate1, strDate2 As String
Dim fDate1, FDate2 As Date
Set sh = ThisWorkbook.Sheets("myDate")
' convert in string with 8 caracters
strDate1 = Right("0" & sh.Range("A1").Value, 8)
strDate2 = Right("0" & sh.Range("B1").Value, 8)
'format Year, month, day
fDate1 = DateSerial(Right(strDate1, 4), Mid(strDate1, 3, 2), Left(strDate1, 2))
fDate2 = DateSerial(Right(strDate2, 4), Mid(strDate2, 3, 2), Left(strDate2, 2))
diff = DateDiff("d", fDate2, fDate1)
Debug.Print ("difference :" & diff)

Converting from dd.mm.yyyy to dd/mm/yyyy

I am currently using Excel 2010 and I have a column that contains date in such format (dd.mm.yyyy). I would like to change the dots to slash (/). I have tried using rng.Cells(1, 6) = WorksheetFunction.Substitute(rng.Cells(1, 6), ". ", "/")
However, when I do that, the result I get is different from my original date. For example, 02.11.2011 will become 11/02/2011.
The column that contains (dd.mm.yyyy) is in a date format
May I know why is that or is there another way of doing?
Is the column formatted as a date? If so, you can try
rng.Cells(1, 6) = Format(CDate(rng.Cells(1, 6)), "dd/MM/yyyy")
If it's an actual date value, then use NumberFormat
Range("B1").NumberFormat = "d/m/yyyy"
Range("B2").NumberFormat = "m/d/yyyy"
Range("B3").NumberFormat = "m-d-yyyy"
Im using this
splR = Split(oRange.Value, ".")
If UBound(splR) = 2 Then oRange.Value = Format(DateSerial(splR(2), splR(1), splR(0)), RegionalDateFormat) Else oRange.Value = oRange.Value
Function RegionalDateFormat(Optional outS As String)
Dim DateOrder As String
Dim DateSeparator As String
With Application
DateSeparator = .International(xlDateSeparator)
Select Case .International(xlDateOrder)
Case Is = 0
DateOrder = "mm" & DateSeparator & "dd" & DateSeparator & "yyyy"
Case Is = 1
DateOrder = "dd" & DateSeparator & "mm" & DateSeparator & "yyyy"
Case Is = 2
DateOrder = "yyyy" & DateSeparator & "mm" & DateSeparator & "dd"
Case Else
DateOrder = "Error"
End Select
End With
If outS = "Sep" Then outputS = DateSeparator Else outputS = DateOrder
RegionalDateFormat = outputS
End Function
Let's clarify that an Excel spreadsheet does not have a "date" data type per se. Excel's approach to dates is to store an integer, which you can choose to format as a date. So, for example, 43467 is the integer representing Jan 2 2019. (And the decimal part represents time during that day, so 43467.333.. represents Jan 2 2019 8:00 am.)
Try entering a date, then right-click > "Format cells" to format that cell as a number, to observe what I'm talking about.
In the same way, you can cause Excel to render that cell in the date format you want using the same method: select the cell > right-click > "Format cells", choose Custom, and enter a custom format, like dd.mm.yyyy.
Once you see that works, then your remaining task is simply to perform that same action from VBA, which would be with a statement like:
Range("B1").NumberFormat = "dd.mm.yyyy"
... as pointed out by others.
Now, if your initial attempt to get Excel to format your date cell as a number fails (it maintains its date appearance) then the date you see in the cell is actually stored as a string, and won't function as a date (for example to do date arithmetic). So you'll need to decide how to proceed -- perhaps convert these strings to "dates" (ie: numbers formatted as dates).

How to display sub string in reverse order but read from left to right in VBA

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

Subtract two columns with text and numbers in excel vba

I have two columns that contain information in the following format.
Column A - 35 days
Column B - 29 days
How can i subtract the two columns to show just a number, like 35 days - 29 days = 6.
The following equation should do the trick
= VALUE(MID(A1, 1, FIND(" ",A1))) - VALUE(MID(B1, 1,FIND(" ",B1)))
First we find the index of the space " " in the cell using FIND(" ", A1). Then we cut the string in the cell and we take the first index to the index of the space by MID(A1, 1, ...). Then we convert this value to a number using VALUE(...).
If all your days always have 2 digits, none of them are >= 100, then we can simplify this by
= VALUE(MID(A1, 1, 2)) - VALUE(MID(B1, 1,2))
But, I think the general case is preferable.
You can use the Replace function and replace days with an empty string, then you can convert your string to a integer with CInt:
?CInt(Replace("39 days", "days", ""))-CInt(Replace("25 days", "days", ""))
14
Edit:
or like Jeeped suggested in the commment you could use:
?Val("39 days")-Val("25 days")
14
You can also use SUBSTITUTE() function.
=(TRIM(SUBSTITUTE(A1,"days",""))*1)-TRIM(SUBSTITUTE(B1,"days",""))*1
Edit:
Only SUBSTITUTE() will also work.
=SUBSTITUTE(A1,"days","")-SUBSTITUTE(B1,"days","")
Change the cell number format to Custom with a format mask of 0 \d\a\y\s. Now type in 35 into A1 and 29 into B1. Now, while the cells display 35 days and 29 days they can be conventionally used like,
'on the worksheet
=a1-b1
'in vba
i = range("a1").value - range("b1").value
'in vba to see *35 days* in the Immediate window
?range("a1").text
You could even get a little fancier with a custom number format of,
[>1]0 \d\a\y\s;[=1]0 \d\a\y;0 \d\a\y\s;
Try this code:
Sub SumDays()
Dim lastRow As Long, i As Long, cellA As String, cellB As String
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lastRow
cellA = Cells(i, 1).Value
cellB = Cells(i, 2).Value
Cells(i, 3).Value = CInt(Mid(cellA, 1, InStr(1, cellA, " ") - 1)) + CInt(Mid(cellB, 1, InStr(1, cellB, " ") - 1))
Next
End Sub

Resources