I am trying to use the following code to display how long a series of commands took to run. In this example case, I expected it to come back with "10" or something similar.
Instead it comes back with:
What is going on and how can I format this correctly?
Sub timeyWimey()
Dim t1 As Date
Dim t2 As Date
Dim timeTaken As Date
t1 = Now()
Application.Wait (Now + TimeValue("0:00:10"))
t2 = Now()
timeTaken = t2 - t1
MsgBox timeTaken
End Sub
Edit:
Final Code after some great Answers:
Sub timeyWimey()
'Dim t1 As Double
'Dim t2 As Double
t1 = Now()
Application.Wait (Now + TimeValue("0:00:10"))
t2 = Now()
timeTaken = t2 - t1
MsgBox Format(timeTaken, "nn:ss.000")
End Sub
Results in:
BAM! Problem Solved! Thanks everyone for your help!
Date's are stored as a numeric value within the MS Access and MS Excel. So if in your immediate window (Ctrl+G) you type ?Cdbl(now()) you will get a number like this: 42195.5204050926.
The whole numbers depicts how many days have passed since 1899 December 30th, and the decimal shows how much of the current day has passed.
So in your code you are basically saying something like this:
timeTaken = 42195.5222337963 - 42195.5204050926
In this example I just checked Now() once and then again a few minutes later. So I ended up with 0.0018287037.
Now if I go to display that using a Date variable such as in your example, am basically saying what time was it at 0.0018287037 which is December 30th 1899, 12:02:38 AM.
You can visually see this by going back to your immediate window and typing ?cdate(0.0018287037) and you will get a result like: 12:02:38 AM. To take it one step further you can then type ?cdate(1.0018287037) and you will get a result saying: 1899-12-31 12:02:38 AM
So in your situation you can simply just change:
MsgBox timeTaken
To:
MsgBox Format(timeTaken, "nn:ss")
Note: I hadn't noticed in the screenshot it says "Excel" though this answer should still be valid.
Normally you'd use the DateDiff function to calculate the difference between two dates, but i think in your case you'll want something else, as DateDiff won't give you milliseconds. Instead, just replace your call to the "Now" function by Timer(), which is just a number of seconds (careful though, it only gives you the time elapsed since midnight, so t2 - t1 can be negative, and if your commands last several days you won't get any meaningful result).
You can try the timer function. As other answers indicate, there may be some caveats.
Dim startTime As Double, endTime As Double
startTime = Timer
Application.Wait (Now + TimeValue("0:00:10"))
endTime = Timer
msgBox endTime - startTime
Related
I have the following formula which fetches data from the same day from table UniqueLast:
=IFERROR(QUERY(UniqueLast!$A$3:X;"select * where dateDiff(A, now())=0"))
It runs correctly but sometimes the table where this formula is executed keeps the result from the previuos day which is already old. How can I make a regulation for running the formula in 00:00?
Create a macro function and include the above expression. Use VBExpress and create a script (.exe) to open the spreadsheet and run the macro. Add it in the Windows scheduled tasks.
Function to call in Macro
Function getNextRunTime() As Date
Dim curDate As Date
Dim curTime As Date
Dim chkTime As Date
Dim runTime As Date
curDate = Date
curTime = TimeValue(Now)
runTime = curDate + TimeValue("15:59:00")
chkTime = curDate + curTime
If chkTime > runTime Then 'schedule for next day'
runTime = DateAdd("d", 1, runTime)
End If
getNextRunTime = runTime
End Function
The SQL statement parameter of the QUERY function should be a single value of type TEXT. NOW() it not valid Google Query Language function. Google Sheets magnes dates on the background as numbers with a different EPOCH date so we should convert it to a date with the proper format. Try
=QUERY(
UniqueLast!$A$3:X,
"select * where dateDiff(A, date """&TEXT(now(),"yyyy-mm-dd")&""")=0"
)
Removed IFERROR in order to make it easy to check if change proposed works with the OP data. You could add it later once you are sure that it does.
When a date is returned from our UTC server database Windows very helpfully changes the Date to a DateTime (say 23 June 2017 to 2017-06-23 00:00) and then makes an adjustment for the current Time Zone (to, say 2017-06-22 16:00)... For years we have used the code below to convert it back...
About four months ago users running Windows 7 (Windows 10 doesn't seem to be effected) that did not have 'Automatically adjust clock for Daylight Saving Time' checked, or live in a state like Arizona where that option is not available, noticed that reports where returning the date from the day before - our DB is returning the correct date but the conversion is no longer working correctly..
Any suggestions?
Thanks
Public Function LocalDateFormat(ByVal InputDate As Date) As String
Dim vDate As String = InputDate.ToString("d", System.Globalization.CultureInfo.InvariantCulture)
Dim LocalZone As TimeZone = TimeZone.CurrentTimeZone
Dim CurrentOffset As TimeSpan = LocalZone.GetUtcOffset(InputDate)
Dim DayLightSaving As Boolean = LocalZone.IsDaylightSavingTime(InputDate)
Dim CalculatedOffset As New DateTime(InputDate.Ticks, DateTimeKind.Local)
If CurrentOffset.CompareTo(TimeSpan.Zero) < 0 Then
CalculatedOffset -= LocalZone.GetUtcOffset(InputDate)
If DayLightSaving = True Then
CalculatedOffset = CalculatedOffset.AddHours(1)
End If
Else
CalculatedOffset += LocalZone.GetUtcOffset(InputDate)
If DayLightSaving = True Then
CalculatedOffset = CalculatedOffset.AddHours(-1)
End If
End If
InputDate = CalculatedOffset
Dim vCulture As String = System.Globalization.CultureInfo.CurrentCulture.ToString
Dim vReturnDate As String = ""
Select Case vCulture
Case "en-US"
vReturnDate = Format(InputDate, "MM/dd/yyyy")
Case "en-GB"
vReturnDate = Format(InputDate, "dd/MM/yyyy")
Case Else
vReturnDate = Format(InputDate, "dd/MM/yyyy")
End Select
Return vReturnDate
End Function
Your entire function can be re-written as:
Public Function LocalDateFormat(ByVal InputDate As Date) As String
Return InputDate.ToLocalTime().ToShortDateString()
End Function
With the code so small, you may want to rethink whether there's any benefit of having this in a function at all.
As far as why your existing function didn't work properly:
TimeZone.GetUtcOffset already factors in whether DST is in effect or not, though it has some problems with that that are described in the MSDN docs.
You shouldn't be using TimeZone any more at all. If you need to work with time zones, use TimeZoneInfo, or Noda Time. In this case, you don't need either of them, as you're just converting from UTC to local time, which is what DateTime.ToLocalTime does.
This code has some logic that appears to think one should subtract an hour for DST if the offset is positive. Sorry, but DST doesn't work that way - you always add an hour (unless you are in Lord Howe Island, Australia, where you add 30 minutes).
It also seems to think you should add the offset from UTC if its positive and subtract it if its negative. This is essentially an absolute value function, and also incorrect.
All the culture stuff is handled for you by formatting within the current culture. There's no need to do it by hand.
You say it works fine on Windows 10, but I'm sorry - this is bad code that will have errors wherever it is run. Just use the built-in APIs provided by the framework. Don't reinvent the wheel. :)
I'm working on a problem where I need to determine the total time my program takes to execute. First line of code needs to write the current "Start time" and last lines of code need to write the current "End time". Then I'm subtracting "Start time" - "End Time" = Total Time.
I'm confused how I would use the FORMAT() function within VBA on the value of C2 to convert into seconds? Is there an other function that would work better than FORMAT? Basically I'm confused about Excel's Date Serial values and what they represent.
Code is below
EDIT: Thanks for the responses everyone. Both answers below work for what I'm trying to do.
sub ExecutionTime()
Worksheets("Table").Range("A2").Value = Now()
'All my executable code goes here. It's a relatively small program compiling a table so it
runs very quick.
Worksheets("Table").Range("B2").Value = Now()
Worksheets("Table").Range("C2").Value = Worksheets("Table").Range("A2").Value - Worksheets("Table").Range("B2").Value
end Sub
Do not use a Date data member or the Now method to analyze run time of your program. Instead, the Timer function is the most appropriate solution as it returns a Single representing seconds. It will require no type conversion and yields a more accurate result than an integer amount of seconds.
Using LimaNightHawk's answer as a template as you should be storing these in local variables instead of writing directly to the worksheet.
Dim startTime as Single
startTime = Timer()
' Do stuff
Dim endTime as Single
endTime = Timer()
Dim runTime as Single
runTime = endTime - startTime
Results should be written at the end of the routine.
With Worksheets("Table")
.Range("A2").Value = startTime
.Range("B2").Value = endTime
.Range("C2").Value = runTime
End With
Documentation on the timer function
In the first line of your program get the date (no need to format):
Dim startTime as Date
startTime = Now()
At the end of your program, get the date again:
Dim endTime as Date
endTime = Now()
Then use the DateDiff
Dim timeInSeconds as long
timeInSeconds = DateDiff("s", startTime, endTime)
DateDiff() is what you are looking for. The "s" defines that you are looking for the difference in seconds.
Worksheets("Table").Range("C2").Value = DateDiff("s", Worksheets("Table").Range("A2").Value, Worksheets("Table").Range("B2").Value)
EDIT: http://www.likeoffice.com/28057/excel-date to learn more about working with dates and times in Excel VBA. It is important to understand that dates work differently within the context of VBA, and have their own unique set of syntax functions for manipulating.
2nd EDIT: A cleaner version of this would be:
StartDateTime = Now()
'Run Code
Worksheets("Table").Range("C2").Value = DateDiff("s", StartDateTime, Now())
There's a few ways you can use VBA to format cells / variables.
In no particular order, firstly you can format ranges with the NumberFormat property which can be applied like so:
Worksheets("Table").Range("C2").Value = Now()
Worksheets("Table").Range("C2").NumberFormat = "ss"
The other way is that you could format Now() using the Format() function:
Worksheets("Table").Range("C2").Value = Format(Now(), "ss")
See the documentation from Microsoft to implement different formats:
NumberFormat: http://msdn.microsoft.com/en-us/library/office/ff196401%28v=office.15%29.aspx
Format: http://msdn.microsoft.com/en-us/library/office/gg251755%28v=office.15%29.aspx
How i generally go about bragging my process time to user
Sub Process()
Dim startTime as Date
Dim endTime as Date
startTime = Now
'Logic for what your process must do
endTime = Now
MsgBox "Process completed in : " & Format(endTime - startTime, "hh:mm:ss")
End Sub
How can I compare the last characters using of month, day, and year or the completedate rather than using datetime, Example case is Textbox3 is greater than textbox9 because Textbox3 day = 26 and textbox9 day = 25.
Mycode:
'in my case I have 2 Textbox.
'Date format: hh.mm MM/DD/YYYY
'Textbox3= 02.02 03/26/2014
'TextBox9= 21.01 03/25/2014
If Val(Strings.Left(TextBox9.Text.Trim, 5)) < Val(Strings.Left(Textbox3 .Text.Trim, 5))Then
TimeError.ShowDialog()
End If
Really, the fastest, most reliable, and most effective way to do this is to parse the values into a DateTime. And taking a step back from there, the fastest, most effective way to get a date time from a textbox is to use a DateTimePicker control.
But if that's not an option, we can build on the code I gave you last time:
Dim temp1() As String = Textbox3.Text.Trim().Split(" .".ToCharArray())
Dim temp2() As String = Textbox9.Text.Trim().Split(" .".ToCharArray())
If DateTime.Parse(temp2(2)) < DateTime.Parse(temp1(2)) Then
TimeError.ShowDialog()
End If
I'll add that you probably want to also have code to compare the time values in the case where the date portions are equal. Given this as a starting point, you should be able to write that code on your own.
in vb.net you can comopare dates like this:
dim date1 as date = cdate(Textbox1.text)
dim date2 as date = Date.now()
if date1.date=date2.date then ....
and months like this
if date1.month=date2.month then ...
New VB coder here, trying to check if todays date is more then 10 years past a date from a grabbed database entry, and display a message if it is.
The Database is already imported and set up in the VB application H ave made, and working, I made a report to display the information.
I am guessing I need to use the Datediff but I can't seem to get it to work, Thanks.
I will give my variable name here
Dim Custsince as Date
'From the Database here
CustSince = CustListodr("Custsince")
Thanks in advance, working with dates is not my strong point.
You can just use a TimeSpan directly by subtracting the dates:
Dim customerLength = DateTime.Now - Custsince
Dim approxYears = customerLength.TotalDays / 365
If the date read from the database is already stored in a Date variable, you can simply subtract one date from another to get the difference. The result of subtracting two dates is a TimeSpan object. TimeSpan objects contain useful properties that allow you to see how long the span of time is in various units (e.g. days, hours, minutes). For instance:
Dim date1 As Date = ...
Dim date2 As Date = Date.Now
Dim span As TimeSpan = date2 - date1
If span.TotalDays >= 3650 then ' Ten years
'...
End If
Alternatively, if you need to compare calendar years, rather than the actual span of time, you can compare the years from each date, like this:
If date2.Year - date1.Year >= 10 Then
'...
End If
If the date being read from the database is stored as a string, rather than as a Date value, you would need to use Date.Parse or Date.ParseExact to convert the string into a Date value.