Excel Timer with banner that changes in segments - vba

Trying to make a banner that changes through different segments of an allotted time. The different segments are 15, 20, 25 minutes. I have a setup page that the user can select the segment from a combobox. Then displays the workflow page Like so:
This is a sample of what the banner should do for a 15 minute segment (pseudo code):
When it starts (15 remaining)
TimeBanner = "Thinking Time"
After 1 minute (14 remaining)
TimeBanner = "Response Time"
after 10 minutes (3 remaining)
TimeBanner = "Refine and Improve"
after 14 minutes(1 remaining)
TimeBanner = "Submit"
after 15 minutes (0 remaining)
TimeBanner = "Time Up"
The timer works, but the the banner doesn't change
So I thought perhaps I just needed to add DoEvents, but it doesn't change
Here's the code
Option Explicit
Public interval As Date
Sub timer()
interval = Now + TimeValue("00:00:01")
If Sheets("VSS").Range("D1").Value = 0 Then Exit Sub
'Show the time elapsed
Sheets("VSS").Range("D1").Value = Sheets("VSS").Range("D1").Value - TimeValue("00:00:01")
DoEvents
Sheets("VSS").Range("E3").Value = TimeBanner(Sheets("ControlData").Range("A7").Value, Minute(Sheets("VSS").Range("D1").Value))
DoEvents
'Show the Time Banner matching the Elapsed Time
'MsgBox Minute(Sheets("VSS").Range("D1").Value)
Application.OnTime interval, "timer"
DoEvents
End Sub
Sub stop_timer()
'Only allow 'Stop' if the timer has started
Dim iMin As Integer
iMin = Left(Format(Sheets("VSS").Range("D1").Value, "mm:ss"), 2)
'i.e. if the time elapsed DOES NOT equal whatever they chose
'It means that the timer has started
If iMin <> Sheets("ControlData").Range("A7").Value Then
Application.OnTime EarliestTime:=interval, Procedure:="timer", Schedule:=False
End If
End Sub
Sub reset_timer()
Sheets("VSS").Range("D1").Value = "00:" & Sheets("ControlData").Range("A7").Value & ":00"
End Sub
Function TimeBanner(iTimeChosen As Integer, iElapsedTime As Integer) As String
Debug.Print "Time chosen: " & iTimeChosen & ", Elapsed " & dtElapsedTime
Select Case iTimeChosen
Case 25
Select Case iElapsedTime
Case Is <= 25
TimeBanner = "Thinking Time"
Case Is <= 23
TimeBanner = "Response Time"
Case Is <= 5
TimeBanner = "Refine and Improve"
Case Is <= 1
TimeBanner = "Submit"
Case 0
TimeBanner = "Time Up"
End Select
Case 20
Select Case iElapsedTime
Case Is <= 20
TimeBanner = "Thinking Time"
Case Is <= 18
TimeBanner = "Response Time"
Case Is <= 4
TimeBanner = "Refine and Improve"
Case Is <= 1
TimeBanner = "Submit"
Case Is = 0
TimeBanner = "Time Up"
End Select
Case 15
Select Case iElapsedTime
Case Is <= 15
TimeBanner = "Thinking Time"
Case Is <= 14
TimeBanner = "Response Time"
Case Is <= 3
TimeBanner = "Refine and Improve"
Case Is <= 1
TimeBanner = "Submit"
Case Is = 0
TimeBanner = "Time Up"
End Select
End Select
End Sub

Reverse the order of your case conditions. Case Is <= 25, for instance, will always fire for any number 25 and down, which is all of them, so your first condition is always executed.

The first case of you Select Case will always trigger before the subsequent cases. If Case Is < 14 then Case Is <=15 is also true.
Case 15
Select Case iElapsedTime
Case Is <= 15
TimeBanner = "Thinking Time"
Case Is <= 14
TimeBanner = "Response Time"
Case Is <= 3
TimeBanner = "Refine and Improve"
Case Is <= 1
TimeBanner = "Submit"
Case Is = 0
TimeBanner = "Time Up"
End Select
Removing the < signs will make the code work properly.
Function TimeBanner(iTimeChosen As Integer, iElapsedTime As Integer) As String
Debug.Print "Time chosen: " & iTimeChosen & ", Elapsed " & dtElapsedTime
Select Case iTimeChosen
Case 25
Select Case iElapsedTime
Case Is < 25
TimeBanner = "Thinking Time"
Case Is < 23
TimeBanner = "Response Time"
Case Is < 5
TimeBanner = "Refine and Improve"
Case Is < 1
TimeBanner = "Submit"
Case 0
TimeBanner = "Time Up"
End Select
Case 20
Select Case iElapsedTime
Case Is < 20
TimeBanner = "Thinking Time"
Case Is < 18
TimeBanner = "Response Time"
Case Is < 4
TimeBanner = "Refine and Improve"
Case Is < 1
TimeBanner = "Submit"
Case 0
TimeBanner = "Time Up"
End Select
Case 15
Select Case iElapsedTime
Case 15
TimeBanner = "Thinking Time"
Case Is < 14
TimeBanner = "Response Time"
Case Is < 3
TimeBanner = "Refine and Improve"
Case Is < 1
TimeBanner = "Submit"
Case 0
TimeBanner = "Time Up"
End Select
End Select
End Function

Related

Ms Access formula to define Time-Shift based on Time Entered in a Cell

i have one cell (TimeOut) as Time (Short Time Format, 24 Hrs)
i have another cell (ShiftName) Text Filed
Required formula as below
if Me.TimeOut >=6.00 and <= 14.00 Then
Me.shiftName = "Morning Shift"
Else If Me.TimeOut >= 14.01 and <= 22.00 then
Me.ShiftMane = "Afternoon Shift"
Else
Me.ShiftName = "Night Shift"
Time is not numbers, so try:
Select Case Me!TimeOut.Value
Case < #06.00#
Me!ShiftName = "Night Shift"
Case <= #14.00#
Me!ShiftName = "Morning Shift"
Case <= #22.00#
Me!ShiftMane = "Afternoon Shift"
Case Else
Me!ShiftName = "Night Shift"
End Select

Excel VBA function passing in null date causes #VALUE! error

I have a VBA function (DecTime) that I call passing in the value of a cell. The cell is formatted as custom hh:mm
in my cell the formula is "=DecTime(M6)"
If M6 is a time, eg 01:05 then it works fine, if it is null then I get #VALUE!
I am sure it's a simple solution but having spent the last hour trying lots of things from here and google I am baffled!
Here is my function :
Function DecTime(Optional time As Date = #12:00:00 AM#) As Single 'String
Dim Hours As Integer
Dim Minutes As Single
Dim HoursStr As String
Dim arrTime
'On Error Resume Next
'On Error GoTo error_handler
' HoursStr = Format(time, "h:mm")
' DecTime = HoursStr
If time = #12:00:00 AM# Then
' If HoursStr = "12:00" Then
' If IsEmpty(time) Then
' If IsEmpty(time) = True Then
' If IsNull(time) Then
' If arrTime.Count = 0 Then
' If InStr(0, time, ":") = 0 Then
' If IsDate(time) = False Then
DecTime = 88
' DecTime = HoursStr
Else
arrTime = Split(time, ":")
If arrTime(1) <= 0 Then
Minutes = 0
ElseIf arrTime(1) <= 5 Then
Minutes = 0.1
ElseIf arrTime(1) <= 10 Then
Minutes = 0.2
ElseIf arrTime(1) <= 15 Then
Minutes = 0.3
ElseIf arrTime(1) <= 20 Then
Minutes = 0.3
ElseIf arrTime(1) <= 25 Then
Minutes = 0.4
ElseIf arrTime(1) <= 30 Then
Minutes = 0.5
ElseIf arrTime(1) <= 35 Then
Minutes = 0.6
ElseIf arrTime(1) <= 40 Then
Minutes = 0.7
ElseIf arrTime(1) <= 45 Then
Minutes = 0.8
ElseIf arrTime(1) <= 50 Then
Minutes = 0.8
ElseIf arrTime(1) <= 55 Then
Minutes = 0.9
Else
Minutes = 0
End If
Hours = arrTime(0)
DecTime = Hours + Minutes
' DecTime = HoursStr
End If
'error_handler:
' DecTime = 99
'Resume Next
End Function
As you can see from the remarked code I have tried lots of different options to deal with a blank parameter passed in so if someone can tell me what I've done wrong I'd be very greatful!
I am a sql programmer so not much experience with VB
Assuming you want to return 0 if the cell is empty or doesn't contain a date, you could use:
Function DecTime(Optional time = #12:00:00 AM#) As Double
Dim Hours As Integer
Dim Minutes As Single
Dim arrTime
If Not IsDate(time) Then
DecTime = 0
ElseIf time = #12:00:00 AM# Then
DecTime = 0
Else
arrTime = Split(time, ":")
Select Case arrTime(1)
Case Is = 0
Minutes = 0
Case Is <= 5
Minutes = 0.1
Case Is <= 10
Minutes = 0.2
Case Is <= 20
Minutes = 0.3
Case Is <= 25
Minutes = 0.4
Case Is <= 30
Minutes = 0.5
Case Is <= 35
Minutes = 0.6
Case Is <= 40
Minutes = 0.7
Case Is <= 50
Minutes = 0.8
Case Is <= 55
Minutes = 0.9
Case Else
Minutes = 0
End Select
Hours = arrTime(0)
DecTime = Hours + Minutes
End If
End Function

Case statement only runs one condition

hey when I enter an integer into my case statement it produces the right output but with a string it just produces the same result each time, do you guys know any solutions?
Select Case Grades.Text
Case = "A*"
score = score + 100
MessageBox.Show("You entered an A*")
Gcount = Gcount + 1
Case >= 90
score = score + 100
MessageBox.Show("You entered an A*")
Gcount = Gcount + 1
Case = "A"
score = score + 85
MessageBox.Show("You entered an A")
Gcount = Gcount + 1
MessageBox.Show(Gcount)
Case < 90 And Grades.Text >= 80
score = score + 85
MessageBox.Show("You entered an A")
Gcount = Gcount + 1
MessageBox.Show(Gcount)
Case = "B"
score = score + 75
MessageBox.Show("You entered a B")
Gcount = Gcount + 1
MessageBox.Show(score)
Case < 80 And Grades.Text >= 70
score = score + 75
MessageBox.Show("You entered a B")
Gcount = Gcount + 1
Case = "C"
score = score + 65
MessageBox.Show("You entered a C")
Gcount = Gcount + 1
Case < 70 And Grades.Text >= 60
score = score + 65
MessageBox.Show("You entered a C")
Gcount = Gcount + 1
You should set Option Strict On.
So there is a way like this
Select case True
Case intVariable <= 90
' do something...
Case 91 < intVariable AndAlso intVariable <= 100
' do something...
Case 100 < intVariable AndAlso intVariable <= 110
' do something... and so on
End Select
try this:
Select Case Grades.Text
Case Is >= 90
MessageBox.Show("You entered an A*")
Case Is < 90 And Grades.Text >= 80
MessageBox.Show("You entered an A")
Case Is < 80 And Grades.Text >= 70
MessageBox.Show("You entered a B")
Case Is < 70 And Grades.Text >= 60
MessageBox.Show("You entered a C")
End Select

Is there an alternative method to using 15 If statements?

I have 15 items in my ComboBox and when the user selects an item I want to present something different in my TextBox.
At the moment I have:
If cb_dropdown.SelectedIndex = 0 Then
RTB_Sql.Text = "update access
set accessdesc = 'Less than 5' where accessID < '5'"
Else
If cb_dropdown.SelectedIndex = 1 Then
RTB_Sql.Text = "update access
set accessdesc = 'More than 5' where accessID > '5' and < '10' "
Else
If cb_dropdown.SelectedIndex = 2 Then
RTB_Sql.Text = ""
etc....
Is there a nicer and more methodical way to approach this as it looks quite scruffy?
Yes, it is called select.
Select Case cb_dropdown.SelectedIndex
Case 0 To 4
RTB_Sql.Text = "update access
set accessdesc = 'Less than 5' where accessID < '5'"
Case 5
RTB_Sql.Text = [...]
Case Else
RTB_Sql.Text = [...]
End Case
Although in your case I think what you are looking for is < (less than) and > (greater than).
If cb_dropdown.SelectedIndex < 5 Then
RTB_Sql.Text = "update access set accessdesc = 'Less than 5' where accessID < '5'"
ElseIf cb_dropdown.SelectedIndex < 10 Then
RTB_Sql.Text = "update access set accessdesc = 'More than 5' where accessID > '5' and < '10' "
End If
Not really sure what you are trying to do though. Maybe if you explain in more detail someone can provide a better answer. So let me take a wild guess:
Dim n As Integer = cb_dropdown.SelectedIndex * 5
RTB_Sql.Text = "update access set accessdesc = 'More than " + n + "' where accessID > '" + n + "' and < '" + (n+6) + "' "
This will give you the following result based on SelectedIndex:
0 = from 1 to including 5
1 = from 6 to including 10
etc...
If you want to shift it down one (include 0 and not 5 in first batch) then just change > to >= and 6 to 5.
You can also use something like this if you want to check range of values:
Sub Main()
Dim i As Integer = 6
Select Case True
Case 0 <= i AndAlso i < 5
Console.WriteLine("i is between 0 and 4")
Case 6 <= i
Console.WriteLine("i is 6 or greater")
End Select
Console.ReadLine()
End Sub
Be aware that it stops in the first true condition.

Visual Basic - "If" Statements Not Showing Result In Label

I'm working on an assignment where the program needs to calculate and display the total cost for shipping a package, based on weight and whether it is being shipped to Continental U.S., Alaska, or Hawaii. When I click the Calculate button, though, the label that is supposed to display the total is left blank. I've looked through this and tried placing the calculation in different parts/at the end of the "If" statements. Here's what I have thus far, any help would be appreciated:
Dim decWeight As Decimal
Dim decTotalCost As Decimal
Dim decDestination As Decimal
Dim decRate As Decimal
If IsNumeric(txtWeight.Text) Then
decWeight = Convert.ToDecimal(txtWeight.Text)
If decWeight <= 30 > 0 Then
If radContinental.Checked Then
decDestination = 1
ElseIf radHawaii.Checked Then
decDestination = 1.2
ElseIf radAlaska.Checked Then
decDestination = 1.26
End If
If decWeight <= 2 Then
decRate = 3.69
ElseIf decWeight <= 4 > 2 Then
decRate = 4.86
ElseIf decWeight <= 6 > 4 Then
decRate = 5.63
ElseIf decWeight <= 8 > 6 Then
decRate = 5.98
ElseIf decWeight <= 10 > 8 Then
decRate = 6.28
ElseIf decWeight <= 30 > 10 Then
decRate = 15.72
End If
decTotalCost = decRate * decDestination
lblTotalCost.Text = decTotalCost.ToString("C")
ElseIf decWeight <= 0 Then
MsgBox("Please Enter a Positive Weight.", , "Input Error")
ElseIf decWeight > 30 Then
MsgBox("You Have Entered " & decWeight.ToString() & ". Please Enter a Weight Under 30 Pounds", , "Input Error")
End If
ElseIf txtWeight.Text = "" Then
MsgBox("Please Enter the Weight", , "Input Error")
Else : MsgBox("Please Enter a Number", , "Input Error")
End If
You should try this if statement: If decWeight <= 30 and decWeight > 0 Then
This will check if the decWeight is less than or equal to 30 and make sure that it is 'non-zero' Hope this helps :-)