none
obtener el valor medio de tres posibles de un datagridview RRS feed

  • Pregunta

  • buenas tardes a todos! mi duda es la siguiente..tengo un datagridview en el cual en distintas celdas le cargo valores mediante un DateTimePicker (dtpTiempo)a traves de un boton (btnAgregarTiempo), que equivale a los tiempos realizados por un atleta en una competencia. Una vez cagados los tres tiempos, se calcula el mejor tiempo, en este caso el mayor tiempo, y de acuerdo al tiempo la posicion respectiva del atleta.

    la pregusta es como puedo calcular el valor medio de esos tres tiempos (no el promedio) y guardarlo en otra celda("Mejor Tiempo") del mismo datagridview. Ejemplo: valor o tiempo 1= "01:01:01",valor o tiempo 2= "01:01:02", valor o tiempo 3= "01:01:03". MejorTiempo= "01:01:02"

    a continuacion les dejo el codigo que tengo y muchas gracias!!!

     ' CREACION DE CONSTANTES
        Const COLUMNA_PRIMER_TIEMPO As Integer = 5
        Const COLUMNA_SEGUNDO_TIEMPO As Integer = 6
        Const COLUMNA_TERCER_TIEMPO As Integer = 7
        Const COLUMNA_MEJOR_TIEMPO As Integer = 8

     ' BOTON AGREGAR TIEMPO
        Private Sub btnAgregarTiempo_Click(sender As System.Object, e As System.EventArgs) Handles btnAgregarTiempo.Click
            'VALIDA HS VACIA (00:00:00)

            If dtpTiempo.Value.ToString("HH:mm:ss") = "00:00:00" Then
                MessageBox.Show("Debe ingresar un tiempo para poder continuar")
                dtpTiempo.Select()
                dtpTiempo.Focus()
                Exit Sub
            End If
            'CONFIRMA INGRESO DE TIEMPO DEL ATLETA CON APELLIDO.....
            Dim filaActual = Me.dgvTiempos.SelectedRows(0)
            If MessageBox.Show("Confirma ingresar el tiempo de: " & Environment.NewLine & CStr(filaActual.Cells(3).Value),
                               "Confirmar acción", MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.Yes Then
                Dim valor As String = dtpTiempo.Value.ToString("HH:mm:ss")
                CargarSiguienteCelda(filaActual, valor)
                'limpiar el time picker
                dtpTiempo.Value = Date.FromOADate(0)
            End If
            btnActualizar.Enabled = True
            Ordenar()
        End Sub

     ' RECORRE LAS CELDAS, VALIDA QUE LA POSICION ESTE VACIA O SEA IGUAL A "00:00:00" INGRESA EL VALOR
        Private Sub CargarSiguienteCelda(ByRef filaActual As DataGridViewRow, valorAponer As String)
            ' recorre las columnas 4 a 6 que corresponden a los primeros tres tiempos
            For i As Integer = COLUMNA_PRIMER_TIEMPO To COLUMNA_TERCER_TIEMPO
                ' valida que la posicion este vacia, si es asi agrega el valor
                If String.IsNullOrEmpty(CStr(filaActual.Cells(i).Value).Trim()) OrElse CStr(filaActual.Cells(i).Value).Trim() = "00:00:00" Then 'busca la primer posición vacía d las celdas 4,5,6
                    filaActual.Cells(i).Value = valorAponer
                    If i = COLUMNA_TERCER_TIEMPO Then
                        CalcularMejorTiempo(filaActual)

                        MessageBox.Show("El Mejor Tiempo logrado de: " & Environment.NewLine & CStr(filaActual.Cells(3).Value) & filaActual.Cells(8).Value)
                    End If
                    Exit Sub
                End If
            Next
        End Sub

      ' CALCULO DEL MEJOR TIEMPO
        Private Sub CalcularMejorTiempo(ByRef filaActual As DataGridViewRow)

            If String.IsNullOrEmpty(CStr(filaActual.Cells(COLUMNA_MEJOR_TIEMPO).Value).Trim()) OrElse CStr(filaActual.Cells(COLUMNA_MEJOR_TIEMPO).Value).Trim() = "00:00:00" Then
                Dim Tiempos As List(Of Date) = New List(Of Date)
                Tiempos.Add(ConvertirADate(filaActual.Cells(COLUMNA_PRIMER_TIEMPO).Value))
                Tiempos.Add(ConvertirADate(filaActual.Cells(COLUMNA_SEGUNDO_TIEMPO).Value))
                Tiempos.Add(ConvertirADate(filaActual.Cells(COLUMNA_TERCER_TIEMPO).Value))
                filaActual.Cells(COLUMNA_MEJOR_TIEMPO).Value = Tiempos.OrderByDescending(Function(t) t.Hour). _
                    ThenByDescending(Function(t) t.Minute). _
                    ThenByDescending(Function(t) t.Second).First().ToString("hh:mm:ss")
            End If
        End Sub

     Private Sub Ordenar()
            'ORDENA EL DATAGRID Y PONE AS POSICIONES
            dgvTiempos.Sort(dgvTiempos.Columns(8), System.ComponentModel.ListSortDirection.Ascending)

            Dim cont As Integer
            cont = 0
            For Each rows As DataGridViewRow In Me.dgvTiempos.Rows
                cont = cont + 1
                rows.Cells(9).Value = cont
            Next
        End Sub


    valeria heredia


    martes, 18 de julio de 2017 19:54

Respuestas

  • Para calcular el valor medio recorre las tres columnas de tiempos y súmalos teniendo en cuenta que pueden no tener valor. Luego divides por el nº de casillas de tiempos con valor y ya tienes la media.

            Dim SumaTiempos As TimeSpan
            Dim NumeroDeTiempos As Integer = 0

            For Each Fila As DataGridViewRow In dgvTiempos.Rows

                SumaTiempos = TimeSpan.Zero
                NumeroDeTiempos = 0

                For Columna As Integer = COLUMNA_PRIMER_TIEMPO  To COLUMNA_TERCER_TIEMPO 
                    If Not String.IsNullOrEmpty(Fila.Cells(Columna).Value) Then

                        NumeroDeTiempos += 1

                        SumaTiempos += TimeSpan.Parse(Fila.Cells(Columna).Value)

                    End If
                Next

                If NumeroDeTiempos > 0 Then
                    Dim Media As Long = SumaTiempos.Ticks / NumeroDeTiempos
                    Fila.Cells(COLUMNA_MEDIA_TIEMPOS).Value = New TimeSpan(Media)
                End If
            Next


    Saludos, Javier J

    miércoles, 19 de julio de 2017 8:54
  • Entiendo que deseas obtener la mediana, ¿verdad?. El procedimiento es muy simple, sólo debes tener en cuenta dos consideraciones:

    - La lista debe estar ordenada de manera creciente.

    - Si la cantidad de elementos es impar la mediana es la central, si la cantidad de elementos es par la mediana es la media entre los elementos centrales. Para el caso que expones (tres registros de tiempo) el cálculo es simple porque la mediana coincide con la central.

    Private Sub btnMejorTiempo_Click(sender As Object, e As EventArgs) Handles btnMejorTiempo.Click
    
    	Dim Fila = DataGridView1.CurrentRow
    
    	If Fila IsNot Nothing Then
    
    		Dim Tiempos As New List(Of TimeSpan) From
    			{
    				TimeSpan.ParseExact(Fila.Cells("Tiempo1").Value.ToString, "c",
    								CultureInfo.InvariantCulture),
    				TimeSpan.ParseExact(Fila.Cells("Tiempo2").Value.ToString, "c",
    								CultureInfo.InvariantCulture),
    				TimeSpan.ParseExact(Fila.Cells("Tiempo3").Value.ToString, "c",
    								CultureInfo.InvariantCulture)
    			}
    
    		Fila.Cells("MejorTiempo").Value = Tiempos.
    				OrderBy(Function(c) c.TotalSeconds).ToList()(1)
    
    	End If
    End Sub

    - Resultado (los datos no siempre se registran ordenados):


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    jueves, 20 de julio de 2017 4:58

Todas las respuestas

  • Para calcular el valor medio recorre las tres columnas de tiempos y súmalos teniendo en cuenta que pueden no tener valor. Luego divides por el nº de casillas de tiempos con valor y ya tienes la media.

            Dim SumaTiempos As TimeSpan
            Dim NumeroDeTiempos As Integer = 0

            For Each Fila As DataGridViewRow In dgvTiempos.Rows

                SumaTiempos = TimeSpan.Zero
                NumeroDeTiempos = 0

                For Columna As Integer = COLUMNA_PRIMER_TIEMPO  To COLUMNA_TERCER_TIEMPO 
                    If Not String.IsNullOrEmpty(Fila.Cells(Columna).Value) Then

                        NumeroDeTiempos += 1

                        SumaTiempos += TimeSpan.Parse(Fila.Cells(Columna).Value)

                    End If
                Next

                If NumeroDeTiempos > 0 Then
                    Dim Media As Long = SumaTiempos.Ticks / NumeroDeTiempos
                    Fila.Cells(COLUMNA_MEDIA_TIEMPOS).Value = New TimeSpan(Media)
                End If
            Next


    Saludos, Javier J

    miércoles, 19 de julio de 2017 8:54
  • javier!! gracias por tu atencion!! entiendo lo que dices..pero disculpame, me he expresado mal

    necesito obtener el valor del medio de los 3 tiempos ingresados (NO EL PROMEDIO!!).

    por ejemplo:

      1° tiempo: 01:01:01

    2° tiempo:  01:01:02 ======>   este es el valor que debo obtener para utilizarlo como "Mejor Tiempo"

    3° tiempo: 01:01:03

    es decir que debo hacer la comparacion entre los tres. Debo ver todas las posibilidades posibles..

    muchas gracias nuevamente por tu atencion!! saludos cordiales


    valeria heredia

    jueves, 20 de julio de 2017 1:29
  • Entiendo que deseas obtener la mediana, ¿verdad?. El procedimiento es muy simple, sólo debes tener en cuenta dos consideraciones:

    - La lista debe estar ordenada de manera creciente.

    - Si la cantidad de elementos es impar la mediana es la central, si la cantidad de elementos es par la mediana es la media entre los elementos centrales. Para el caso que expones (tres registros de tiempo) el cálculo es simple porque la mediana coincide con la central.

    Private Sub btnMejorTiempo_Click(sender As Object, e As EventArgs) Handles btnMejorTiempo.Click
    
    	Dim Fila = DataGridView1.CurrentRow
    
    	If Fila IsNot Nothing Then
    
    		Dim Tiempos As New List(Of TimeSpan) From
    			{
    				TimeSpan.ParseExact(Fila.Cells("Tiempo1").Value.ToString, "c",
    								CultureInfo.InvariantCulture),
    				TimeSpan.ParseExact(Fila.Cells("Tiempo2").Value.ToString, "c",
    								CultureInfo.InvariantCulture),
    				TimeSpan.ParseExact(Fila.Cells("Tiempo3").Value.ToString, "c",
    								CultureInfo.InvariantCulture)
    			}
    
    		Fila.Cells("MejorTiempo").Value = Tiempos.
    				OrderBy(Function(c) c.TotalSeconds).ToList()(1)
    
    	End If
    End Sub

    - Resultado (los datos no siempre se registran ordenados):


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    jueves, 20 de julio de 2017 4:58
  • williams!! gracias!! te debo la nota de mi tesis!! funciona perfecto el codigo. saludos!!


    valeria heredia

    jueves, 20 de julio de 2017 19:17