-
Detention Code not working
Below is a complete SUB I have currently in my code. The Specific area of issue is that the DETENTION area is not working. I consistently get back $0.00 as a result. The code runs through the 5th TRY statement, within the included code, 3-4 times in Debug showing one option (or CASE) being all true therefore should run. This works on initial run through then this SUB repeats itself 4x. On the 4th pass the previously all true case mysteriously develops one false statement which then bypasses because where all statements that were previously true, one goes false, resulting in a end result of $0.00 to be returned.
My coding skills are not top shelf and I am just not understanding why the following scenarios are occurring:
- Code runs through the 5th TRY statement 4 times, Why?
- What causes a previously all TRUE case statement to change to at least one false item on the 4th pass.
- Is there a better way to smooth this code out to make it work as intended?
The intended result is to look at the time elapsed between the scheduled date/time and the departure date/time. If that elapsed time is greater then 2 hours, then begin determining the amount of detention time AFTER the first two hours (in other words the first 2 hours after the scheduled date/time is "free" or not claimable for detention). This is to be done ONLY if the arrival date/time is PRIOR to or exactly at the scheduled appointment date/time (in other words if the truck is late to the appointment, then no detention can be claimed). Also one has to allow that the date could potentially roll over into the next date.
Code:
Private Sub Detention_ValueChanged(sender As Object, e As EventArgs) Handles dtp01DepartDate.ValueChanged, dtp01DepartTime.ValueChanged, dtp90DepartDate.ValueChanged, dtp90DepartTime.ValueChanged
'Dim c As Decimal
Dim shipA As Date = (dtp01ArriveDate.Value.Date) + (dtp01ArriveTime.Value.TimeOfDay) ' 01 Arrival Date/Time
Dim shipD As Date = (dtp01DepartDate.Value.Date) + (dtp01DepartTime.Value.TimeOfDay) ' 01 Departure Date/Time
Dim shipT As Date = (dtp01PickDate.Value.Date) + (dtp01PickTime.Value.TimeOfDay) ' 01 Scheduled P/U Date/Time
Dim rcvrA As Date = (dtp90ArriveDate.Value.Date) + (dtp90ArriveTime.Value.TimeOfDay) ' 90 Arrival Date/Time
Dim rcvrD As Date = (dtp90DepartDate.Value.Date) + (dtp90DepartTime.Value.TimeOfDay) ' 90 Departure Date/Time
Dim rcvrT As Date = (dtp90DropDate.Value.Date) + (dtp90DropTime.Value.TimeOfDay) ' 90 Scheduled Delivery Date/Time
Dim arrive01 As TimeSpan = shipA.Subtract(shipT) ' 01 Arrival Date/Time - 01 Scheduled Time
Dim arrive90 As TimeSpan = rcvrA.Subtract(rcvrT) ' 90 Arrival Date/Time - 90 Scheduled Time
Dim depart01 As TimeSpan = shipD.Subtract(shipT) ' 01 Departure Date/Time - 01 Scheduled Date/Time
Dim depart90 As TimeSpan = rcvrD.Subtract(rcvrT) ' 90 Scheduled Date/Time - 90 Departure Date/Time
'Detention Due Box coloring - If at ship/Rcvr more than 2 hours
Try
If depart01.TotalMinutes >= 180 Then
tb01.BackColor = Color.Red
ElseIf depart01.TotalMinutes >= 120 AndAlso depart01.TotalMinutes < 180 Then
tb01.BackColor = Color.Yellow
ElseIf depart01.TotalMinutes < 120 Then
tb01.BackColor = Color.Chartreuse
End If
Catch ex As Exception
End Try
' Is Detention Due from Receiver?
Try
If depart90.TotalMinutes >= 180 Then
tb90.BackColor = Color.Red
ElseIf depart90.TotalMinutes >= 120 AndAlso depart90.TotalMinutes < 180 Then
tb90.BackColor = Color.Yellow
ElseIf depart90.TotalMinutes < 120 Then
tb90.BackColor = Color.Chartreuse
End If
Catch ex As Exception
End Try
'Did truck arrive on time at Shipper?
Try
If arrive01.TotalMinutes >= 30 Then
lblPUTime.BackColor = Color.Red
lblPUTime.ForeColor = Color.White
ElseIf arrive01.TotalMinutes >= 15 AndAlso depart01.TotalMinutes <= 29 Then
lblPUTime.BackColor = Color.Yellow
lblPUTime.ForeColor = Color.Black
ElseIf arrive01.TotalMinutes >= 5 AndAlso depart01.TotalMinutes < 15 Then
lblPUTime.BackColor = Color.Cyan
lblPUTime.ForeColor = Color.Black
ElseIf arrive01.TotalMinutes <= 4 Then
lblPUTime.BackColor = Color.Transparent
lblPUTime.ForeColor = Color.Black
End If
Catch ex As Exception
End Try
'Did truck arrive on time at Receiver?
Try
If arrive90.TotalMinutes >= 30 Then
lblDroppedDate.BackColor = Color.Red
lblDroppedDate.ForeColor = Color.White
ElseIf arrive90.TotalMinutes >= 15 AndAlso depart90.TotalMinutes <= 29 Then
lblDroppedDate.BackColor = Color.Yellow
lblDroppedDate.ForeColor = Color.Black
ElseIf arrive90.TotalMinutes >= 5 AndAlso depart90.TotalMinutes < 15 Then
lblDroppedDate.BackColor = Color.Cyan
lblDroppedDate.ForeColor = Color.Black
ElseIf arrive90.TotalMinutes <= 4 Then
lblDroppedDate.BackColor = Color.Transparent
lblDroppedDate.ForeColor = Color.Black
End If
Catch ex As Exception
End Try
Dim c As Decimal
Try
Select Case True
'Lipsey Logistics
Case tbBrokerAgency.Text = "LIPSEY LOGISITCS"
If depart01.TotalMinutes > 120 AndAlso arrive01.TotalMinutes <= 10 AndAlso depart90.TotalMinutes < 120 Then
c = CDec(Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 17.5, 0))
tbDetentionOwed.Text = c.ToString("C2")
ElseIf depart90.TotalMinutes > 120 AndAlso arrive90.TotalMinutes <= 10 AndAlso depart01.TotalMinutes < 120 Then
c = CDec(Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 17.5, 0))
tbDetentionOwed.Text = c.ToString("C2")
ElseIf depart01.TotalMinutes > 120 AndAlso arrive01.TotalMinutes >= 10 AndAlso depart90.TotalMinutes > 120 AndAlso arrive90.TotalMinutes >= 10 Then
c = CDec(Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 17.5, 0))
tbDetentionOwed.Text = c.ToString("C2")
Else
c = 0
tbDetentionOwed.Text = c.ToString("C2")
End If
'Total Quality Logistics
Case tbBrokerAgency.Text = "TOTAL QUALITY LOGISTICS"
If depart01.TotalMinutes > 120 AndAlso arrive01.TotalMinutes <= 10 AndAlso depart90.TotalMinutes < 120 Then
c = CDec(Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 17.5, 0))
tbDetentionOwed.Text = c.ToString("C2")
ElseIf depart90.TotalMinutes > 120 AndAlso arrive90.TotalMinutes <= 10 AndAlso depart01.TotalMinutes < 120 Then
c = CDec(Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 17.5, 0))
tbDetentionOwed.Text = c.ToString("C2")
ElseIf depart01.TotalMinutes > 120 AndAlso arrive01.TotalMinutes >= 10 AndAlso depart90.TotalMinutes > 120 AndAlso arrive90.TotalMinutes >= 10 Then
c = CDec(Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 17.5, 0))
tbDetentionOwed.Text = c.ToString("C2")
Else
c = 0
tbDetentionOwed.Text = c.ToString("C2")
End If
'Coyote Logistics
Case tbBrokerAgency.Text = "COYOTE"
If depart01.TotalMinutes > 120 AndAlso arrive01.TotalMinutes <= 10 AndAlso depart90.TotalMinutes < 120 Then
c = CDec((CDec((depart01.TotalMinutes - 120) / 30) * 17.5))
tbDetentionOwed.Text = c.ToString("C2")
ElseIf depart90.TotalMinutes > 120 AndAlso arrive90.TotalMinutes <= 10 AndAlso depart01.TotalMinutes < 120 Then
c = CDec((CDec((depart01.TotalMinutes - 120) / 30) * 17.5))
tbDetentionOwed.Text = c.ToString("C2")
ElseIf depart01.TotalMinutes > 120 AndAlso arrive01.TotalMinutes >= 10 AndAlso depart90.TotalMinutes > 120 AndAlso arrive90.TotalMinutes >= 10 Then
c = CDec((CDec((depart01.TotalMinutes - 120) / 30) * 17.5))
tbDetentionOwed.Text = c.ToString("C2")
Else
c = 0
tbDetentionOwed.Text = c.ToString("C2")
End If
'CH Robinson Logistics
Case tbBrokerAgency.Text = "CH ROBINSON"
If depart01.TotalMinutes > 120 AndAlso arrive01.TotalMinutes <= 10 AndAlso depart90.TotalMinutes < 120 Then
c = Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 25, 0)
tbDetentionOwed.Text = c.ToString("C2")
ElseIf depart90.TotalMinutes > 120 AndAlso arrive90.TotalMinutes <= 10 AndAlso depart01.TotalMinutes < 120 Then
c = Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 25, 0)
tbDetentionOwed.Text = c.ToString("C2")
ElseIf depart01.TotalMinutes < 120 AndAlso arrive01.TotalMinutes >= 10 AndAlso depart90.TotalMinutes > 120 AndAlso arrive90.TotalMinutes >= 10 Then
c = Math.Max(CDec((depart01.TotalMinutes - 120) / 30) * 25, 0)
tbDetentionOwed.Text = c.ToString("C2")
Else
c = 0
tbDetentionOwed.Text = c.ToString("C2")
End If
End Select
Catch ex As Exception
Dim frm As New MeMsgCalcError(ex, "'Detention' Calculation Error. Lines 1993-2021")
frm.Show()
End Try
End Sub
-
Re: Detention Code not working
Your code refers to dozens of controls on a form. Could you provide the form as well? Preferably the entire project. Also those Try/Catch blocks that have no code in the Catch block could be hiding exceptions being thrown that are relevant to your problem. Have you tried outputting those to the debug window?
-
Re: Detention Code not working
I don't feel like wasting too much time on that code, but I wonder if the last ElseIf line may have something to do with the problem. It's the only place where there's <120 instead of >120. A typo?
edit: Now I see that other things in that line are reversed, so no doubt it's intentional. But you don't deal with the case where TotalMinutes = 120. That's asking for trouble. You should use >= or <= in the appropriate places.
BB
-
Re: Detention Code not working
That's a fair amount of code. In the end, I think you need to narrow it down a bit. What did you find when you debugged it? The first step in solving this should be to put a breakpoint on a line before where you think the problem occurs, then step through the code watching how the variables change, and which path the execution takes. By doing that, you should be able to say more clearly which part of the code is the problem.
Also, let me second the view that having empty catch blocks is a totally bad idea. Those Try...Catch blocks shouldn't be there anyways, since none of that code deals with exceptional circumstances. There is no exception that could be thrown by that code which couldn't also be tested for ahead of time. Using exception trapping (and ignoring, in this case) when you can test for something, is really bad.
-
Re: Detention Code not working
I have re-worked the code a bit to parry out the TRY/Catch statements and simply made them a IF statement. This is an obvious oversight on my part and thanks for pointing that out.
-----
Allow me to ask my concern in a simple manner then that someone may be able to answer. :I am not looking for someone to do my code, I need to adjust my code to work as I intend it and should be able to once I understand what I am doing improperly. Concise pointers/examples would be great. MSDN seems now to only offer assistance with C# and that is an issue with me. They have removed most of the VB references and examples, unless I am just not finding them anymore.
I have a SCHEDULED TIME to be someplace. I arrive at said location on or before the scheduled time.
I DEPART the location 5 hours later. I am basing all elapsed time off TotalMinutes - therefore TotalMinutes = 300 (5 hours)
All time elapsed past the initial 2 hours after the SCHEDULED time I get detention paid (ie first 2 hours are non-chargeable). Therefore, based on the above scenario, I qualify for 3 hours of detention (300-120 = 180 minutes (or 3 hours)).
Detention is paid at $25.00/hour billable at 30 minute increments.
Based on the above known facts, I then should take the ((180/30) * 12.5) to come up with a total of 75.
I have tried taking the DEPART time (timeB) and subtracting this from the SCHEDULED time (timeA). using: timeA.subtract(timeB) - this results in a -300
I cannot multiply a negative number by an hourly rate as the result would always be "0".
I need to understand how to take a negative amount of minutes and convert it to a positive number then be able to multiply it by the hourly rate.
I attempted to use DURATION which is supposed to always give a positive result, but alas I cannot get this to work properly.
-
Re: Detention Code not working
Quote:
Originally Posted by
K3JAE
MSDN seems now to only offer assistance with C# and that is an issue with me. They have removed most of the VB references and examples, unless I am just not finding them anymore.
I completely agree and have the same problem.
I have found a solution to this here and now use it often. I have the link on my bookmark bar, right next to the link for VB Forum.
A word of caution however, you say "only offer assistance with C# ". This isn't so, I've been caught out recently, MSDN also use C++, in amongst their C# examples, usually without drawing attention to it.
Poppa.
-
Re: Detention Code not working
Quote:
Originally Posted by
K3JAE
Based on the above known facts, I then should take the ((180/30) * 12.5) to come up with a total of 75.
I have tried taking the DEPART time (timeB) and subtracting this from the SCHEDULED time (timeA). using: timeA.subtract(timeB) - this results in a -300
Of course it does... Departure time will always be greater than arrival time, even if it's within the same minute... You can't leave before you arrive. Have you considered taking the SCHEDULED time (timeA) from the DEPART time (timeB) ?
You could also use the Math.abs method, which will give you the same result whichever way you do the maths. i.e. the difference between the two figures.
Poppa.
-
Re: Detention Code not working
Quote:
Originally Posted by
Poppa Mintin
Of course it does... Departure time will always be greater than arrival time, even if it's within the same minute... You can't leave before you arrive. Have you considered taking the SCHEDULED time (timeA)
from the DEPART time (timeB) ?
You could also use the
Math.abs method, which will give you the same result whichever way you do the maths. i.e. the difference between the two figures.
Poppa.
Yes, I understand the result would actually be a negative number... I did try the math.Abs method.. But cannot figure out proper syntax for it. Again, as noted above your link does me no good to understand it since all the MSDN shows is C# information.
-
Re: Detention Code not working
Quote:
Originally Posted by
Poppa Mintin
Of course it does... Departure time will always be greater than arrival time, even if it's within the same minute... You can't leave before you arrive. Have you considered taking the SCHEDULED time (timeA)
from the DEPART time (timeB) ?
You could also use the
Math.abs method, which will give you the same result whichever way you do the maths. i.e. the difference between the two figures.
Poppa.
Yes, I understand the result would actually be a negative number... I did try the math.Abs method.. but cannot figure out proper syntax for it. Again, as noted above your link does me no good to understand it since all the MSDN shows is C# information.
-
Re: Detention Code not working
The Microsoft site can show multiple languages, but only one at a time, so you need to pick the one you want (at the top-right of the page the current language is listed, click on it to see a list of others)
In this case all you need is:
Code:
positiveValue = Math.Abs(value)
Also note that in a few places your code can be simplified in a way that makes it easier to read (and slightly quicker to run). For example, this:
Quote:
Code:
If depart01.TotalMinutes >= 180 Then
ElseIf depart01.TotalMinutes >= 120 AndAlso depart01.TotalMinutes < 180 Then
ElseIf depart01.TotalMinutes < 120 Then
End If
...can become:
Code:
If depart01.TotalMinutes >= 180 Then
ElseIf depart01.TotalMinutes >= 120 Then
Else
End If
(because failing the previous If means that the < is already known)
Also this section:
Quote:
Code:
Select Case True
'Lipsey Logistics
Case tbBrokerAgency.Text = "LIPSEY LOGISITCS"
'Total Quality Logistics
Case tbBrokerAgency.Text = "TOTAL QUALITY LOGISTICS"
'Coyote Logistics
Case tbBrokerAgency.Text = "COYOTE"
'CH Robinson Logistics
Case tbBrokerAgency.Text = "CH ROBINSON"
End Select
...can become:
Code:
Select Case tbBrokerAgency.Text
'Lipsey Logistics
Case "LIPSEY LOGISITCS"
'Total Quality Logistics
Case "TOTAL QUALITY LOGISTICS"
'Coyote Logistics
Case "COYOTE"
'CH Robinson Logistics
Case "CH ROBINSON"
End Select
(Select Case True is an unusual thing to do, and should only be used if doing unrelated comparisons)
By the way, this may be a typo: "LIPSEY LOGISITCS"
-
Re: Detention Code not working
OK, I have tried the above suggestion:
Code:
positiveValue = Math.Abs(value)
I get error TIMESPAN cannot be converted to double (or any manner). I guess I am still not understanding the concept here. Sorry for my thick head!!
Also, Thank you for the code cleaning tips... They are being incorporated.
-
Re: Detention Code not working
You should be putting some kind of number in place of value , which can include something like depart01.TotalMinutes , eg:
Code:
minutesDifference = Math.Abs(depart01.TotalMinutes)
-
Re: Detention Code not working
OK, I got this in hand now... one last question....
I should get a negative number if a truck arrives PRIOR to the scheduled arrival time. This needs to be accounted for. If the truck arrives even a few seconds prior to the scheduled time the truck is not late.
What, in your opinion is the best way to handle this based on the code I submitted?
In other words, would redoing the code a 2nd time in a second sub to determine DETENTION only be advised? Or can this still work under the same sub? If so how would one recommend this work around. I only need to be careful of detention time being all positive numbers so I can properly calculate detention.
-
Re: Detention Code not working
Just because you want to use the positive version in one place, that doesn't mean you have to use only the positive version - you can keep the original value separately, and use it in other places (or only store the original version, and just use Abs inside your calculations that need the positive version).
-
Re: Detention Code not working
Quote:
Originally Posted by
si_the_geek
Just because you want to use the positive version in one place, that doesn't mean you have to use only the positive version - you can keep the original value separately, and use it in other places (or only store the original version, and just use Abs inside your calculations that need the positive version).
DOH! Guess that really was a stupid question eh? I knew that!! LOL... Sorry for my "brain fart" as I truly did know and understand that!
-
Re: Detention Code not working
I have, I hope, one last question. Please read and look at syntax carefully...
Intended goal is to determine a few conditions to be true... specifically to determine if total minutes is 10 minutes or less OR if the override box is checked. Either condition being true would move to next condition.I am concerned putting the 2 conditions within a parenthesis is proper.
Is the Following a valid statement:
Code:
Case tbBrokerAgency.Text = "COYOTE" Or tbBrokerAgency.Text = "TOTAL QUALITY LOGISTICS" Or tbBrokerAgency.Text = "LIPSEY LOGISTICS"
If (ts1.TotalMinutes <= 10 Or ckbx01DetOverride.CheckState = CheckState.Checked) AndAlso ts2.TotalMinutes > 120 AndAlso (ts3.TotalMinutes <= 10 Or ckbx90DetOverride.CheckState = CheckState.Checked) AndAlso ts4.TotalMinutes > 120 Then
a = CDec(((depart01 - 120) / 60) * 35) + CDec(((depart90 - 120) / 60) * 35)
tbDetentionOwed.Text = a.ToString("C2")
ElseIf (ts1.TotalMinutes <= 10 Or ckbx01DetOverride.CheckState = CheckState.Checked) AndAlso ts3.TotalMinutes > 120 Then
a = CDec(((depart01 - 120) / 60) * 35)
tbDetentionOwed.Text = a.ToString("C2")
ElseIf (ts3.TotalMinutes <= 10 Or ckbx90DetOverride.CheckState = CheckState.Checked) AndAlso ts4.TotalMinutes > 120 Then
a = CDec(((depart90 - 120) / 60) * 35)
tbDetentionOwed.Text = a.ToString("C2")
Else
a = 0
tbDetentionOwed.Text = a.ToString("C2")
End If
-
Re: Detention Code not working
When mixing And/AndAlso with Or/OrElse, using parenthesis as you have is the only sensible way to do it - because that makes sure they are done in the order you intended, and makes your intentions clear to whoever reads the code later (including yourself in a few months/years).
By the way, this:
Code:
Select Case True
Case tbBrokerAgency.Text = "COYOTE" Or tbBrokerAgency.Text = "TOTAL QUALITY LOGISTICS" Or tbBrokerAgency.Text = "LIPSEY LOGISTICS"
...does the same as this:
Code:
Select Case tbBrokerAgency.Text
Case "COYOTE", "TOTAL QUALITY LOGISTICS", "LIPSEY LOGISTICS"
-
Re: Detention Code not working
Thank you for that.... and to your point with the select case... I had done that then reverted back while trying to workout the condition statement and forgot to push it back out. Correction has been made.
Thanks all of you for the assistance and think I got this working pretty closely now.. still a few minor bugs to work out but indeed the biggest issue is resolved!
-
Re: Detention Code not working
Quote:
Originally Posted by
K3JAE
Yes, I understand the result would actually be a negative number... I did try the math.Abs method.. but cannot figure out proper syntax for it. Again, as noted above your link does me no good to understand it since all the MSDN shows is C# information.
When we click on VB Forum emails, we get taken to the last posted message, this can (and often does) mean that we miss a previous message.
I suspect that this is just such a case... Please check the post immediately prior to the one you've replied to. (post #6)
Poppa.
-
Re: Detention Code not working
I apologize for the late added question... how can I round UP the time to the nearest 30 minute increment using the latest code I have already posted? I need to have a finite 30 minute billing and if a time span falls into the next half hour it needs to bill. The below code is the final version (working) that I use to determine amount of detention.
EXAMPLE:12:05 would bill to 12:30 since it is inside the next 1/2 hour.
Code:
If (ts1.TotalMinutes <= 10 Or ckbx01DetOverride.CheckState = CheckState.Checked) AndAlso ts3.TotalMinutes > 120 AndAlso (ts2.TotalMinutes <= 10 Or ckbx90DetOverride.CheckState = CheckState.Checked) AndAlso ts4.TotalMinutes > 120 Then
a = CDec((CDec((depart01 - 120) / 30) * 17.5) + (CDec((depart90 - 120) / 30) * 17.5))
tbDetentionOwed.Text = a.ToString("C2")
ElseIf (ts1.TotalMinutes <= 10 Or ckbx01DetOverride.CheckState = CheckState.Checked) AndAlso ts3.TotalMinutes > 120 Then
a = CDec((CDec((depart01 - 120) / 30) * 17.5))
tbDetentionOwed.Text = a.ToString("C2")
ElseIf (ts2.TotalMinutes <= 10 Or ckbx90DetOverride.CheckState = CheckState.Checked) AndAlso ts4.TotalMinutes > 120 Then
a = CDec((CDec((depart90 - 120) / 30) * 17.5))
tbDetentionOwed.Text = a.ToString("C2")
Else
a = 0
tbDetentionOwed.Text = a.ToString("C2")
End If
-
Re: Detention Code not working
There are various ways to round numbers, including Floor (always round down) and Ceiling (always round up).
To round to a particular amount other than 1, divide by the number you want to round to, round in the appropriate way (this time Ceiling), and finally multiply by the number you want to round to, eg:
Code:
minutesRoundedUpToMultipleOf30 = Decimal.Ceiling(minutes / 30) * 30
-
Re: Detention Code not working
Excellent.. thank you. Had to make a new Variable to work through this but nonetheless, it is working as it is supposed to now. thanks!
-
Re: Detention Code not working
Good to know it's working for you now.
Did you check Post #6 ?
Poppa.
-
Re: Detention Code not working
Yes Sir I did,and you are correct. Thank you!