Question Smallest Value in DataGridView Column

BleepyEvans

Active member
Joined
May 2, 2011
Messages
41
Programming Experience
1-3
Hi guys, ive been working on a stopwatch project as some of you know.

Ive created the stopwatch, and thanks to some of your members, I finally got the stopwatch to add the timings into a datagridview every time the lap button is pressed.

Although because im converting the times to strings im having trouble trying to get the smallest value for the fastest lap.

Here what some of my form looks like:
Untitled-1.png

And some of my code:
Private Sub LapButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LapButton.Click
        i += 1
        If DataGridView1.Rows.Count > 0 Then
            DataGridView1.Rows.Add(i, StopwatchLabel.Text, laptimerer.Text)
        Else
            DataGridView1.Rows.Add(i, StopwatchLabel.Text, StopwatchLabel.Text)
        End If
        Label3.Text = Label3.Text + Val(1)
        lapTime = DateTime.Now
    End Sub


    Private Sub StartButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartButton.Click
        startTime = DateTime.Now
        StartStopWatch()
    End Sub


 Public Sub StartStopWatch()
        startTime = DateTime.Now
        StopWatch.Start()
        InRaceCountDownTime = DateTime.Now.AddMinutes(racelength.Text)
        InRaceCountDownTimer.Start()
        ProgressBar1.Value = 0
        lapTime = DateTime.Now
        Lap.Start()
    End Sub


 Private Sub Lap_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Lap.Tick
        Dim span As TimeSpan = DateTime.Now.Subtract(lapTime)
        laptimerer.Text = span.Minutes.ToString & ":" & span.Seconds.ToString & "." & span.Milliseconds
      End Sub


Any ideas guys?
 
By adding this to form load?
DataGridView1.Columns("Lap Time").DefaultCellStyle.Format = "mm:ss.tt"


If so, then how can I get the timespan, into the datagrid when the button is pressed as they are in differnet subs :/
 
Last edited:
That helped alot thanks, and I was wrong it wasnt what I coded before, it was ment to be:
DataGridView1.Columns(3).DefaultCellStyle.Format = "mm\:ss\:fff"

Thanks

-

Anyways, I also solved the problem of the differnet subs. As Im not using labels any more because im leaving the as Spans, I have no need in keeping the timers. So I just put the span code straight into my lap button sub.

As we have solved the "sub-issues", now how can I detect which is the smallest span in the column, or in other words, the fastest lap?
 
Last edited:
As you're using .NET 4.0, the simplest option is to use LINQ and the Min function, e.g.
Dim minTimeRow As DataGridViewRow = myDataGridView.Rows.Cast(Of DataGridViewRow)().Min(Function(row) CDate(row.Cells(3).Value).TimeOfDay)
That will give you the row that contains the minimum time. If you need just the minimum time itself then you can modify that code a little.
 
As you're using .NET 4.0, the simplest option is to use LINQ and the Min function, e.g.
Dim minTimeRow As DataGridViewRow = myDataGridView.Rows.Cast(Of DataGridViewRow)().Min(Function(row) CDate(row.Cells(3).Value).TimeOfDay)
That will give you the row that contains the minimum time. If you need just the minimum time itself then you can modify that code a little.

How would I get that to work for a time span?
Value of type 'System.TimeSpan' cannot be converted to 'System.Windows.Forms.DataGridViewRow'.

Thanks
 
Sorry about that. I typed that code straight into the forum without testing and I was wrong about what it would return. I was thinking that it would return the whole row but it just returns the TimeSpan. In that case it should be:
Dim minTimeRow As DataGridViewRow = myDataGridView.Rows.Cast(Of DataGridViewRow)().Min(Function(row) CDate(row.Cells(3).Value).TimeOfDay)
That won't work if you can add new data directly to the grid though, because it will always come up with a zero time in the data entry row. In that case you'd need to add a Where call:
Dim minTime As TimeSpan = Me.DataGridView1.Rows.Cast(Of DataGridViewRow)().
                                                Where(Function(row) Not row.IsNewRow).
                                                Min(Function(row) CDate(row.Cells(3).Value).TimeOfDay)
which would probably be better written in query syntax:
Dim minTime As TimeSpan = (From row In Me.DataGridView1.Rows.Cast(Of DataGridViewRow)()
                           Where Not row.IsNewRow
                           Select CDate(row.Cells(3).Value).TimeOfDay).Min()
 
Was looking good until i got this:
Conversion from string "0:1.95" to type 'Date' is not valid.

My Columns are in format:
DataGridView1.Columns(4).DefaultCellStyle.Format = "c"

also tried this
DataGridView1.Columns(3).DefaultCellStyle.Format = "mm\:ss\:fff"




And I used for final version of the code:
Dim minTime As TimeSpan = (From row In Me.DataGridView1.Rows.Cast(Of DataGridViewRow)()
                           Where Not row.IsNewRow
                           Select CDate(row.Cells(3).Value).TimeOfDay).Min()


While im here, can I just check, that this finds the smallest value in the column, not row?

Thanks
 
Last edited:
Also would there be anything in the TimeSpan.MinValue.

Im not familiar with it but I accidnt came across it and thought it might be an easy solution if someone could help me get it to work.
 
Ok Thanks

Untitled-1.png

 Private Sub LapButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LapButton.Click
        Dim span As TimeSpan = DateTime.Now.Subtract(lapTime)
        i += 1

        If DataGridView1.Rows.Count > 0 Then

            Dim minTime As TimeSpan = (From row In Me.DataGridView1.Rows.Cast(Of DataGridViewRow)()
                           Where Not row.IsNewRow
                           Select CDate(row.Cells(3).Value).TimeOfDay).Min()
            DataGridView1.Rows.Add(i, StopwatchLabel.Text, span, minTime)

        Else

            DataGridView1.Rows.Add(i, StopwatchLabel.Text, StopwatchLabel.Text, StopwatchLabel.Text)

        End If
        Label3.Text = Label3.Text + Val(1)
        lapTime = DateTime.Now

    End Sub
 
You have apparently ignored what I said back in post #2. If your code is unable to convert the values in the grid from type String to type Date then that means that they must be type String in the first place. I told you not to use Strings but rather to use Dates instead. If you were doing that then there'd be no conversion required.
 
I have been doing that, cells are in the format m\:s\:fff which I found using the link JohnH gave me after your post, link named Custom TimeSpan Format Strings

My Form1 load code is;
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        DataGridView1.ColumnCount = 4
        DataGridView1.Columns(1).DefaultCellStyle.Format = "m\:s\.fff"
        DataGridView1.Columns(2).DefaultCellStyle.Format = "m\:s\.fff"
        DataGridView1.Columns(3).DefaultCellStyle.Format = "m\:s\.fff"
    End Sub


It I had of converted the time into a string then surely the lap time wouldnt show when I used this code;

------------------------------------------------------------------------

Private Sub LapButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LapButton.Click
Dim span As TimeSpan = DateTime.Now.Subtract(lapTime)

i += 1

If DataGridView1.Rows.Count > 0 Then


Dim minTime As TimeSpan = (From row In Me.DataGridView1.Rows.Cast(Of DataGridViewRow)()

Where Not row.IsNewRow
Select CDate(row.Cells(3).Value).TimeOfDay).Min()

DataGridView1.Rows.Add(i, StopwatchLabel.Text, span, minTime)

Else


DataGridView1.Rows.Add(i, StopwatchLabel.Text, StopwatchLabel.Text, StopwatchLabel.Text)


End If

Label3.Text = Label3.Text + Val(1)
lapTime = DateTime.Now

End Sub

------------------------------------------------------------------------

It sounds more like that the code you gave me is incorrect as the error message says
"Conversion from string "0:0.502" to type 'Date' is not valid."
 
Last edited:
Well gee, do you think that this might be the issue?
VB.NET:
DataGridView1.Rows.Add(i, StopwatchLabel.Text, StopwatchLabel.Text, StopwatchLabel.Text)
You're adding an Integer and three Strings.
 
Back
Top