none
Problem with a list task RRS feed

  • Question

  • Hi!

    I have some data generated from a attendance system

    I want to do a program to be able to detect when the next line has same text C/OUT or C/IN and to get only first line time and subtract the next line time witch has the different text 

    so what I want to do exactly is

    10:08:36 - 08:24:24 = ...

    10:48:35 - 10:32:34 = ...

    So when reading the list if the next line has same text (C/OUT or C/IN) skip the second line


    • Edited by ai1231 Wednesday, June 24, 2020 12:28 PM
    Wednesday, June 24, 2020 12:26 PM

Answers

  • Hi

    Here is yet another version.  This one uses a variable 'Required' which determines whether to count the Time In or Time Out (for example, discards first items in List which do not match Required.

    I have tried to accomodate many different possible requirements, such as text case of C/OUT  -  c/out  -  C/Out   etc

    No doubt this example is incomplete, but may be a step in the right direction.

    *

    Tested using this text file

    XX YY 2020-06-23 08:00:00 C/Out   
    XX YY 2020-06-23 08:01:00 C/Out 
    XX YY 2020-06-23 08:01:00 C/OUT
    XX YY 2020-06-23 08:01:00 C/Out 
    XX YY 2020-06-23 10:00:00 C/In
    XX YY 2020-06-23 10:02:00 C/In        
    XX YY 2020-06-23 10:30:00 C/Out 
    XX YY 2020-06-23 11:00:00 C/IN
    XX YY 2020-06-23 11:00:00 C/In        
    XX YY 2020-06-23 11:00:00 C/In 
    XX YY 2020-06-23 11:02:00 C/IN 
    XX YY 2020-06-23 12:00:00 C/OUT
    XX YY 2020-06-23 14:30:33 C/In  

    ' Form1 with
    ' 3 ListBoxes (1-3)
    ' 3 Labels for header text
    Option Strict On
    Option Explicit On
    Public Class Form1
      ' Cumulative Time In  or  Time Out
      Dim Required As String = "Time Out"
    
      Dim Path As String = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "TestFile.txt")
      Dim OrigLst As New List(Of String)
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        OrigLst.AddRange(IO.File.ReadAllLines(Path))
    
        ListBox1.Items.AddRange(OrigLst.ToArray)
    
        ' need to go through this to
        ' change any format of case to
        ' same (lower case) as original
        ' style was changed by OP
        For i As Integer = 0 To OrigLst.Count - 1
          OrigLst(i) = Trim((OrigLst(i).Replace("XX YY ", Nothing)).ToLower)
        Next
    
        Dim inx As New List(Of Integer)
        For i As Integer = 0 To OrigLst.Count - 1
          If Required = "Time In" Then
            If OrigLst(i).EndsWith("c/out") Then
              inx.Add(i)
            Else
              Exit For
            End If
          Else
            If OrigLst(i).EndsWith("c/in") Then
              inx.Add(i)
            Else
              Exit For
            End If
          End If
        Next
        inx.Reverse()
        For Each i As Integer In inx
          OrigLst.RemoveAt(i)
        Next
    
        ' keep all lower case as case is
        ' undecided by OP
        OrigLst = StripDups("c/in", OrigLst)
        OrigLst = StripDups("c/out", OrigLst)
    
        Dim dts As New List(Of DateTime)
        Dim dt As DateTime = Nothing
        For i As Integer = 0 To OrigLst.Count - 1
          ' keep all lower case as case is
          ' undecided by OP
          OrigLst(i) = OrigLst(i).Replace(" c/out", Nothing).Replace(" c/in", Nothing)
          If DateTime.TryParse(OrigLst(i), dt) Then
            dts.Add(dt)
          End If
        Next
    
        ListBox2.Items.AddRange(OrigLst.ToArray)
    
        For i As Integer = 0 To OrigLst.Count - 2 Step 2
          Dim d1 As TimeSpan = dts(i + 1) - dts(i)
          ListBox3.Items.Add(dts(i + 1).ToString("HH:mm:s") & " - " & dts(i).ToString("HH:mm:s") & " = " & d1.ToString)
        Next
    
      End Sub
      Function StripDups(s As String, lst As List(Of String)) As List(Of String)
        Dim inx As New List(Of Integer)
        For i As Integer = 0 To lst.Count - 2
          If lst(i).EndsWith(s) AndAlso lst(i + 1).EndsWith(s) Then
            inx.Add(i + 1)
          End If
        Next
        inx.Reverse()
        For Each i As Integer In inx
          lst.RemoveAt(i)
        Next
        Return lst
      End Function
    End Class


    Regards Les, Livingston, Scotland


    • Edited by leshay Friday, June 26, 2020 2:17 PM
    • Marked as answer by ai1231 Tuesday, July 7, 2020 12:46 PM
    Friday, June 26, 2020 2:14 PM
  • Ok I achieved what I wanted

    Thank you leshay for your time

    • Marked as answer by ai1231 Wednesday, July 8, 2020 3:07 PM
    Wednesday, July 8, 2020 12:43 PM

All replies

  • Why this doesnt remove what I want? 

      For x As Integer = 1 To ListBox1.Items.Count - 1
                If ListBox1.Items(x).ToString.Contains(ListBox1.Items(x - 1).ToString) Then
    
                Else
                    ListBox2.Items.Add(ListBox1.Items(x))
                End If
    
    
    
            Next

    Wednesday, June 24, 2020 1:10 PM
  • Why this doesnt remove what I want? 

      For x As Integer = 1 To ListBox1.Items.Count - 1
                If ListBox1.Items(x).ToString.Contains(ListBox1.Items(x - 1).ToString) Then
    
                Else
                    ListBox2.Items.Add(ListBox1.Items(x))
                End If
    
    
    
            Next

    Well because there is only a Add, no Remove code.

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Wednesday, June 24, 2020 1:26 PM
    Moderator
  • Hi

    Here is one attempt.  This assumes that there will always be pairs of results from which a timespan can be found. (if not then you need to take care of exceptions)

    This is a stand alone example and has a file called TestFile.txt on my DeskTop which contains the data as per your post.

    ' Form1 with
    ' 3 ListBoxes (1-3)
    ' 3 Labels for header text
    Option Strict On
    Option Explicit On
    Public Class Form1
      Dim Path As String = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "TestFile.txt")
      Dim OrigLst As New List(Of String)
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        OrigLst.AddRange(IO.File.ReadAllLines(Path))
    
        For i As Integer = 0 To OrigLst.Count - 1
          OrigLst(i) = OrigLst(i).Replace("XX YY ", Nothing)
        Next
    
        ListBox1.Items.AddRange(OrigLst.ToArray)
    
        OrigLst = StripDups("C/OUT", OrigLst)
        OrigLst = StripDups("C/IN", OrigLst)
    
        Dim dts As New List(Of DateTime)
        Dim dt As DateTime = Nothing
        For i As Integer = 0 To OrigLst.Count - 1
          OrigLst(i) = OrigLst(i).Replace(" C/OUT", Nothing).Replace(" C/IN", Nothing)
          If DateTime.TryParse(OrigLst(i), dt) Then
            dts.Add(dt)
          End If
        Next
    
        ListBox2.Items.AddRange(OrigLst.ToArray)
    
        For i As Integer = 0 To OrigLst.Count - 1 Step 2
          Dim d1 As TimeSpan = dts(i + 1) - dts(i)
          ListBox3.Items.Add(dts(i + 1).ToString("HH:mm:s") & " - " & dts(i).ToString("HH:mm:s") & " = " & d1.ToString)
        Next
    
      End Sub
      Function StripDups(s As String, lst As List(Of String)) As List(Of String)
        For i As Integer = lst.Count - 1 To 0 Step -1
          If lst(i).EndsWith(s) AndAlso lst(i - 1).EndsWith(s) Then
            lst.RemoveAt(i)
            i -= 1
          End If
        Next
        Return lst
      End Function
    End Class


    Regards Les, Livingston, Scotland

    • Marked as answer by ai1231 Wednesday, June 24, 2020 2:40 PM
    • Unmarked as answer by ai1231 Wednesday, June 24, 2020 2:54 PM
    Wednesday, June 24, 2020 1:45 PM
  • I dont want to "remove" but to "skip" the line that has same value so when I copy them to listbox2 to get only the value I want

    I tried but failed

    Wednesday, June 24, 2020 1:54 PM
  • I dont want to "remove" but to "skip" the line that has same value so when I copy them to listbox2 to get only the value I want

    I tried but failed

    Hi

    Be very very careful! If you post your code, you may be in danger of getting a solution.


    Regards Les, Livingston, Scotland

    Wednesday, June 24, 2020 1:58 PM
  • For x As Integer = 0 To ListBox1.Items.Count - 1
                If x = 0 Then
                    ListBox2.Items.Add(ListBox1.Items(x))
                    x = x + 1
                Else
    
                    If ListBox1.Items(x).ToString.Split("/"c)(0) = (ListBox1.Items(x - 1).ToString.Split("/"c)(0)) Then
    
                    Else
    
                        ListBox2.Items.Add(ListBox1.Items(x))
    
    
                    End If
    
    
    
                   
                End If
    
    
    
    
            Next

    Wednesday, June 24, 2020 2:00 PM
  • Hi

    Sorry but that code seems to do very little, certainly does not do anything as I understood your question to need.

    Did you try the code I posted?


    Regards Les, Livingston, Scotland

    Wednesday, June 24, 2020 2:28 PM
  • OK I'm progressing

    Now I can remove one of the line witch contains same text with next value

     For x As Integer = 1 To ListBox1.Items.Count - 1
    
                If ListBox1.Items(x).ToString.Split("/"c)(1) = (ListBox1.Items(x - 1).ToString.Split("/"c)(1)) Then
    
                Else
                    ListBox2.Items.Add(ListBox1.Items(x))
                End If
            Next 


    Now I want to calculate subtract time every two lines so the next value with previous value

    so second value - first value

    fourth value - third value

    ect




    • Edited by ai1231 Wednesday, June 24, 2020 2:36 PM
    Wednesday, June 24, 2020 2:32 PM
  • Hi

    Here is one attempt.  This assumes that there will always be pairs of results from which a timespan can be found. (if not then you need to take care of exceptions)

    This is a stand alone example and has a file called TestFile.txt on my DeskTop which contains the data as per your post.

    ' Form1 with
    ' 3 ListBoxes (1-3)
    ' 3 Labels for header text
    Option Strict On
    Option Explicit On
    Public Class Form1
      Dim Path As String = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "TestFile.txt")
      Dim OrigLst As New List(Of String)
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        OrigLst.AddRange(IO.File.ReadAllLines(Path))
    
        For i As Integer = 0 To OrigLst.Count - 1
          OrigLst(i) = OrigLst(i).Replace("XX YY ", Nothing)
        Next
    
        ListBox1.Items.AddRange(OrigLst.ToArray)
    
        OrigLst = StripDups("C/OUT", OrigLst)
        OrigLst = StripDups("C/IN", OrigLst)
    
        Dim dts As New List(Of DateTime)
        Dim dt As DateTime = Nothing
        For i As Integer = 0 To OrigLst.Count - 1
          OrigLst(i) = OrigLst(i).Replace(" C/OUT", Nothing).Replace(" C/IN", Nothing)
          If DateTime.TryParse(OrigLst(i), dt) Then
            dts.Add(dt)
          End If
        Next
    
        ListBox2.Items.AddRange(OrigLst.ToArray)
    
        For i As Integer = 0 To OrigLst.Count - 1 Step 2
          Dim d1 As TimeSpan = dts(i + 1) - dts(i)
          ListBox3.Items.Add(dts(i + 1).ToString("HH:mm:s") & " - " & dts(i).ToString("HH:mm:s") & " = " & d1.ToString)
        Next
    
      End Sub
      Function StripDups(s As String, lst As List(Of String)) As List(Of String)
        For i As Integer = lst.Count - 1 To 0 Step -1
          If lst(i).EndsWith(s) AndAlso lst(i - 1).EndsWith(s) Then
            lst.RemoveAt(i)
            i -= 1
          End If
        Next
        Return lst
      End Function
    End Class


    Regards Les, Livingston, Scotland

    It doesnt do what you have shown in photo when I test with these details

    XX YY 2020-06-23 08:00:00 C/Out   
    XX YY 2020-06-23 08:01:00 C/Out  
    XX YY 2020-06-23 10:00:00 C/In
    XX YY 2020-06-23 10:02:00 C/In        
    XX YY 2020-06-23 10:30:00 C/Out        
    XX YY 2020-06-23 11:00:00 C/In 
    XX YY 2020-06-23 11:02:00 C/In 
    XX YY 2020-06-23 12:00:00 C/Out

    Wednesday, June 24, 2020 2:55 PM
  • Hi

    Here is yet another version.  This one uses a variable 'Required' which determines whether to count the Time In or Time Out (for example, discards first items in List which do not match Required.

    I have tried to accomodate many different possible requirements, such as text case of C/OUT  -  c/out  -  C/Out   etc

    No doubt this example is incomplete, but may be a step in the right direction.

    *

    Tested using this text file

    XX YY 2020-06-23 08:00:00 C/Out   
    XX YY 2020-06-23 08:01:00 C/Out 
    XX YY 2020-06-23 08:01:00 C/OUT
    XX YY 2020-06-23 08:01:00 C/Out 
    XX YY 2020-06-23 10:00:00 C/In
    XX YY 2020-06-23 10:02:00 C/In        
    XX YY 2020-06-23 10:30:00 C/Out 
    XX YY 2020-06-23 11:00:00 C/IN
    XX YY 2020-06-23 11:00:00 C/In        
    XX YY 2020-06-23 11:00:00 C/In 
    XX YY 2020-06-23 11:02:00 C/IN 
    XX YY 2020-06-23 12:00:00 C/OUT
    XX YY 2020-06-23 14:30:33 C/In  

    ' Form1 with
    ' 3 ListBoxes (1-3)
    ' 3 Labels for header text
    Option Strict On
    Option Explicit On
    Public Class Form1
      ' Cumulative Time In  or  Time Out
      Dim Required As String = "Time Out"
    
      Dim Path As String = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "TestFile.txt")
      Dim OrigLst As New List(Of String)
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        OrigLst.AddRange(IO.File.ReadAllLines(Path))
    
        ListBox1.Items.AddRange(OrigLst.ToArray)
    
        ' need to go through this to
        ' change any format of case to
        ' same (lower case) as original
        ' style was changed by OP
        For i As Integer = 0 To OrigLst.Count - 1
          OrigLst(i) = Trim((OrigLst(i).Replace("XX YY ", Nothing)).ToLower)
        Next
    
        Dim inx As New List(Of Integer)
        For i As Integer = 0 To OrigLst.Count - 1
          If Required = "Time In" Then
            If OrigLst(i).EndsWith("c/out") Then
              inx.Add(i)
            Else
              Exit For
            End If
          Else
            If OrigLst(i).EndsWith("c/in") Then
              inx.Add(i)
            Else
              Exit For
            End If
          End If
        Next
        inx.Reverse()
        For Each i As Integer In inx
          OrigLst.RemoveAt(i)
        Next
    
        ' keep all lower case as case is
        ' undecided by OP
        OrigLst = StripDups("c/in", OrigLst)
        OrigLst = StripDups("c/out", OrigLst)
    
        Dim dts As New List(Of DateTime)
        Dim dt As DateTime = Nothing
        For i As Integer = 0 To OrigLst.Count - 1
          ' keep all lower case as case is
          ' undecided by OP
          OrigLst(i) = OrigLst(i).Replace(" c/out", Nothing).Replace(" c/in", Nothing)
          If DateTime.TryParse(OrigLst(i), dt) Then
            dts.Add(dt)
          End If
        Next
    
        ListBox2.Items.AddRange(OrigLst.ToArray)
    
        For i As Integer = 0 To OrigLst.Count - 2 Step 2
          Dim d1 As TimeSpan = dts(i + 1) - dts(i)
          ListBox3.Items.Add(dts(i + 1).ToString("HH:mm:s") & " - " & dts(i).ToString("HH:mm:s") & " = " & d1.ToString)
        Next
    
      End Sub
      Function StripDups(s As String, lst As List(Of String)) As List(Of String)
        Dim inx As New List(Of Integer)
        For i As Integer = 0 To lst.Count - 2
          If lst(i).EndsWith(s) AndAlso lst(i + 1).EndsWith(s) Then
            inx.Add(i + 1)
          End If
        Next
        inx.Reverse()
        For Each i As Integer In inx
          lst.RemoveAt(i)
        Next
        Return lst
      End Function
    End Class


    Regards Les, Livingston, Scotland


    • Edited by leshay Friday, June 26, 2020 2:17 PM
    • Marked as answer by ai1231 Tuesday, July 7, 2020 12:46 PM
    Friday, June 26, 2020 2:14 PM
  • Hi ai1231,

    How is the question going? If your question has been answered then please click the "Mark as Answer" Link at the bottom of the correct post(s), so that it will help other members to find the solution quickly if they face a similar issue.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, July 2, 2020 2:33 AM
    Moderator
  • With this data I get an error "'Index was out of range. Must be non-negative and less than the size of the collection.Parameter name: index'"

    on the line

      Dim d1 As TimeSpan = dts(i + 1) - dts(i)

    I tested and that error happens when I change the XX YY to something else like Gabriel in this example

    Gabriel YY 2020-07-07 08:44:37 C/In
    Gabriel YY 2020-07-07 08:45:06 C/In
    Gabriel YY 2020-07-07 08:45:27 C/Out
    Gabriel YY 2020-07-07 08:48:30 C/In
    Gabriel YY 2020-07-07 08:52:05 C/In
    Gabriel YY 2020-07-07 08:52:12 C/In
    Gabriel YY 2020-07-07 08:53:15 C/Out
    Gabriel YY 2020-07-07 08:53:22 C/Out
    Gabriel YY 2020-07-07 08:53:33 C/In
    Gabriel YY 2020-07-07 08:53:44 C/Out
    Gabriel YY 2020-07-07 08:54:05 C/In
    Gabriel YY 2020-07-07 08:54:13 C/Out
    Gabriel YY 2020-07-07 08:55:10 C/In
    Gabriel YY 2020-07-07 08:55:20 C/Out
    Gabriel YY 2020-07-07 10:22:15 C/In
    Gabriel YY 2020-07-07 10:22:27 C/In
    Gabriel YY 2020-07-07 10:22:59 C/In
    Gabriel YY 2020-07-07 10:23:10 C/In
    Gabriel YY 2020-07-07 10:26:34 C/In
    Gabriel YY 2020-07-07 10:27:27 C/In
    Gabriel YY 2020-07-07 10:49:21 C/In
    Gabriel YY 2020-07-07 10:49:37 C/Out
    Gabriel YY 2020-07-07 10:49:56 C/In
    Gabriel YY 2020-07-07 10:54:52 C/Out
    Gabriel YY 2020-07-07 11:08:24 C/In
    Gabriel YY 2020-07-07 11:10:06 C/Out

    Tuesday, July 7, 2020 1:10 PM
  • Hi

    You need to debug the code - this is part of the learning process. You can not expect to get completely bug free examples which have been produced on demand to serve as EXAMPLES ONLY.

    The exception you mention: you need to check but I would guess that i + 1 is greater than the number of elements in dts.


    Regards Les, Livingston, Scotland


    • Edited by leshay Tuesday, July 7, 2020 2:12 PM
    Tuesday, July 7, 2020 2:12 PM
  • Hi

    You need to debug the code - this is part of the learning process. You can not expect to get completely bug free examples which have been produced on demand to serve as EXAMPLES ONLY.

    The exception you mention: you need to check but I would guess that i + 1 is greater than the number of elements in dts.


    Regards Les, Livingston, Scotland


    No the problem is not there but on the OrigLst array where he first is replacing the XX YY with nothing and when he get the time from the list its only the time but when I change the name XX YY to something ZZZ YY orglist contains olso the name in it

    Tuesday, July 7, 2020 2:25 PM
  • Hi

    You are now asking for help with code that you have changed yet you don't even show the code (AFAIK)


    Regards Les, Livingston, Scotland

    Tuesday, July 7, 2020 2:34 PM
  • here is the code working now

    What i want to achieve now is to be able to make this calculation for each name and their coresponding data on the list

    for example with this data(to get for each name nd each date the calculations)

    John Dick 2020-07-06 08:34:33 C/In        
    John Dick 2020-07-06 14:07:59 C/Out         
    John Dick 2020-07-06 14:26:26 C/In        
    John Dick 2020-07-06 17:41:36 C/Out 

    John Dick 2020-07-07 08:34:33 C/In        
    John Dick 2020-07-07 14:07:59 C/Out         
    John Dick 2020-07-07 14:26:26 C/In        
    John Dick 2020-07-07 17:41:36 C/Out 

    Ben Locki 2020-07-06 08:59:10 C/In        
    Ben Locki 2020-07-06 09:26:57 C/Out         
    Ben Locki 2020-07-06 10:05:18 C/In        
    Ben Locki 2020-07-06 12:50:52 C/Out         
    Ben Locki 2020-07-06 14:29:33 C/In        
    Ben Locki 2020-07-06 15:23:49 C/Out         
    Ben Locki 2020-07-06 17:38:41 C/In        
    Ben Locki 2020-07-06 18:58:16 C/Out     

    Imports System.IO
    
    Public Class Form1
        Dim Required As String = "Time Out"
        Dim Path As String = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "jk.txt")
        Dim OrigLst As New List(Of String)
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            Dim sr As StreamReader = New StreamReader(Path)
            Dim strLine As String
            Do While sr.Peek() >= 0
                strLine = String.Empty
                strLine = sr.ReadLine
                If strLine.Contains("John Dicki") Then
                    ListBox1.Items.Add(strLine)
                    OrigLst.Add(strLine)
                End If
            Loop
            sr.Close()
            ' OrigLst.AddRange(IO.File.ReadAllLines(Path))
            'ListBox1.Items.AddRange(OrigLst.ToArray)
            ' need to go through this to
            ' change any format of case to
            ' same (lower case) as original
            ' style was changed by OP
            For i As Integer = 0 To OrigLst.Count - 1
                OrigLst(i) = Trim((OrigLst(i).Replace("Enkeleda Sopaj ", Nothing)).ToLower)
            Next
            ' keep all lower case as case is
            ' undecided by OP
            OrigLst = StripDups("c/in", OrigLst)
            OrigLst = StripDups("c/out", OrigLst)
    
            Dim dts As New List(Of DateTime)
            Dim dt As DateTime = Nothing
            For i As Integer = 0 To OrigLst.Count - 1
                ' keep all lower case as case is
                ' undecided by OP
                OrigLst(i) = OrigLst(i).Replace(" c/out", Nothing).Replace(" c/in", Nothing)
                If DateTime.TryParse(OrigLst(i), dt) Then
                    dts.Add(dt)
                End If
            Next
    
            ListBox2.Items.AddRange(OrigLst.ToArray)
            Dim d2 As TimeSpan
            For i As Integer = 0 To OrigLst.Count - 2 Step 2
                Dim d1 As TimeSpan = dts(i + 1) - dts(i)
                ListBox3.Items.Add(dts(i + 1).ToString("HH:mm:ss") & " - " & dts(i).ToString("HH:mm:ss") & " = " & d1.ToString)
    
    
                d2 += d1
    
            Next
            ListBox4.Items.Add(d2.ToString())
    
    
        End Sub
        Function StripDups(s As String, lst As List(Of String)) As List(Of String)
            Dim inx As New List(Of Integer)
            For i As Integer = 0 To lst.Count - 2
                If lst(i).EndsWith(s) AndAlso lst(i + 1).EndsWith(s) Then
                    inx.Add(i + 1)
                End If
            Next
            inx.Reverse()
            For Each i As Integer In inx
                lst.RemoveAt(i)
            Next
            Return lst
        End Function
    End Class




    • Edited by ai1231 Tuesday, July 7, 2020 3:06 PM
    Tuesday, July 7, 2020 3:02 PM
  • Hi

    I don't know what you are doing in the code (for example, what has

    "John Dicki"

    got to do with the process as you only have

    "John Dick"

    in the list.

    *

    As you will be able to tell, when you start to change things mid way, then it is easy to lose support - you have now changed from fixed XX YY to variable first/last name. It makes a world of difference in how to handle the data.

    Anyway, a couple of questions to you.

    1.  Is the format of your data ALWAYS as you show?  (i.e.  is it always one word, space, one word, space, date, space, time, space, C/In or C/Out)

    2. Are the groups of name/date ALWAYS as you show with a blank line between?

    3. Do you have any control over the format of the data you are getting - such as the delimiters?

    4. Are you going to change your requirements later?

    *

    Before any further progress, please answer those questions.


    Regards Les, Livingston, Scotland

    Tuesday, July 7, 2020 3:32 PM
  • Hi

    OK, due to the lack of a response to my questions, here is my final attempt to help you.

    This is a stand alone example. It needs a BLANK default DataGridView1 on Form1.

    This version attempts to a) filter data file for duplicates b) display subtotal and total times per name block.

    I have used you latest data file WITH extra duplicate lines for testing.

    Image

    Here is the data file I have tested with:

    John Dick 2020-07-06 08:34:33 C/In  
    John Dick 2020-07-06 23:23:23 C/In       
    John Dick 2020-07-06 23:23:23 C/In
    John Dick 2020-07-06 23:23:23 C/In
    John Dick 2020-07-06 14:07:59 C/Out  
    John Dick 2020-07-06 23:23:23 C/Out 
    John Dick 2020-07-06 23:23:23 C/Out        
    John Dick 2020-07-06 14:26:26 C/In 
    John Dick 2020-07-06 23:23:23 C/In
    John Dick 2020-07-06 23:23:23 C/In       
    John Dick 2020-07-06 17:41:36 C/Out 
    John Dick 2020-07-06 23:23:23 C/Out 
    
    John Dick 2020-07-07 08:34:33 C/In        
    John Dick 2020-07-07 14:07:59 C/Out         
    John Dick 2020-07-07 14:26:26 C/In        
    John Dick 2020-07-07 17:41:36 C/Out 
    
    Ben Locki 2020-07-06 08:59:10 C/In        
    Ben Locki 2020-07-06 09:26:57 C/Out         
    Ben Locki 2020-07-06 10:05:18 C/In        
    Ben Locki 2020-07-06 12:50:52 C/Out         
    Ben Locki 2020-07-06 14:29:33 C/In        
    Ben Locki 2020-07-06 15:23:49 C/Out         
    Ben Locki 2020-07-06 17:38:41 C/In        
    Ben Locki 2020-07-06 18:58:16 C/Out  
    CODE
    ' https://social.msdn.microsoft.com/Forums/vstudio/en-US/6f24dc53-4f52-4849-951a-3d1655682f31/problem-with-a-list-task?forum=vbgeneral#022aa5ba-405b-4221-ae0e-3be42d8930ff
    Option Strict On
    Option Explicit On
    Public Class Form1
    	Dim dt As New DataTable("Freddy")
    	Dim BS As New BindingSource
    	Dim Path As String = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "Clockin.txt")
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    		'John Dick 2020-07-06 08:34:33 C/In   
    		With dt
    			.Columns.Add("Name", GetType(String))
    			.Columns.Add("Date", GetType(DateTime))
    			.Columns.Add("Action", GetType(String))
    			.Columns.Add("Worked", GetType(TimeSpan))
    
    			Dim lines() As String = IO.File.ReadAllLines(Path)
    
    			Dim start As String = "c/in"
    			Dim t1, t2 As DateTime
    			Dim t3 As TimeSpan = TimeSpan.Zero
    			Dim name As String = Nothing
    			For Each line As String In lines
    				Dim a() As String = line.Split(New String() {" "c}, StringSplitOptions.RemoveEmptyEntries)
    				If a.Length = 5 Then
    					If a(4).ToLower = start Then
    						If start = "c/in" Then
    							start = "c/out"
    							t1 = CDate(a(2) & " " & a(3))
    							If Not name = Nothing AndAlso Not a(0) & " " & a(1) = name Then
    								.Rows.Add(Nothing, Nothing, "Total", t3.ToString)
    								.Rows.Add()
    								t3 = TimeSpan.Zero
    							End If
    							.Rows.Add(a(0) & " " & a(1), t1, a(4))
    						Else
    							start = "c/in"
    							t2 = CDate(a(2) & " " & a(3))
    							Dim ts As TimeSpan = t2 - t1
    							name = a(0) & " " & a(1)
    							.Rows.Add(name, t2, a(4), ts.ToString)
    							t3 = t3.Add(ts)
    						End If
    					End If
    				End If
    			Next
    			.Rows.Add(Nothing, Nothing, "Total", t3.ToString)
    		End With
    		BS.DataSource = dt
    		With DataGridView1
    			.DataSource = BS
    			.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
    			.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
    			With .DefaultCellStyle
    				.BackColor = Color.PaleGoldenrod
    				.Font = New Font("Arial", 14)
    			End With
    			.RowHeadersVisible = False
    				.Columns("Date").DefaultCellStyle.Format = "dd MMM yyyy"
    				.Columns("Date").DefaultCellStyle.Format = "dd MMM yyyy HH:mm"
    			End With
      End Sub
    End Class


    Regards Les, Livingston, Scotland

    Wednesday, July 8, 2020 3:03 AM
  • Hi

    OK, due to the lack of a response to my questions, here is my final attempt to help you.

    This is a stand alone example. It needs a BLANK default DataGridView1 on Form1.

    This version attempts to a) filter data file for duplicates b) display subtotal and total times per name block.

    I have used you latest data file WITH extra duplicate lines for testing.

    Image

    Here is the data file I have tested with:

    John Dick 2020-07-06 08:34:33 C/In  
    John Dick 2020-07-06 23:23:23 C/In       
    John Dick 2020-07-06 23:23:23 C/In
    John Dick 2020-07-06 23:23:23 C/In
    John Dick 2020-07-06 14:07:59 C/Out  
    John Dick 2020-07-06 23:23:23 C/Out 
    John Dick 2020-07-06 23:23:23 C/Out        
    John Dick 2020-07-06 14:26:26 C/In 
    John Dick 2020-07-06 23:23:23 C/In
    John Dick 2020-07-06 23:23:23 C/In       
    John Dick 2020-07-06 17:41:36 C/Out 
    John Dick 2020-07-06 23:23:23 C/Out 
    
    John Dick 2020-07-07 08:34:33 C/In        
    John Dick 2020-07-07 14:07:59 C/Out         
    John Dick 2020-07-07 14:26:26 C/In        
    John Dick 2020-07-07 17:41:36 C/Out 
    
    Ben Locki 2020-07-06 08:59:10 C/In        
    Ben Locki 2020-07-06 09:26:57 C/Out         
    Ben Locki 2020-07-06 10:05:18 C/In        
    Ben Locki 2020-07-06 12:50:52 C/Out         
    Ben Locki 2020-07-06 14:29:33 C/In        
    Ben Locki 2020-07-06 15:23:49 C/Out         
    Ben Locki 2020-07-06 17:38:41 C/In        
    Ben Locki 2020-07-06 18:58:16 C/Out  
    CODE
    ' https://social.msdn.microsoft.com/Forums/vstudio/en-US/6f24dc53-4f52-4849-951a-3d1655682f31/problem-with-a-list-task?forum=vbgeneral#022aa5ba-405b-4221-ae0e-3be42d8930ff
    Option Strict On
    Option Explicit On
    Public Class Form1
    	Dim dt As New DataTable("Freddy")
    	Dim BS As New BindingSource
    	Dim Path As String = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "Clockin.txt")
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    		'John Dick 2020-07-06 08:34:33 C/In   
    		With dt
    			.Columns.Add("Name", GetType(String))
    			.Columns.Add("Date", GetType(DateTime))
    			.Columns.Add("Action", GetType(String))
    			.Columns.Add("Worked", GetType(TimeSpan))
    
    			Dim lines() As String = IO.File.ReadAllLines(Path)
    
    			Dim start As String = "c/in"
    			Dim t1, t2 As DateTime
    			Dim t3 As TimeSpan = TimeSpan.Zero
    			Dim name As String = Nothing
    			For Each line As String In lines
    				Dim a() As String = line.Split(New String() {" "c}, StringSplitOptions.RemoveEmptyEntries)
    				If a.Length = 5 Then
    					If a(4).ToLower = start Then
    						If start = "c/in" Then
    							start = "c/out"
    							t1 = CDate(a(2) & " " & a(3))
    							If Not name = Nothing AndAlso Not a(0) & " " & a(1) = name Then
    								.Rows.Add(Nothing, Nothing, "Total", t3.ToString)
    								.Rows.Add()
    								t3 = TimeSpan.Zero
    							End If
    							.Rows.Add(a(0) & " " & a(1), t1, a(4))
    						Else
    							start = "c/in"
    							t2 = CDate(a(2) & " " & a(3))
    							Dim ts As TimeSpan = t2 - t1
    							name = a(0) & " " & a(1)
    							.Rows.Add(name, t2, a(4), ts.ToString)
    							t3 = t3.Add(ts)
    						End If
    					End If
    				End If
    			Next
    			.Rows.Add(Nothing, Nothing, "Total", t3.ToString)
    		End With
    		BS.DataSource = dt
    		With DataGridView1
    			.DataSource = BS
    			.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
    			.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
    			With .DefaultCellStyle
    				.BackColor = Color.PaleGoldenrod
    				.Font = New Font("Arial", 14)
    			End With
    			.RowHeadersVisible = False
    				.Columns("Date").DefaultCellStyle.Format = "dd MMM yyyy"
    				.Columns("Date").DefaultCellStyle.Format = "dd MMM yyyy HH:mm"
    			End With
      End Sub
    End Class


    Regards Les, Livingston, Scotland

    Hello thanks for helping till here

    You got the idea of what I want but one with one problem on your last code

    You calculate the sum of a person for all dates,instead I want to calculate working hours for each person and for each date separately

    For example

    So loop through dates from 1-31 and for each name calculate working hours for each day

    So

    Day 2020-07-01

    John Dick = working hours

    Ben Locki = working hours

    Day 2020-07-02

    John Dick = working hours

    Ben Locki = working hours

    ect

    for each day of the month and for each name

       

    Your code does the job but if there are two or more different dates for a person it calculate them all,instead I want to calculate each date for that person separately



    This is what I achieved with the first example using listboxes

    Get for a specific date for each person in the list calculate hours

    How to make for all dates of the month? 

    • Edited by ai1231 Wednesday, July 8, 2020 9:26 AM
    Wednesday, July 8, 2020 7:07 AM
  • Hi

    Aain, you are just making more work for me. Sorry, but the ball is in your court now. You should not expect to keep changing/adding things you want - it is called 'moving the goal posts!'

    Are you aware of the work involved in trying to accomodate changes AFTERWARDS? These latest changes are now your problem.


    Regards Les, Livingston, Scotland

    Wednesday, July 8, 2020 10:53 AM
  • Hi

    Aain, you are just making more work for me. Sorry, but the ball is in your court now. You should not expect to keep changing/adding things you want - it is called 'moving the goal posts!'

    Are you aware of the work involved in trying to accomodate changes AFTERWARDS? These latest changes are now your problem.


    Regards Les, Livingston, Scotland


    Sorry if i didnt explain well from the begining. Anyway i will try out my self(as i am already) and if I achive it will post results. I think looping through dates will do the job I will use the first example with listboxes as it is more simple for me to undestand the code
    Wednesday, July 8, 2020 11:44 AM
  • Ok I achieved what I wanted

    Thank you leshay for your time

    • Marked as answer by ai1231 Wednesday, July 8, 2020 3:07 PM
    Wednesday, July 8, 2020 12:43 PM