Ask Me Help Desk

Ask Me Help Desk (https://www.askmehelpdesk.com/forum.php)
-   Visual Basic (https://www.askmehelpdesk.com/forumdisplay.php?f=469)
-   -   Add a time from a TextBox into a ListBox (https://www.askmehelpdesk.com/showthread.php?t=350342)

  • May 6, 2009, 02:58 AM
    dan28
    1 Attachment(s)
    Add a time from a TextBox into a ListBox
    I need to add a time from a textbox into a list box with a message after that time.
    I've tried many different codes all with poor results. Either I can't change the time or when I changed the time it adds every move to the listbox e.g if the time is 10:00 and I want to change it to 2:00 when I click backspace it adds 10:0, 10:, 10, 1, etc to the list box.
    I have to do this without using a button.
    Please help!

    Attached is an image of what should happen.

    If you know how to do the times for the checkbox's that would help also. (numbers in brackets represent time in minutes)

    Thanks
  • May 6, 2009, 04:50 AM
    Perito

    Can you post a code fragment that shows how you're trying to use it now? I think I've done this before and my recollection is that it wasn't all that hard.
  • May 6, 2009, 04:58 AM
    dan28
    This is the latest code I've tried

    Private Sub tbxStart_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbxStart.TextChanged

    Dim dtmTurnOvenOn As Date = #12:00:00 AM#
    Dim strStart As String = dtmTurnOvenOn.ToString("t")

    strStart = tbxStart.Text
    tbxStart.Text = Format(#12:00:00 PM#)

    If rdbOven1.Checked = True Then
    lbxOven1.Items.Add(strStart & (" Turn On, Heat (15) "))
    End If

    End Sub

    Ive also tried formating the tbxStart.Text as Format("hh:mm) but that left hh:mm in the text box. This current code won't let me change the time at all. And when I try it just keeps producing cases of 12:00:00 AM Turn oven on.
    Ive tried it without the Dim dtmTurnOvenOn and just used Strings but that also didn't work.
  • May 6, 2009, 05:46 AM
    Perito

    tbxStart is the "shift start time", from your label. Let's say you want to change the shift start time from 4:00 to 12:00 - the start of the next shift. Is this the proper scenario?

    Your TextChanged subroutine will be called five times -- when you hit 1, 2, :, 0, and 0. This will add five lines to a listbox. You obviously need a way to check that and eliminate multiple entries. You might be able to use a different event (maybe the Leave or Validating event). You might also check the format of the time. If it's not complete, you exit out of the event before trying to add anything to the listbox. Finally, use a semaphore to make sure you don't "overrun" yourself:

    Private Semaphore as Boolean = false ' class-level variable.

    Private Sub...
    if Semaphore then exit sub
    try
    Semaphore = true
    finally
    Semaphore = false
    end try

    I don't think it's the time formatting that's causing you problems. I think it's something having to do with adding multiple lines to the listbox.

    You also mentioned something about changing the time. Do you wish to update all of the lines in the listbox? That's possible, but you have to re-parse each line, remove the current time from the line, update the time and rebuild the line and re-add it to the listbox.

    Post back with your thoughts. I'll look in in an hour or so.
  • May 6, 2009, 06:04 AM
    dan28
    Yes tbxStart is the "Shift Start time."
    When the time is changed the time next to "Turn oven on" in the selected listbox should be updated, therefore updating the times of the other things in the listbox.
    ATM when I change the Start time instead of updated the "Turn oven on" Time it adds new ones under the data. Every time I change anything in the Start time textbox it adds a new "Turn oven on"
  • May 6, 2009, 06:09 AM
    dan28
    Sorry, "Turn on, Heat" not "Turn oven on"
  • May 6, 2009, 06:19 AM
    Perito

    Quote:

    tbxStart is the "Shift Start time."

    When the time is changed the time next to "Turn oven on" in the selected listbox should be updated, therefore updating the times of the other things in the listbox.
    ATM when i change the Start time instead of updated the "Turn oven on" Time it adds new ones under the data. Every time i change anything in the Start time textbox it adds a new "Turn oven on"
    OK. Let me try this:

    Private Sub tbxStart_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbxStart.TextChanged

    ' don't process this line unless there are at least 4 characters in the text box.
    If tbxStart.text.length < 4 then exit sub

    Dim dtmTurnOvenOn As Date = #12:00:00 AM#
    Dim strStart As String = dtmTurnOvenOn.ToString("t")

    strStart = tbxStart.Text
    tbxStart.Text = Format(#12:00:00 PM#)

    ' This code determines the oven.
    If rdbOven1.Checked = True Then
    ' This adds an item to the checkbox. It doesn't modify anything already in there.
    ' lbxOven1.Items.Add(strStart & (" Turn On, Heat (15) "))

    Dim tStr as string
    Dim TimeStr as string
    Dim OpStr as string
    for i as integer = 0 to lbxOven1.Items.Count-1
    tStr = lbxOven1.Items(i)
    ... ' parse the string into the time, TimeStr, and the operation, OpStr.
    ... Update the time string
    TimeStr = something.
    tStr = TimeStr & OpStr ' add them together again
    lbxOven1.Items(i)=tStr ' put it back into the listbox
    Next
    lbxOven1.Update ' make the listbox repaint itself.
    End If

    End Sub

    If you're unsure how to parse the string, I can show you that.
  • May 6, 2009, 06:36 AM
    dan28
    A few error messages from that code. From this part:

    For I As Integer = 0 To lbxOven1.Items.Count - 1
    tStr = lbxOven1.Items(I)
    ... ' parse the string into the time, TimeStr, and the operation, OpStr.
    ... Update the time string
    TimeStr = something.
    tStr = TimeStr & OpStr ' add them together again
    lbxOven1.Items(I) = tStr ' put it back into the listbox
    Next
    lbxOven1.Update() ' make the listbox repaint itself.
    End If

    option strict on disallows implicit conversion from 'object' to 'string'.

    and the rest were just from things like the... and = something.

    I have no idea how to parse strings so if you could show me that would be great.

    Thanks
  • May 6, 2009, 06:50 AM
    Perito

    To fix the option strict problem, change to

    Dim tStr As String = lbxOven.Items(I).ToString

    "Parse" means to break a sentence into its parts. In programming, it means to break down a string into pieces.

    http://en.wikipedia.org/wiki/Parsing

    Now, for parsing. If your times are always entered in the format "hh:mm text" with a two-digit hour, a colon, a two-digit minute, and a space, then we can parse it like this:

    for I as integer = 0 to lbxOven1.Items.Count-1
    Dim tStr As String = lbxOven.Items(I).ToString
    TimeStr = tStr.SubString(0, 5) ' start at character 0, take 5 characters. Ignore the space.
    Dim L as integer = tStr.length
    OpStr = tStr.SubString(6, L-6) ' get the operation

    Now update the time. The time in the listbox is in TimeStr. Replace TimeStr with whatever time you wish.
    TimeStr =...
    lbxOven1.Items(I) = TimeStr & " " & OpStr
    Next
    lbxOvem1.Update

    Another option for parsing would be to insert a character, possibly a "-" between the time and the operation. The string could be parsed like this

    Dim P As Integer = tStr.IndexOf("-"c) ' P is the position of the "-".
    TimeStr = tStr.SubString(0, P-1).Trim ' Take everything before the "-", and delete leading and trailing spaces.
    OpStr = tStr.SubString(P+1, tStr.Length - P - 1)
    ...
    lbxOtem1.Items(I) = TimeStr & "-" & OpStr

    Of course, if there is no "-", this code will fail so you need to make sure that there is always that character in the string.
  • May 7, 2009, 09:03 PM
    dan28
    Thanks for your help Perito.
    I've managed to get the start time working.
    My next problem is getting the bakery items to insert after the "Turn on, Heat" text in the list box and before the other 3 texts. ATM they are just going after everything.
    I also need to work out how to get them to add the time that's in the brackets to the time shown next to them as shown in the image in Oven 2.
    The start time text box is a string so will also need a way to avoid getting bad times such as 9:73 instead of 10:13.
    All help is much appreciated.
  • May 8, 2009, 04:58 AM
    Perito
    Quote:

    My next problem is getting the bakery items to insert after the "Turn on, Heat" text in the list box and before the other 3 texts. ATM they are just going after everything.
    I hope I understand this correctly. If you wish to insert them before other texts, you can't use lbxOven1.Items.Add() because that will simply put the new string at the end. You should make use of the lbxOven1.Items array to figure out where to put the next item. (but see my last idea, below).

    Quote:

    I also need to work out how to get them to add the time that's in the brackets to the time shown next to them as shown in the image in Oven 2.
    The start time text box is a string so will also need a way to avoid getting bad times such as 9:73 instead of 10:13.
    One idea that would solve all of these problems is to keep the operations and times in either two arrays or an array of struct.

    Private Structure OvenStruc
    Public OvenOp As String
    Public Optime As DateTime
    End Structure
    Private OvenOps() As OvenStruc

    ' This assumes that Op.Optime is properly set before calling this routine
    ' it adds a record to the OvenOps array.
    Private Sub AddOperation(ByVal Op As OvenStruc)
    Dim index As Integer
    Dim found As Boolean = False
    For i As Integer = 0 To OvenOps.GetUpperBound(0)
    If Op.Optime > OvenOps(i).Optime Then
    index = i
    found = True
    Exit For
    End If
    Next
    ReDim Preserve OvenOps(OvenOps.GetUpperBound(0) + 1) ' enlarge the OvenOps array
    If found Then ' add at index
    For i As Integer = index To OvenOps.GetUpperBound(0) - 1
    OvenOps(i + 1) = OvenOps(i)
    Next
    OvenOps(index) = Op ' insert the operation
    Else ' add at the end
    OvenOps(OvenOps.GetUpperBound(0)) = Op
    End If
    End Sub

    ' This deletes an operation from the OvenOps array.
    Private Sub DeleteOperation(ByVal index As Integer)
    If OvenOps.Length >= 1 Then
    Dim Counter As Integer = OvenOps.GetUpperBound(0)
    For i As Integer = index To Counter - 1
    OvenOps(i) = OvenOps(i + 1)
    Next
    ReDim Preserve OvenOps(Counter - 1)
    End If
    End Sub

    Private Sub Fill_Listbox()
    Dim TimeStr As String
    lbxOven1.Items.Clear() ' completely empty the listbox.
    For i As Integer = 0 To OvenOps.GetUpperBound(0)
    TimeStr = Format(OvenOps(i).Optime, "hh:mm tt ")
    lbxOven1.Items.Add(TimeStr & OvenOps(i).OvenOp)
    Next
    lbxOven1.Refresh()
    End Sub

    When you wish to add an item to the array, you enter the time and the operation into the OvenOps array; then call AddOperation. If you wish to delete something, call DeleteOperation. Of course you'll still have to adjust some of the times somewhere, but it should be simpler since the times will be in the DateTime format. That format is easier to handle -- to add or subtract times from.

    Instead of parsing strings from the listbox, simply fill the listbox each time there's a change. Fill_Listbox shows how this is done.
  • May 13, 2009, 03:47 AM
    dan28
    Thanks perito. With using your code and some others my partner and I have gathered we came up with this:



    Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click

    'adds ticked items to list boxes

    Dim chkBakeItem As CheckBox
    Dim intIndex As Integer = lbxOven1.Items.Count
    Dim intIndex2 As Integer = lbxOven2.Items.Count
    Dim intIndex3 As Integer = lbxoven3.Items.Count


    If tbxStart.Text = "" Or tbxFinish.Text = "" Then
    MessageBox.Show("Please enter Start and Finish times of shift before adding items")

    Else : For Each chkBakeItem In gbxBakeryItems.Controls


    If chkBakeItem.Checked = True And rdbOven1.Checked = True Then
    lbxOven1.Items.Insert(intIndex - 3, (("00:00 ") + (chkBakeItem.Text)))

    ElseIf chkBakeItem.Checked = True And rdbOven2.Checked = True Then
    lbxOven2.Items.Insert(intIndex2 - 3, (("00:00 ") + (chkBakeItem.Text)))

    ElseIf chkBakeItem.Checked = True And rdbOven3.Checked = True Then
    lbxoven3.Items.Insert(intIndex3 - 3, (("00:00 ") + (chkBakeItem.Text)))


    End If
    Next

    Dim intPosition, intBakeTime As Integer
    Dim strCurrentString As String
    Dim strBakeryItem As String
    For i = 0 To lbxOven1.Items.Count

    strCurrentString = lbxOven1.Items(i).ToString
    strBakeryItem = strCurrentString.Substring(6, strCurrentString.Length - 6)

    intPosition = strCurrentString.IndexOf("(")
    intBakeTime = CInt(strCurrentString.Substring(intPosition + 1, 2))
    'MessageBox.Show(intPosition & " " & intBakeTime)

    If i = 0 Then

    Else
    'finds the space after the time in the string
    Dim intspace As Integer = strCurrentString.IndexOf(" ")
    'takes the string of the whole time
    Dim strTime As String = strCurrentString.Substring(0, intspace)
    'takes the string of the minutes
    Dim strMinutes As String = strCurrentString.Substring(3, 2)
    'finds position of ":"
    Dim intColons As Integer = strCurrentString.IndexOf(":")
    'takes string of the hrs
    Dim strHours As String = strCurrentString.Substring(0, intColons - 1)
    'take the previous time and add it to the beginning of the current item
    Dim strPrevious As String = strMinutes(i - 1) ' This is where the error message comes up
    'makes time of current item = previous time
    Dim strNew As String = strPrevious
    'edits string to add baking time
    strMinutes = CStr(intBakeTime)

    If CDbl(strMinutes) > 59 Then
    strHours = CStr(CDbl(strHours) + 1)
    strMinutes = CStr(60 - intBakeTime)

    End If

    The error message we get is "Index was outside the bounds of the array"

    Any ideas on where we went wrong?

  • All times are GMT -7. The time now is 09:47 AM.