none
Eliminar las filas de un datagridview que ha sido filtrado RRS feed

  • Pregunta

  • ¿Como puedo borrar las filas de un Datagridview que previamente he cargado mediante un filtro?

    El datagrid está enlazado mediante la propiedad Datasource del control a la tabla de datos.

     

    Lo que por el momento estoy intentando es lo siguiente:

     Try

                Dim pregunta As Integer

                pregunta = MessageBox.Show("Se dispone a eliminar un registro relacionado los documentos que haya creado. Debe de saber que la eliminación del registro conlleva la eliminación de los documentos." & Chr(13) & "¿Desea eliminar dicho registro?, presione 'SI' para eliminarlo, o por el contrario presione NO para anular este proceso.", "Información", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)

                If pregunta = Windows.Forms.DialogResult.Yes Then

    'con la siguiente línea filtro los documentos por el número de registro.

                    Me.DocumentosTableAdapter.FiltrarPorID(Me.DataSet.Documentos, nID)

                    'Ahora recorro las líneas del datagrid para eliminar los registros

    For i As Integer = 0 To DGVDocumentos.Rows.Count - 1

                        Me.DGVDocumentos.Rows.RemoveAt(i)

                    Next

                 PREGUNTA: ¿Es suficiente con las siguientes líneas para actualizar los datos enlazados a la base de datos? o falta algo más?...

                    Me.Validate()

                    Me.DocumentosBindingSource.EndEdit()

                    Me.DocumentosTableAdapter.Update(Me.DataSet.Documentos)

                    MessageBox.Show("Ok, El registro y los documentos han sido eliminados.", "Datos eliminados", MessageBoxButtons.OK)

                Else

            End If

           Catch ex As Exception

                MessageBox.Show(ex.Message, "Error")

            End Try

     

    Bueno el problema es que me sale este mensaje:

    "El índice de fila proporcionado está fuera de rango. Nombre del parámetro: index"

     

    Lo he intentado también de esta forma:

    Dim fila As Integer

                    If fila < 0 OrElse fila > DGVDocumentos.Rows.Count - 1 Then Exit Sub

                    For Each row As DataGridViewRow In DGVDocumentos.Rows

                        DGVDocumentos.Rows.Remove(row)

                    Next

    Pero me salía otro error:

    Update requeire que DeleteCommand sea válido cuando se pasa la colección Datarow con filas eliminadas.

     

    ¿Que estoy haciendo mal?...

    sábado, 30 de octubre de 2010 19:41

Respuestas

  • "Tavernero" me preguntó:

    > SoftJaen: He probado las líneas de código que aportas, y sigue saliendo el error
    > (Update requeire que DeleteCommand sea válido cuando se pasa la colección
    > Datarow con filas eliminadas),  por lo que deduzco, que el origen de datos
    > no está bien configurado, pero en cambio si me añade datos y me los modifica.

    ¡Bueno! Las líneas de código que te aporté solamente sirven para que no obtengas las excepción "El índice de fila proporcionado está fuera de rango. Nombre del parámetro: index", que por supuesto no tiene nada que ver con la excepción "Update requeire que DeleteCommand sea válido cuando se pasa la colección Datarow con filas eliminadas".

    Al igual que te indiqué anteriormente, si obtienes ésta última excepción, entiendo que se debe a que el adaptador de datos del origen de datos no está debidamente configurado, concretamente su propiedad DeleteCommand, porque si se permite añadir nuevas filas y modificar las ya existente, será porque sus propiedades InsertCommand y UpdateCommand estarán correctamente definidas.

    > SoftJaen... ¿se te ocurre algo más para comprobar donde estoy metiendo la pata...?
    >
    > Me.DocumentosTableAdapter.Update(Me.DataSet.Documentos)

    Antes de llamar al método Update del adaptador de datos, establece un punto de interrupción para que en tiempo de ejecución consultes en la Ventana Inmediato (se activa pulsando Control + G), el valor de la propiedad DeleteCommand:

        ? Me.DocumentosTableAdapter.Adapter.DeleteCommand

    Si su valor es Nothing, está claro que no puedes eliminar filas. Tienes que configurar correctamente dicha propiedad, de la misma manera que has configurado las propiedades InsertCommand y UpdateCommand, pero claro está, para poder ejecutar una consulta SQL de eliminación (DELETE).

    Si en tu proyecto has configurado un origen de datos, entiendo que el Asistente ha tenido que crear y configurar la propiedad DeleteCommand, salvo que algo raro haya ocurrido a la hora de configurar el origen de datos.

    NOTA: como observo que Leandro Tuttini también participa en la conversación, te indico que yo solamente voy a entrar en las preguntas que directa y exclusivamente me efectues a mí, porque yo te puedo indicar una cosa y Leandro Tuttini te puede indicar otra muy diferente, o viceversa, tal y como ya he tenido oportunidad de comprobar, con lo cual, lo único que puede pasar es que te "hagas la picha un lío", aparte de que la conversación se puede hacer bastante larga. Y como me imagino que tanto tú como yo no queremos que eso suceda, sería conveniente que le preguntaras únicamente a él o me preguntaras únicamente a mí, porque él puede tener una opinión, o ver las cosas, de diferente manera a como yo las veo, formas de opinar y pensar que yo respeto totalmente, como no podía ser de otra manera. ¿De acuerdo?

     


    Enrique Martínez [MS MVP - VB]
    • Marcado como respuesta Tavernero domingo, 31 de octubre de 2010 23:03
    domingo, 31 de octubre de 2010 7:11
    Moderador
  • hola

    podrias validar que no tenga nulos el valor de la grilla

     

    For Each row As DataGridViewRow In DGVDocumentos.Rows

      If row.Cells("nombrecampoId").Value IsNot DBNull.Value Then

           DocumentosTableAdapter.Delete(CInt(row.Cells("nombrecampoId").Value))

      End If

    Next

     

    salidos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta Tavernero domingo, 31 de octubre de 2010 23:03
    domingo, 31 de octubre de 2010 21:00

Todas las respuestas

  • > 'Ahora recorro las líneas del datagrid para eliminar los registros
    >
    >  For i As Integer = 0 To DGVDocumentos.Rows.Count - 1
    >
    >    Me.DGVDocumentos.Rows.RemoveAt(i)
    >
    >  Next
    >
    > Bueno el problema es que me sale este mensaje:
    >
    > "El índice de fila proporcionado está fuera de rango. Nombre del parámetro: index"

    Tal cual estás recorriendo el bucle For ... Next, es normal que te aparezca ese mensaje de error, porque al eliminar la fila del control DataGridView, se van disminuyendo el número de filas existentes, y llegará un momento en que no exista el índice especificado por el valor de la variable « i » del bucle, de ahí que se produzca la excepción.

    Para eliminar todas las filas del control DataGridView, tienes que recorrer las filas al revés: de la última a la primera fila:

           For i As Integer = FacturasDataGridView.Rows.Count - 1 To 0 Step -1

                    ' Si es la fila de nuevos registros, pasamos al siguiente índice
                    '
                    If (DGVDocumentos.Rows(i).IsNewRow) Then Continue For

                    Me.DGVDocumentos.Rows.RemoveAt(i)

            Next

    > PREGUNTA: ¿Es suficiente con las siguientes líneas para actualizar
    > los datos enlazados a la base de datos? o falta algo más?...
    >
    >                Me.Validate()
    >
    >                Me.DocumentosBindingSource.EndEdit()
    >
    >                Me.DocumentosTableAdapter.Update(Me.DataSet.Documentos)

    Si el origen de datos de tu proyecto está bien configurado, en principio es más que suficiente.


    > Pero me salía otro error:
    >
    > Update requeire que DeleteCommand sea válido cuando se pasa
    > la colección Datarow con filas eliminadas.

    Esto creo que es otro tema bien distinto. Insisto que si el origen de datos está bien configurado, no tienes por qué obtener éste mensaje de error.

    Prueba a eliminar las filas del control DataGridView tal y como te he comentado.

    Un saludo

     


    Enrique Martínez [MS MVP - VB]
    sábado, 30 de octubre de 2010 21:30
    Moderador
  • hola

    no entendi la finalidad de ese codigo

    veo que haces

    Me.DocumentosTableAdapter.FiltrarPorID(Me.DataSet.Documentos, nID)

    luegos recorrer las filas para eliminar los registros e la grilla, pero continuas con estas ultimas dos lineas

    Me.DocumentosBindingSource.EndEdit()                  Me.DocumentosTableAdapter.Update(Me.DataSet.Documentos)

    que pareciera estan actualziando el dataset que acabas de cargar en la priemr linea, pero sin haber realziado ningun cambio, no veo donde has asignado el DataSet.Documentos, al DataGridView

     

    no me cerro cual es el objetivo del codigo, si necesitas eliminar los registros podrias ahcerlo directo en el DataSet, usando el TableAdapter que se crea a tal fin, o es mas crear un metodo nuevo en el TableAdapter en dodne le apses el id del registro que quieres eliminar

    en este articulo

    Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0

    explic como extender el tableadaptr para agregar nueva funcionalidad, alli podrias agregar el metodo nuevo para eliminar, pasandole un valor determinado

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    sábado, 30 de octubre de 2010 21:53
  • Hola SoftJaen y Leandro, ante todo, muchas gracias por vuestro interés y ayuda.

    SoftJaen: He probado las líneas de código que aportas, y sigue saliendo el error (Update requeire que DeleteCommand sea válido cuando se pasa la colección Datarow con filas eliminadas),  por lo que deduzco, que el origen de datos no está bien configurado, pero en cambio si me añade datos y me los modifica.

    Mi método para configurarlo ha sido de la siguiente forma:

    He creado un formulario, he arrastrado algunos de los controles textbox y demás desde el origen de datos hasta el formulario, y otros los he enlazado directamente mediante la propiedad Databinding y Text a la tabla y columna que estará enlazado de forma que los datos los envio y cargo desde la base de datos sin problemas.

    El datagridview está enlazado con la propiedad bindingsource, y los filtros me funcionan correctamente.

    SoftJaen... ¿se te ocurre algo más para comprobar donde estoy metiendo la pata...? cualquier consejo será muy útil para mí.

     

    Leandro, te explico:

    Cuando el usuario quiere eliminar un registro y éste registro tiene relacionado por su número unos documentos, también tengo que eliminar los documentos, por lo que primero necesito borrar estos documentos, para ello (se me ocurre) que primero sería realizar un filtro de los documentos que ese registro tiene asignados y una vez filtrados éstos se muestran en el datagridview y por lo tanto, puedo borrarlos únicamente los que están relacionados con dicho registro... para posteriormente pasar a borrar el registro.

    Si bien como comentas, si puedo eliminar desde la tabla directamente los registros, pues sería buena opción, pero está el problema que no se como hacerlo... 

    En el artículo que muestras, se entiende como crear un procedimiento con el diseñador de dataset para efectuar un INSERT, UPDATE o DELETE entre otras... pero tendría que pasarle igualmente parámetros para eliminar uno a uno cada registro... sería de agradecer que me añadieras alguna forma de hacerlo una vez tuviera creado el procedimiento para borrar la fila...

    Gracias.


    .


    sábado, 30 de octubre de 2010 22:41
  • hola

    hay distintas formas de hacerlo, pero se me ocurre sie s que queres controlar el proceso que crees en el TableAdapter un nuevo metodo para elimianr los registros, usa la opciond e DELETE de esta pantalla imagen

    por supuesto usarias una query del tipo DELETE FROM Tabla WHERE id = @id

    el nombre del campo podrias cambirlo esto es solo un ejmeplo, al igual que el nombre de la tablas

    la idea es que luego recorras el DataGridView he invoques por cada fila el metodo del delete del TabelAdapter

    For Each row As DataGridViewRow In DGVDocumentos.Rows

      DocumentosTableAdapter.Delete(CInt(row.Cells("nombrecampoId").Value))

    Next

    la idea es que envies al Delete() el identificador o clave de la tabla para eliminar cada registro

    entocnes de esta forma ya no eliminas del DataGridView la fila, sino que lo haces directo en la tabla, al final luego del for Each  recargas los datos de la grilla para actualziar la informacion

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    sábado, 30 de octubre de 2010 23:16
  • "Tavernero" me preguntó:

    > SoftJaen: He probado las líneas de código que aportas, y sigue saliendo el error
    > (Update requeire que DeleteCommand sea válido cuando se pasa la colección
    > Datarow con filas eliminadas),  por lo que deduzco, que el origen de datos
    > no está bien configurado, pero en cambio si me añade datos y me los modifica.

    ¡Bueno! Las líneas de código que te aporté solamente sirven para que no obtengas las excepción "El índice de fila proporcionado está fuera de rango. Nombre del parámetro: index", que por supuesto no tiene nada que ver con la excepción "Update requeire que DeleteCommand sea válido cuando se pasa la colección Datarow con filas eliminadas".

    Al igual que te indiqué anteriormente, si obtienes ésta última excepción, entiendo que se debe a que el adaptador de datos del origen de datos no está debidamente configurado, concretamente su propiedad DeleteCommand, porque si se permite añadir nuevas filas y modificar las ya existente, será porque sus propiedades InsertCommand y UpdateCommand estarán correctamente definidas.

    > SoftJaen... ¿se te ocurre algo más para comprobar donde estoy metiendo la pata...?
    >
    > Me.DocumentosTableAdapter.Update(Me.DataSet.Documentos)

    Antes de llamar al método Update del adaptador de datos, establece un punto de interrupción para que en tiempo de ejecución consultes en la Ventana Inmediato (se activa pulsando Control + G), el valor de la propiedad DeleteCommand:

        ? Me.DocumentosTableAdapter.Adapter.DeleteCommand

    Si su valor es Nothing, está claro que no puedes eliminar filas. Tienes que configurar correctamente dicha propiedad, de la misma manera que has configurado las propiedades InsertCommand y UpdateCommand, pero claro está, para poder ejecutar una consulta SQL de eliminación (DELETE).

    Si en tu proyecto has configurado un origen de datos, entiendo que el Asistente ha tenido que crear y configurar la propiedad DeleteCommand, salvo que algo raro haya ocurrido a la hora de configurar el origen de datos.

    NOTA: como observo que Leandro Tuttini también participa en la conversación, te indico que yo solamente voy a entrar en las preguntas que directa y exclusivamente me efectues a mí, porque yo te puedo indicar una cosa y Leandro Tuttini te puede indicar otra muy diferente, o viceversa, tal y como ya he tenido oportunidad de comprobar, con lo cual, lo único que puede pasar es que te "hagas la picha un lío", aparte de que la conversación se puede hacer bastante larga. Y como me imagino que tanto tú como yo no queremos que eso suceda, sería conveniente que le preguntaras únicamente a él o me preguntaras únicamente a mí, porque él puede tener una opinión, o ver las cosas, de diferente manera a como yo las veo, formas de opinar y pensar que yo respeto totalmente, como no podía ser de otra manera. ¿De acuerdo?

     


    Enrique Martínez [MS MVP - VB]
    • Marcado como respuesta Tavernero domingo, 31 de octubre de 2010 23:03
    domingo, 31 de octubre de 2010 7:11
    Moderador
  • Bueno, vuelvo al ataque para resolver este "tapón" que me tiene colapsado.

    SoftJaen, primero que todo, comentarte que en estos momentos soy una completa "esponja" lo absorbo todo, cualquier participación que un experto como vosotros realice, me sirve, no es trabajo perdido, de hecho, me sirvo de los cientos de contestaciones que habéis realizado tanto tu como Leandro y muchos otros, y me consta que otros compañeros mios usan este foro muy a menudo y todos somos unos auténticos seguidores de cada uno de vuestras aportaciones, en este caso, si por cualquier causa no utilizara alguna de las opciones que cada uno me propone, puedes tener por seguro, que en cualquier otro momento serán utilizados.

    Volviendo al caso en concreto, he comprobado que tenía mal configurado el Tableadapter, he agregado el método Deletecommand, seguidamente me ha dado otro error que he resuelto configurando la propiedad CommandText, seguidamente me ha dado otro error, que no he podido solucionar porque tengo algo más, mal.

     

    Leandro: Probando el código que aportas, he conseguido borrar las filas del documento, pero me da el siguiente error:

    La conversión del tipo 'DBNull' en el tipo Integer no es válida.

    Una vez se han eliminado correctamente los documentos, le paso los parámetros para eliminar el registro principal de la forma siguiente:

    Int32.TryParse(Me.IDTextBox.Text, NumID)

    REGISTROSTableAdapter.DeleteRegistro(NumID)

    y seguidamente me sale dicho error.

    ¿Que puedo hacer en este caso?...

     

    domingo, 31 de octubre de 2010 20:51
  • hola

    podrias validar que no tenga nulos el valor de la grilla

     

    For Each row As DataGridViewRow In DGVDocumentos.Rows

      If row.Cells("nombrecampoId").Value IsNot DBNull.Value Then

           DocumentosTableAdapter.Delete(CInt(row.Cells("nombrecampoId").Value))

      End If

    Next

     

    salidos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta Tavernero domingo, 31 de octubre de 2010 23:03
    domingo, 31 de octubre de 2010 21:00
  • Muchas gracias a los dos, con ésto último he podido resolver el problema que me daba al borrar las filas con el código de Leandro, aunque los dos me habéis ayudado muchísimo.

    También se me ha resuelto el problema que me daba al hacerlo con el código aportado con Softjaen, el error estaba en que había colocado mal el orden de las líneas de filtro y actualización.

     

    domingo, 31 de octubre de 2010 23:03