locked
listview (copiar datos en excel) RRS feed

  • Pregunta

  • buenas con todos soy nuevo espero poder hacer muchos amigos y resolver muchas dudas desde ya muchas gracias por su ayuda

    tengo un problema con el listview quiero copiarlo a excel pero en un rango de celdas o que comienze a llenar mi excel a partir de la 14va fila por ejemplo este es el codigo q estoy utilizando:

    Public Class Form1
    
        Dim cn As New OleDb.OleDbConnection
        Dim cm As New OleDb.OleDbCommand
        Dim da As New OleDb.OleDbDataAdapter
        Dim dt As New DataTable
        Dim dataset As DataSet
    
        Sub llenarListview()
    
        End Sub
    
        Private Sub form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'cuando el formulario carga crear la conexion , notese que el string de conexion se edita de forma manual.
    
            llenarListview()
            cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\SISTEMAS-MONITOREO\Desktop\visual\BDACC\datos.xlsx;Extended Properties=Excel 12.0"
    
            Dim sql = "select * from [Hoja1$]"
            da = New OleDb.OleDbDataAdapter(sql, cn)
            da.Fill(dt)
    
            'llenar el listwiev
    
            For i = 0 To dt.Rows.Count - 1
    
                ListView1.Items.Add(dt.Rows(i).Item(0))
                ListView1.Items(i).SubItems.Add(dt.Rows(i).Item(1))
    
    
            Next
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'agrega en la BD
            cn.Open()
            cm.Connection = cn
    
            cm.CommandText = "insert into [Hoja1$]values ('" & TextBox1.Text & "','" & TextBox2.Text & "','" & TextBox3.Text & "')"
            cm.ExecuteNonQuery()
    
            'Agrega en el list view
            Dim indice As Integer = ListView1.Items.Count
    
    
            ListView1.Items.Add(TextBox1.Text) 'agrega una fila nueva
                ListView1.Items(indice).SubItems.Add(TextBox2.Text)
                ListView1.Items(indice).SubItems.Add(TextBox3.Text) ' agrega una columna nueva en la fila creada
    
                cn.Close()
    
        End Sub
    End Class

    viernes, 15 de septiembre de 2017 21:35

Respuestas

  • Hola Ericks, bien en primer lugar trata de modificár la hoja para que la parte en que se encuentra la tabla mantenga el orden de las celdas y en el caso modifíaca lo que se encuentra por soble ella de esta manera la carga sera coherente, desconosco si existe alguna forma de utilizar los datos con celdas modificadas (celdas unificadas) por otro lado verifica los tipos de datos, cuando se toman mediant Ado Net, al ingresar los datos en un tatatable este "acomoda" los tipos de acuerdo a lo que va recibiendo, si carga fechas de origen pedirá fechas al cargar. Bueno el tema cuando el excel no tiene un formato definido de tabla, como es tu caso, se debe seleccionar un rango y especificar que DHR= NO lo que significa que no tomara tal cual la tabla, dado esto el valor de los campos cambia, se especifica F1, F2, F3..... Que es el nombre por defecto que tomara la tabla para sus columnas (campos)  y se agrega un seudonimo a el VALOR. Por lo que en tu caso quedaría algo así:

     cn = New System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0; " & "data source=" & path & "; Extended Properties= 'Excel 12.0 Xml;HDR=NO'")

    da = New System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " & "[" & "Hoja1$" & "A15:J200" & "]  ", cn)

    Y luego colocarémos el INSERT para la carga de datos

     cn.CommandText = "INSERT INTO [Hoja1$]  (F1,F2,F3,F4,F5,F6) VALUES (@F1,@F2,@F3,@F4,@F5,@F6)"
            cm.Parameters.AddWithValue("@F1", num + 1)
            cm.Parameters.AddWithValue("@F2", TextBox3.Text)
            cm.Parameters.AddWithValue("@F3", TextBox5.Text)
            cm.Parameters.AddWithValue("@F4", TextBox6.Text)
            cm.Parameters.AddWithValue("@F5", TextBox10.Text)
            cm.Parameters.AddWithValue("@F6", TextBox9.Text)

             cm.ExecuteNonQuery()
            cm.Close()

    El resultado

    Ten presente que deberas especificar el rango de acuerdo a la necesidad yo coloque J200 pero al caso puede ser J20000 tu lo manejas, a si mismo el inicio ve probando por la base 0 y lo que entiende donde empieza la tabla (en vez de A14 creo que es A12) . En el ejemplo la hoja tiene 13 filas por encima de la tabla

    Espero te sirva saludos

    Edito: te dejo el código completo evalúa para el index Dim Num as ingeter = dt.rows.count -1 y al cargar ......=@F1 = Num + 1)

     Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
            Dim path As String = "C:Rurta de tu excel\Libro1.xlsx"
    
            OleConexion = New System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0; " & "data source=" & path & "; Extended Properties= 'Excel 12.0 Xml;HDR=NO'")
            Dim dats As New DataSet
            DatAdapter = New System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " & "[" & "Hoja1$" & "A15:J200" & "]  ", OleConexion)
            Dim Tabla2 As New DataTable
            DatAdapter.Fill(Tabla2)
            Dim num As Integer = Tabla2.Rows.Count - 1
            OleConexion.Open()
            cm.Connection = OleConexion
            cm.Parameters.Clear()
    
            cm.CommandText = "INSERT INTO [Hoja1$]  (F1,F2,F3,F4,F5,F6) VALUES (@F1,@F2,@F3,@F4,@F5,@F6)"
            cm.Parameters.AddWithValue("@F1", num + 1)
            cm.Parameters.AddWithValue("@F2", TextBox3.Text)
            cm.Parameters.AddWithValue("@F3", TextBox5.Text)
            cm.Parameters.AddWithValue("@F4", TextBox6.Text)
            cm.Parameters.AddWithValue("@F5", TextBox10.Text)
            cm.Parameters.AddWithValue("@F6", TextBox9.Text)
    
    
            cm.ExecuteNonQuery()
            OleConexion.Close()
        End Sub




    miércoles, 20 de septiembre de 2017 22:21

Todas las respuestas

  • muchas gracias por responder :

    me supongo que te refieres a esto

    cm.CommandText = "insert into [Hoja1$A14:B14]values ('" & TextBox1.Text & "','" & TextBox2.Text & "')"
            cm.ExecuteNonQuery()

    pero me sale este error cuando le doy click para guardar

    Información adicional: Esta tabla contiene celdas que están fuera del rango de celdas definido en la hoja de cálculo.

    sábado, 16 de septiembre de 2017 0:01
  • Hola Ericks, el tema es que intentas lograr, si no tienes una estructura de tabla en la hoja excel deberas cargar los datos mediante código o ulizar algúna herramienta para el caso, igualmente un listView no es el mejor control para este caso, preferiblemente utilizar DataGridView que te perite editar sin mayores problemas. Por otro lado INSERT INTO, como te decía necesita de una estructura de tabla para insertar un nuevo registro, este registro lo puedes añadir mediante Parametros ej  cm.Parameter.AddWithValue("Campo1", TextBox1:Text) para luego cm.ExecuteNonQuerry()  pero para esto, dado el ejemplo, debe existir la columna "Campo1" y el registro se cargara al final de las filas.  Creo que deberías explicar un poco más lo que deseas para poder ayudarte mejór

    Saludos




    • Editado Marcelo PF domingo, 17 de septiembre de 2017 17:55
    domingo, 17 de septiembre de 2017 6:25
  • lo que necesito es llenar un registro en la misma hoja de excel para eso el codigo de arriba utilize un archivo de excel como base de datos que cada vez que habro el programa me carga lo que ya se ha llenado previamente

    mi problema es al momento de registrar textbox1.text quiero que se almacene a la ceda A:14 por ejemplo y textbox2.text en B:14 (con el codigo de arriba almacena en las primera fila y columna y eso no me ayuda )

    lunes, 18 de septiembre de 2017 17:57
  • Bien, por lo que veo de tu código cargas en un DataTable lo que tienes en el excel, por tal existe la tabla en el, vamos por partes, mi duda, por qué en la fila 14? o debería ser al final de las filas? entiendo cagando nuevos registros en la base de datos (excel) de ser así INSERT INTO debe funcionar ej: supongamos que en el excel tienes tres columnas ID, Campo1, Campo2

    entonces, cm.ComandText = "INSERT INTO [Hoja1$] VALUES (ID, Campo1, Campo2)"

               cm.Parameters.Clear()

               cm.Parameters.AddWhidValue("ID", Textbox1.text)

               cm.Parameters.AddWhidValue("Campo1", Textbox2.text)

                cm.Parameters.AddWhidValue("Campo2", Textbox3.text)

              cm.ExcecuteNonQuery()

              cm.Connection.Close()

    No lo copies tal cual que lo escribí a mano alzada. Ahora bien aquí te cargará un nuevo registro en la hoja excel (al final del los rows) no exactamente en la fila 14. Por otro lado deberías independizar la carga del ListView con esto que es la carga de la base de datos (excel) puedes optar por dos buttons diferentes. La forma en que cargas ListView, a mi entedeer no es la adecuada debería cargarse medieate ListViewItems en este caso funciona por ser solo dos columnas de ser más podrias tener inconvenietes, hay varios ejemplos en el foro

    Lo pruebas y me dices

    Saludos



    • Editado Marcelo PF lunes, 18 de septiembre de 2017 22:25
    lunes, 18 de septiembre de 2017 20:59
  • si me funciono, muchas gracias y si lo que tu decías tengo problemas cuando son mas columnas alguna recomendación por favor muchas gracias por tu ayuda.

    PD. es para llenar un registro de empleados y esta en excel la plantilla pense que deberia solo enlazarlo con la tabla, veo que cuando el excel esta vacio y solo tengo la trabla me funciona el codigio pero cuando esta lleno por mas celdas que estan fuera de la tabla mi codigo no funciona alguna ayuda?

    me sale

    Excepción no controlada del tipo 'System.ArgumentException' en Microsoft.VisualBasic.dll

    Información adicional: La columna 'campo1' no pertenece a la tabla


    • Editado Ericks Effio martes, 19 de septiembre de 2017 19:09
    martes, 19 de septiembre de 2017 17:24
  • Bien, se entiende que lo coloque es un ejemplo verdad? Cuando se hace referencia a "Campo1" en el plano real debería ser el nombre de tu columna en el excel, para tratar de ordenar un poco más la idea, por favor, coloca una imagen de el excel desde la cabecera del mismo, los valores obviamente cambialos, lo que me interesa y su pongo que a los demás es ver la disposición de las oclumnas y cabeceras de ese excel.  En cuanto tengamos más ideas seguramente saldran mejores soluiciones al respecto. Ten presente también que una cosa es cargar datos en un excel mediante comandos otra eliminar, lo comento por si tu proyecto desarrolla en esa dirección.

     Siguiendo con el ejemplo, la disposición del excel para usar como base de datos debe estar en forma de cabezera y columnas y no tener datos por fuera de estas columnas, como en tu código lo cargas en un DataTable supuse que así debería estar.

    Saludos

    miércoles, 20 de septiembre de 2017 2:02
  • Mi estimado muchas gracias por responder como no esta verificada mi cuenta no puedo agregar imagen pero aca te dejo mi link de la imagen,

    como se ve ese es el excel que quiero llenar en donde dice participantes agregar con un programa a dichos participantes por favor espero tu ayuda o en todo caso si hay otra solución para mi porblema

    https://1drv.ms/i/s!AsviN-YXCXlmgzkVc8xSIc_qar1n

    miércoles, 20 de septiembre de 2017 15:09
  • Hola Ericks, bien en primer lugar trata de modificár la hoja para que la parte en que se encuentra la tabla mantenga el orden de las celdas y en el caso modifíaca lo que se encuentra por soble ella de esta manera la carga sera coherente, desconosco si existe alguna forma de utilizar los datos con celdas modificadas (celdas unificadas) por otro lado verifica los tipos de datos, cuando se toman mediant Ado Net, al ingresar los datos en un tatatable este "acomoda" los tipos de acuerdo a lo que va recibiendo, si carga fechas de origen pedirá fechas al cargar. Bueno el tema cuando el excel no tiene un formato definido de tabla, como es tu caso, se debe seleccionar un rango y especificar que DHR= NO lo que significa que no tomara tal cual la tabla, dado esto el valor de los campos cambia, se especifica F1, F2, F3..... Que es el nombre por defecto que tomara la tabla para sus columnas (campos)  y se agrega un seudonimo a el VALOR. Por lo que en tu caso quedaría algo así:

     cn = New System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0; " & "data source=" & path & "; Extended Properties= 'Excel 12.0 Xml;HDR=NO'")

    da = New System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " & "[" & "Hoja1$" & "A15:J200" & "]  ", cn)

    Y luego colocarémos el INSERT para la carga de datos

     cn.CommandText = "INSERT INTO [Hoja1$]  (F1,F2,F3,F4,F5,F6) VALUES (@F1,@F2,@F3,@F4,@F5,@F6)"
            cm.Parameters.AddWithValue("@F1", num + 1)
            cm.Parameters.AddWithValue("@F2", TextBox3.Text)
            cm.Parameters.AddWithValue("@F3", TextBox5.Text)
            cm.Parameters.AddWithValue("@F4", TextBox6.Text)
            cm.Parameters.AddWithValue("@F5", TextBox10.Text)
            cm.Parameters.AddWithValue("@F6", TextBox9.Text)

             cm.ExecuteNonQuery()
            cm.Close()

    El resultado

    Ten presente que deberas especificar el rango de acuerdo a la necesidad yo coloque J200 pero al caso puede ser J20000 tu lo manejas, a si mismo el inicio ve probando por la base 0 y lo que entiende donde empieza la tabla (en vez de A14 creo que es A12) . En el ejemplo la hoja tiene 13 filas por encima de la tabla

    Espero te sirva saludos

    Edito: te dejo el código completo evalúa para el index Dim Num as ingeter = dt.rows.count -1 y al cargar ......=@F1 = Num + 1)

     Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
            Dim path As String = "C:Rurta de tu excel\Libro1.xlsx"
    
            OleConexion = New System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0; " & "data source=" & path & "; Extended Properties= 'Excel 12.0 Xml;HDR=NO'")
            Dim dats As New DataSet
            DatAdapter = New System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " & "[" & "Hoja1$" & "A15:J200" & "]  ", OleConexion)
            Dim Tabla2 As New DataTable
            DatAdapter.Fill(Tabla2)
            Dim num As Integer = Tabla2.Rows.Count - 1
            OleConexion.Open()
            cm.Connection = OleConexion
            cm.Parameters.Clear()
    
            cm.CommandText = "INSERT INTO [Hoja1$]  (F1,F2,F3,F4,F5,F6) VALUES (@F1,@F2,@F3,@F4,@F5,@F6)"
            cm.Parameters.AddWithValue("@F1", num + 1)
            cm.Parameters.AddWithValue("@F2", TextBox3.Text)
            cm.Parameters.AddWithValue("@F3", TextBox5.Text)
            cm.Parameters.AddWithValue("@F4", TextBox6.Text)
            cm.Parameters.AddWithValue("@F5", TextBox10.Text)
            cm.Parameters.AddWithValue("@F6", TextBox9.Text)
    
    
            cm.ExecuteNonQuery()
            OleConexion.Close()
        End Sub




    miércoles, 20 de septiembre de 2017 22:21