Subtracting from a date in VBA? - excel

I'm having big problems doing operation with the date in Excel VBA.
I have a form that has a textbox where the user will enter the date. The problem is that he may enter it in different formats (eg, 1.08.2011 for 1st of August, or 8/1/11 for the same day). Now what I want to do is to subtract some days from that date that he enters in the TextBox. I had to success so far and I don't know how to do it.
I tried something like this
Format((Format(Me.datalivrare.Value, "dd.mm.yyy") - 4), "dd.mm.yyyy")
Where datalivrare is that textbox where the user enters the date and 4 is the number of days I want to subtract from that date... and I want the format to always be dd.mm.yyyy no matter what they enter in that textbox.

I suggest looking at the DateAdd function for VBA
http://www.techonthenet.com/excel/formulas/dateadd.php
http://office.microsoft.com/en-us/access-help/dateadd-function-HA001228810.aspx
You could do the following:
Format(DateAdd("d", -4, CDate(Me.datalivrare.Value)), "dd.mm.yyyy")

First cast to Date, then subtract days, then format appropriately:
Format(DateAdd("d", -4, CDate(Me.datalivrare.Value)), "dd.mm.yyyy")

the best to add and substract from dates on vba is dateadd() (with negative number for substractions)
also, in your example code there's a missing y on the format string (it accepts 1, 2 or 4 y, only)

It is important to check if the user entered a value that VBA can interprit as a date so first you should:
If isDate(Me.datalivrare.Value) Then
str_Date = Format(DateAdd("d", -4, CDate(Me.datalivrare.Value)), "dd.mm.yyyy")
Else
MsgBox "Not a valid date value", vbCritical + vbOkOnly, "Invalid Entry"
End If
I think bluefeet's answer had the most information so far and I borrowed the use of DateAdd and CDate.

Just a simple answer, as many aren't using the OP's code.
Eg: Minus 4 days
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/dateadd-function
Sub DateTest()
Dim DateVar As Date
DateVar = DateAdd("d", -4, Date)
Debug.Print DateVar
End Sub

Related

VBA: AddDate + time changes the format

Can someone advise, please?
I have used DateSerial, DateValue with mixed results, also Format(... doesn't work in this case.
When I use DateAdd("d", 1, DateValue(x.Value))
06/05/2021 20:20:20
is changed to
05/07/2021 20:20:20
All I need is this 06/05/2021 20:20:20 to be changed to this 07/05/2021 20:20:20
FYI if it helps the format of my cells is as follows:
Try this and swap dd/mm to mm/dd (the format will remain dd/mm/yyyy):
Format(DateAdd("d", 1, cel.Value), "mm/dd/yyyy") & " 18:59:59"
If you wish to use DateAdd, and your value is a true date value (not text), use:
DateAdd("d", 1, x.Value)
This will not alter a time part. If x is 2021-05-06 20:20:20, result will be:
`2021-05-07 20:20:20`
If x is 2021-05-06 18:59:59 you can add one hour:
DateAdd("h", 1, x.Value)
for the result: 2021-05-06 19:59:59
just x.value + 1 it'll get that it's a date and add one day

Using excel VBA, Is there a way for me to get the name of the current dates day (eg. Monday) [duplicate]

I have a small code that gets the Day Name of the Dates listed in Excel. But the problem is, it's not getting the right Day Name(e.g. Tuesday).
For Example:
sDayName = Format(Day(11/1/2016), "dddd")
Then the output produces an incorrect Day Name which is:
sDayName = "Sunday"
when it's supposed to be "Tuesday".
Thanks for the help guys.
For your specific request, assuming your date string is formatted as your regional setings:
sDayName = Format("11/01/2016", "dddd")
If you want the weekday for today:
sDayName = Format(Date, "dddd")
If you want the weekday for any date in any regional settings
sDayName = Format(DateSerial(2016, 11, 4), "dddd")
'change 2016, 11, 4 for your year, month, day values
:)
WEEKDAY Function can be used on this topic and in Vba Codes . For example:
Label2.Caption = WeekdayName(Weekday(TextBox2, 0), False, 0)
I used this function in when I created userform about date entry to active cell.
i use the answer kadrleyn wrote.
But you have to pay attension that the string returned from
WeekdayName(Weekday(TextBox2, 0), False, 0)
is not trimmed so if you want to use it in if statement you have to use trim function.
ps. i could not add comment to his/her answer because of my reputation.

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.

Why does transposing array with dates in format dd/mm/yy change some dates to mm/dd/yy format?

Behavior:
When I transpose a 1 dimensional array, containing dates, in order to print them to a sheet in it's entirety, some dates are changed from the dd/mm/yy to mm/dd/yyyy.
In particular, when the day of the month:
is less than or equal to 12, such as January 2, 2016 (02/01/16), or May 11, 2016 (11/05/16), then the date is printed with the date format mm/dd/yy and is aligned right.
is greater than or equal to 13, such as April 23, 2016 (23/04/16), or December 17, 2016 (17/12/16), then the date is printed with the date format dd/mm/yyyy and is aligned left.
When I use a for loop to print each date separately, or I do not transpose the array and print each date in the first row of each column however, all dates are printed with the format dd/mm/yy and all dates are aligned right.
Additional information:
I have:
Windows 8.1 (English U.S.)
Office 365 Student (English U.S) (Excel 2016 32 bit)
Locale setting: Netherlands
Code:
Option Explicit
Sub TransposeDatesArray()
Dim arrDates() As Date
Dim i As Variant
ReDim arrDates(0)
For i = CDate("Januari 01, 2016") To CDate("December 31, 2016")
If UBound(arrDates) = 0 Then
ReDim arrDates(1 To 1)
Else
ReDim Preserve arrDates(1 To UBound(arrDates) + 1)
End If
arrDates(UBound(arrDates)) = i
Next
With ThisWorkbook.Worksheets(1)
.Cells.Delete
.Cells(1, 1).Resize(UBound(arrDates)).Value = Application.Transpose(arrDates)
.Cells(1, 2).Resize(UBound(arrDates)).Value2 = Application.Transpose(arrDates)
.Cells(1, 3).Resize(UBound(arrDates)).Formula = Application.Transpose(arrDates)
For i = LBound(arrDates) To UBound(arrDates)
.Cells(i, 4).Value = arrDates(i)
.Cells(i, 5).Value2 = arrDates(i)
.Cells(i, 6).Formula = arrDates(i)
Next
End With
End Sub
Result:
After doing some more research, I have found the following:
It would seem that the Application.Transpose(arrDate) transposes not only the array, but also date values when they are stored as actual date.
Consider the date , 42373 (January 4, 2016)
Debug.Print Format(CDate(42373), "mmmm d, yyyy")
produces januari 4, 2016
Debug.Print Application.Transpose(Format(CDate(42373), "mmmm d, yyyy"))
produces april 1, 2016
It appears that a date value can be transposed when stored as an actual date. The transposing effectively reorders the date from day/month to month/day after which the the month becomes the day and the day becomes the month because the system still uses the day/month format. This can only be done if the day of the month is 12 or less, because after transposing the day becomes the month.
I hit this problem, but interestingly, the date switch (from dd/mm to mm/dd) on transpose only happened when I ran the macro from a toolbar button; if I ran it from inside the VBA editor, or from the Developer menu>Macros dialogue box, it worked fine.
To make it work no matter where I ran the macro from, I added a function before the transpose to convert all dates to strings (looping through my array and using the CStr function), and then converted back from strings to dates after the transpose (another loop and CDate function) - the loops having to be slightly different to account for the transposed dimensions.
Transposing array with Application.Transpose() transforms the "Date" data type into "String". Not able to explain why.
So my suggestion is to transform the Column with "Date" data type into "Long" before you do the Application.Transpose() (simply using CLng).
After that you can either transform it back to "Date" or just set the number format as "Date" for the cells, where you would like to paste the array.
I resolve this issue using .FormulaLocal to write back the array in the sheet.

VBA Date as integer

is there a way to get the underlying integer for Date function in VBA ? I'm referring to the integer stored by Excel to describe dates in memory in terms of number of days (when time is included it can be a float then I guess). I'm only interest in the integer part though. Is there just another function for that ?
For example, for today() I'd like to be able to get back 40877..
Date is not an Integer in VB(A), it is a Double.
You can get a Date's value by passing it to CDbl().
CDbl(Now()) ' 40877.8052662037
From the documentation:
The 1900 Date System
In the 1900 date system, the first day that is supported is January 1,
1900. When you enter a date, the date is converted into a serial number that represents the number of elapsed days starting with 1 for
January 1, 1900. For example, if you enter July 5, 1998, Excel
converts the date to the serial number 35981.
So in the 1900 system, 40877.805... represents 40,876 days after January 1, 1900 (29 November 2011), and ~80.5% of one day (~19:19h). There is a setting for 1904-based system in Excel, numbers will be off when this is in use (that's a per-workbook setting).
To get the integer part, use
Int(CDbl(Now())) ' 40877
which would return a LongDouble with no decimal places (i.e. what Floor() would do in other languages).
Using CLng() or Round() would result in rounding, which will return a "day in the future" when called after 12:00 noon, so don't do that.
Just use CLng(Date).
Note that you need to use Long not Integer for this as the value for the current date is > 32767
Public SUB test()
Dim mdate As Date
mdate = now()
MsgBox (Round(CDbl(mdate), 0))
End SUB
You can use bellow code example for date string like mdate and Now() like toDay, you can also calculate deference between both date like Aging
Public Sub test(mdate As String)
Dim toDay As String
mdate = Round(CDbl(CDate(mdate)), 0)
toDay = Round(CDbl(Now()), 0)
Dim Aging as String
Aging = toDay - mdate
MsgBox ("So aging is -" & Aging & vbCr & "from the date - " & _
Format(mdate, "dd-mm-yyyy")) & " to " & Format(toDay, "dd-mm-yyyy"))
End Sub
NB: Used CDate for convert Date String to Valid Date
I am using this in Office 2007 :)

Resources