Hello I have this program that lets you start and stop time on a job the problem I am having now is that if it switches from A.M to P.M while time is tracked the program doesn't work right. so I have a button that puts the Time.Now when its pressed in a excel cell than when you stop the job it puts the End time in another cell and then it go's in and grabs the two cells and subtracts them. what I need it to do is put the Date and Time in the cell then both and only give me the Minutes and hours that it took. here is what I have for code.
'This code is for when you start the job.
'which this is only hours and minutes prob should be
'Date and Time
Dim StartTime As String = DateTime.Now.ToString("h\:mm")
'This line of code puts it in an excel cell
oXL.ActiveCell.Offset(0, 13).Value = StartTime
'This code is for when you end a Job.
'Again its only hours and minutes but prob should be
'Date and Time
Dim EndTime As String = DateTime.Now.ToString("h\:mm")
'This is the Total Time I am going to have
'I used TimeSpan
Dim TotalTime As TimeSpan
'Now this is where I put the End time when the
'Button is clicked.
oXL.ActiveCell.Offset(0, 14).Value = EndTime
'Once Both cells have the start and end Times I get them both with this code.
'Again this should prob be Date and Time.
Dim time1 = TimeSpan.ParseExact(oXL.ActiveCell.Offset(0, 13).Value, "h\:mm", CultureInfo.CurrentCulture)
Dim time2 = TimeSpan.ParseExact(oXL.ActiveCell.Offset(0, 14).Value, "h\:mm", CultureInfo.CurrentCulture)
'I then use this code to do my math.
TotalTime = time2 - time1
The Total time I need i only to be the hour an minutes that it took to do the job.
You are taking two dates, converting them and storing them into string variables, then reading them back into dates to calculate. You are hoping that they are in the right format when you parse them back, this in itself is top heavy. But why store dates as string at all? You can convert a date to a string at any time on the fly with the .ToString() method. Just keep them as dates and write them out to the excel sheet as strings when needed. The values will be the same either way, and you're not relying on your sheet to have the data in the adjacent locations, you will just perform the calculation and you are done.
'This code is for when you start the job.
'which this is only hours and minutes prob should be
'Date and Time
Dim StartTime As DateTime = DateTime.Now
'This line of code puts it in an excel cell
oXL.ActiveCell.Offset(0, 13).Value = StartTime.ToString("h\:mm")
'This code is for when you end a Job.
'Again its only hours and minutes but prob should be
'Date and Time
Dim EndTime As DateTime = DateTime.Now
'Now this is where I put the End time when the
'Button is clicked.
oXL.ActiveCell.Offset(0, 14).Value = EndTime.ToString("h\:mm")
'Once Both cells have the start and end Times I get them both with this code.
'Again this should prob be Date and Time.
' Dim time1 = TimeSpan.ParseExact(oXL.ActiveCell.Offset(0, 13).Value, "h\:mm", CultureInfo.CurrentCulture)
' Dim time2 = TimeSpan.ParseExact(oXL.ActiveCell.Offset(0, 14).Value, "h\:mm", CultureInfo.CurrentCulture)
'This is the Total Time I am going to have
'I used TimeSpan
Dim TotalTime As TimeSpan
'I then use this code to do my math.
TotalTime = EndTime.Subtract(StartTime)
'output time difference
MsgBox(TotalTime.ToString)
.:EDIT:.
To give you an example of total hours and minutes:
Dim startTime As DateTime = DateTime.Now 'read from excel instead
Dim endTime As DateTime = DateTime.Now.AddDays(1.5).AddMinutes(60) 'read from excel
Dim span As TimeSpan
span = endTime.Subtract(startTime)
MessageBox.Show("Total Hours: " & (span.Days * 24) + span.Hours & ", Total Mins: " & span.Minutes)
I hope this will be able to assist in your calculation (grabbing a start and end date string, converting it to DateTime, then outputting the hours and minutes):
'This code is for when you start the job.
'which this is only hours and minutes prob should be
'Date and Time
Dim StartTime As String = DateTime.Now.ToString("h\:mm")
'This code is for when you end a Job.
'Again its only hours and minutes but prob should be
'Date and Time
Dim EndTime As String = DateTime.Now.AddHours(3.5).ToString("h\:mm")
'This is the Total Time I am going to have
'I used TimeSpan
Dim TotalTime As TimeSpan
'Once Both cells have the start and end Times I get them both with this code.
'Again this should prob be Date and Time.
Dim time1 = DateTime.Parse(StartTime)
Dim time2 = DateTime.Parse(EndTime)
'I then use this code to do my math.
TotalTime = time2 - time1
Dim Hours = TotalTime.Hours
Dim Minutes = TotalTime.Minutes
System.Console.WriteLine(Hours & "h " & Minutes & "m")
Related
I used the following code to have a Countdown which would span over 10 slides whilst in slideshow mode. I placed the shapes in a SlideMaster Layout.
Set QS = ActivePresentation.Designs(2).SlideMaster.CustomLayouts(2)
Dim Seconds As Integer
Seconds = 30
QS.Shapes("Counter").TextFrame.TextRange = Seconds
For i = 1 To 30
Dim WAIT As Double
WAIT = Timer
While Timer < WAIT + 1
DoEvents
Wend
Seconds = Seconds - 1
QS.Shapes("Counter").TextFrame.TextRange = Seconds
Next i
Dim time As Date
Dim count As Integer
time = Now()
count = 30
time = DateAdd("s", count, time)
Do Until time < Now
DoEvents
With ActivePresentation.Designs(2).SlideMaster.CustomLayouts(2).Shapes("Counter").TextFrame.TextRange
.Text = Format((time - Now()), "hh:mm:ss")
End With
Loop
Both the codes work properly if they are not placed in SlideMaster Layout.
Are there any better means to have a countdown that spans across multiple slides?
There is a better way to show a countdown by using the Format (Now(), "hh:mm:ss")
To create a countdown we need two values:
The current time
The future time when the countdown expires
Dim time As Date
Dim count As Integer
time = Now() 'the current time
count = 30
time = DateAdd("s", count, time) 'the future time after 30 seconds
The above gives us the two values.
Now, we can make a loop to change the text inside the Counter shape.
Do Until time < Now() 'We change text until the present time passes the set "future time"
DoEvents
For i = 1 To 10 'Assuming you want the countdown in slides 1 To 10
With ActivePresentation.Slides(i).Shapes("countdown").TextFrame.TextRange
.Text = Format((time - Now()), "hh:mm:ss")
End With
Next i
Loop
You can use this to have a countdown across multiples slides.
I mocked up similar code along the lines of:
Set Shape = Application.ActivePresentation.Designs(1).SlideMaster.CustomLayouts(1).Shapes("Testing")
Shape.TextFrame.TextRange.Text = "Did it work"
As you found, the shape's text did not change while presenting the slideshow, although it did update the underlying slide master once you left the slideshow. However, I found that by including the following after this code, it worked as expected:
Shape.Visible = msoTrue
My code is as follows:
Private Sub tbRcvrDepartTime_textchanged(sender As Object, e As EventArgs) Handles tbRcvrDepartTime.TextChanged
'Converts the 90 Receiver Arrival & Departures Date & Times to a string for comparison
Dim raTime As String = tbRcvrArriveTime.Text 'Takes the Time only String and converts to string
Dim raDate As String = dpRcvrArriveDate.Text 'Takes the DateTimePicker and converts date to string
Dim raDateString = String.Concat(raDate, " ", raTime) 'Puts together the Date & Time into one continuous string
'Dim raDateFormat As String = "MM-dd-yyyy HH:mm" 'Sets the String to Date style Format
Dim raResultDate As Date = CDate(raDateString) 'Finalizes the String for use in below comparison
Dim rdTime As String = tbRcvrDepartTime.Text 'Takes the Time only String and converts to string
Dim rdDate As String = dpRcvrDepartDate.Text 'Takes the DateTimePicker and converts date to string
Dim rdDateString = String.Concat(rdDate, " ", rdTime) 'Puts together the Date & Time into one continuous string
'Dim rdDateFormat As String = "MM-dd-yyyy HH:mm" 'Sets the String to Date Format
Dim rdResultDate As Date = CDate(rdDateString) 'Finalizes the String for use in below comparison
'Checks to see if 2 or more hours have elapsed since Receiver Arrival/Departure Date & Time
Dim elapsedR As TimeSpan = rdResultDate.Subtract(raResultDate)
tbRcvrDepartTime.BackColor = If(elapsedR.TotalMinutes > 120, Color.LightPink, Color.White)
End Sub
Both raTime & rdTime are separate textboxes.
Both raDate & rdDate are datetimepickers.
When I run the code "live" initially the first record I look at is displayed correctly. Once I move to another record, this goes out the window... I get random results where it will not change the backcolor to the proper color if >120 minutes has elapsed. Other times it changes the backcolor when there is <120 minutes elapsed. Sometimes no change in backcolor when it should or it will change color when it should not. I attempted to originally do this using TotalHours but met with the same results. It is random and is not consistent. I have worked on this for 2 days now with no difference in results. My thinking is there needs to be a way to "refresh" the rdResultDate & raResultDate info when each new record is loaded but I am unable to do that with my code knowledge.
The code must be able to take into account if a new date is present - ie raDate: 11/01/2016 and raTime: 23:46 and
rdDate: 11/02/2016 and rdTime: 03:00 - this would exceed 2 hours (or 120 minutes) and should read "True" and change the backcolor as it is over 2 hours (or 120 minutes).
However if the following were true:
raDate: 11/01/2016 and raTime: 23:46 and
rdDate: 11/02/2016 and rdTime: 01:00 this would not exceed 2 hours (or 120 minutes) and should read "False" and would not change the backcolor.
All of this code:
Dim Detention90 As String
Try
If elapsedR.TotalMinutes > 120 Then
Detention90 = "True"
Else
Detention90 = "False"
End If
Select Case Detention90.ToString
Case = "True" : tbRcvrDepartTime.BackColor = Color.LightPink
Case Else : tbRcvrDepartTime.BackColor = Color.White
End Select
Catch ex As Exception
'If a problem occurs, show Error message box
MessageBox.Show("Receiver Arrive Time & Depart Time Elapsed error" & vbCrLf & "Lines 1424-1434")
End Try
condenses down to just this:
Dim elapsedR As TimeSpan = rdResultDate.Subtract(raResultDate)
tbRcvrDepartTime.BackColor = If(elapsedR.TotalMinutes > 120, Color.LightPink, Color.White)
Not sure if it will directly address your issue, but it was a bit too much for a comment and I've found compacting code in this way is often extremely beneficial for tracking down difficult bugs.
But in this case, I suspect the main issue is parsing the datetime values... that you're not always parsing the DateTime value you expect from a given input string. Specifically, you have format string variables raDateFormat and rdDateFormat, but then call Date.Parse() such that these format variables are never used, and you are left at the mercy of whatever the default date format is for your thread, process, or system. If you're on a system that uses a d/m/y order as in the UK instead of the US-style m/d/y, you'll end up with some strange results. You probably want DateTime.ParseExact() instead.
I have a excel file.
I wish to write a Excel vba to compare the system time and the cell value time.
If system time is exceed the cell value time, it will show a pop out message to inform user that, the time is exceed.
My file will look like this:
I have been research a while but seem like only vba code will able to complete this requirement.
Sub TimeCheck()
Dim ValueTime As Date
Dim SysTime As Date
SysTime = Now()
Finalrow = Cells(Rows.Count, 14).End(xlUp).Row
'Column 14 stands for N, change as required
For I = 6 To Finalrow
'6 stands for first row filled with value, change as required
ValueTime = Cells(I, 14).Value
If TimeValue(ValueTime) < TimeValue(SysTime) Then
Cells(I, 14).Offset(, 1).Value = "Time is exceeeded" '1 is offsetting to column O. Use 2 for column P, 3 for Q and so on, as you prefer.
MsgBox ("Time is exceeeded for user entry in N" & I)
'To store the time error in adjacent O column cells, and to popup for each error
'Remove either as required - esp MsgBox, it is very annoying - put only because you asked in original question
End If
Next I
End Sub
If you want only advise the guest that the time input does not exceed the current, you don't need a vba (intersect will be one way) you can use the validate date
and you can customize the input msg and also the error msg if the value isn't correct.
Example
Sub TimeNow()
Dim cValue As Date '// Cell Value
Dim sTime As Date '// System
cValue = Sheets("Sheet1").Range("B2").Value
sTime = TimeValue(Now)
If sTime > cValue Then
MsgBox "TiMe iS Up. STOP " & TimeValue(Now)
Else: Exit Sub
'or do something
End If
End Sub
You can use the function TimeValue, which returns the value of time as a number between 0 and 1. Posting a simple code to check on cell N6 alone.
/// You may, of course, use loops to check for a range of cells, or use the excel events, or keyboard shortcuts to run the macro.///
Sub TimeCheck()
Dim ValueTime As Date
Dim SysTime As Date
ValueTime = Range("N6").Value
SysTime = Now()
If TimeValue(ValueTime) < TimeValue(SysTime) Then
MsgBox ("Time is exceeeded")
End If
End Sub
I have a datagridview filled with series of reports ordered in date and time for about an year
List is like below
27/1/2015 10:56:32 AM
27/1/2015 11:56:41 AM
27/1/2015 12:54:42 PM
28/1/2015 8:54:54 AM
28/1/2015 9:02:39 PM
29/1/2015 11:02:47 AM
29/1/2015 9:03:00 PM
30/1/2015 9:03:00 PM
How can I highlight or change color of that particular row, where each new day series begins? i mean highlighting row
where new day begins, 27, 28th etccc. So far i am trying like this
Private Sub myFindRow()
Dim sTime As DateTime = Me.myDataset.myReportTable.Compute("Max(reporttime)", "")
Dim eTime As DateTime = Me.myDataset.myReportTable.Compute("Min(reporttime)", "")
Dim cTime As DateTime = sTime
For Each Day As DateTime In Enumerable.Range(0, (eTime - sTime).Days).Select(Function(i) sTime.AddDays(i))
changeRowColor()
Next Day
End Sub
Private Sub changeRowColor()
For Each myRow As DataGridViewRow In Me.myDatagridView.Rows
Dim myTime As DateTime
myTime = myRow.Cells(2).Value
Next
End Sub
but not getting any idea to proceed futher. any guidence?
I don't think you need to compute anything. I would change the color of the first row then I would loop all rows and compare the date with the previous row. If the day are different then I would change the row color.
Something like this
Private Sub myFindRow()
' Change the color of the first row
For rowIndex As Integer = 1 To Me.myDatagridView.Rows.Count-1
Dim curRow As DataGridViewRow = Me.myDatagridView.Rows(i)
Dim prevRow As DataGridViewRow = Me.myDatagridView.Rows(i-1)
If CType(curRow.Cells(2).Value, DateTime).Date <> CType(prevRow.Cells(2).Value).Date Then
' Change the color of row curRow
End If
Next
End Sub
I have a userform that requires the user to input a specific date and time through two separate comboboxes, cboStartDate, cboStartTime. The user will also have to input the duration in a text field, txtDuration.
Upon saving, the start date and time will be stored in a formatted cell [DD/MM/YYYY HH:MM AM/PM]. The end date and time will be calculated from the duration field and stored in another cell with the same formatting. Something like this:
+-----------------------+-----------------------+
| startTime | endTime |
+-----------------------+-----------------------+
| 2/4/2012 11:30:00 AM | 2/4/2012 2:00:00 PM |
+-----------------------+-----------------------+
However, after running the userform through, the start time is not stored, and the end time is not calculated. Something like this:
+-----------------------+-----------------------+
| startTime | endTime |
+-----------------------+-----------------------+
| 2/4/2012 12:00:00 AM | 2/4/2012 12:00:00 AM |
+-----------------------+-----------------------+
Below is my part of my VBA code:
Dim iRow As Long
Dim ws As Worksheet
Dim startDate As Date
Dim unFmtStartDuration() As String
Dim startDuration As Double
Dim minTest As Integer
Dim endDate As Date
Dim endDuration As Double
Set ws = Worksheets("EVENTS")
'Search for the last row in the worksheet
iRow = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
'Date manipulation and set start and end timings
unFmtStartDuration() = Split(cboStartTime.Text, ":")
startDuration = unFmtStartDuration(0)
If unFmtStartDuration(1) = "00" Then
minTest = 0
Else
minTest = unFmtStartDuration(1)
If minTest = 30 Then
startDuration = startDuration + 0.5
End If
End If
startDate = DateValue(DateAdd("h", startDuration, cboDate.Text & " 12:00AM"))
ws.Cells(iRow, 4).Value = startDate
endDuration = txtDuration.Value
endDate = DateValue(DateAdd("h", endDuration, startDate))
ws.Cells(iRow, 5).Value = endDate
So how can I get this part sorted out? Would appreciate any help here. Thanks.
P.S. Would like to post screenshots here, but my reputation here is too low for it. Sorry.
It looks like you are only adding the time when minTest = 30, but this value probably varies quite a bit. Also, in one instance, you are comparing a string, and another a number when referencing unFmtStartDuration, which may work, but is confusing when reading your code.
To follow your current method, use
startDuration = Val(unFmtStartDuration(0) + Round(Val(unFmtStartDuration(1)) / 60, 2)
to replace this
startDuration = unFmtStartDuration(0)
If unFmtStartDuration(1) = "00" Then
minTest = 0
Else
minTest = unFmtStartDuration(1)
If minTest = 30 Then
startDuration = startDuration + 0.5
End If
End If
This will take whatever the time is and convert it to the decimal form you are using, instead of relying on the 30 match. (Unless you need that specifically. If so, say so, as I think this can still be arranged with rounding tricks.)
However, I think a better option would be to use
startDuration = TimeValue(cboStartTime.Text) * 24
So no other math or checks are involved.
Also, unless cboStartTime.Text (and subsequently startDuration) is greater than 24 hours, this
startDate = DateValue(DateAdd("h", startDuration, cboDate.Text & " 12:00AM"))
will always return the date specified in cboDate.Text with an implied 12:00:00 AM. To correct this, you will want to change to
startDate = DateAdd("h", startDuration, cboDate.Text & " 12:00AM")
I think there is some more to fix, but hopefully this gets you going in the right direction...