none
Leer excel con columnas dinámica RRS feed

  • Pregunta

  • Buenos días

    Tengo que leer de un excel. Me dicen que la primera fila es la cabecera y está ocupa 6 columnas.

    Pero que las filas siguientes pueden tener 6 columnas o más pero siempre en grupos de dos es decir. Que si tiene más de 6 puede ser 8 o 10 o 12 o +, pero nunca un número impar. Donde esa columna si contiene datos jamas será un null o vacio o espacios en blanco.

    Y que cuando la columna que está en una posición mayor o igual que la sexta columna si la siguiente esta vacía acaba ese registro.

    O muestro un ejemplo de como podría llegar a ser

    C.Facturación

    C.Coste / detallable

    IdUdOrganica

    DescMinisterio

    Descripcion

    IdUdOrganica

    Descripcion

    CodigoCliente

    DescEmpresa

    CodigoClienteEmpresa

    DescEmpresa

    CodigoClienteEmpresa

    DescEmpresa

    CodigoClienteEmpresa

    a

    a

    a

    a

    a

    a

    a

    a

    a

    a

    b

    b

    b

    b

    b

    b

    b

    b

    b

    b

    b

    b

    c

    c

    c

    c

    c

    c

    c

    c

    d

    d

    d

    d

    d

    d

    e

    e

    e

    e

    e

    e

    e

    e

    e

    e

    Hasta ahora lo que estaba eran solo las 6 primeras columnas y conseguía la información con el siguiente código:

    var centro = from c in excelCenFase.Worksheet(woksheetName)
        select new ExcelCentro()
        {
            campo1= c[0],
            campo2= c[1],
            campo3= c[2],
            campo4= c[3],
            campo5= c[4],
            campo6= c[5],
            campo7= string.IsNullOrWhiteSpace(c[2]) ? 2 : 1
        };

    Pero la verdad es que no se como hacerlo, ya que varía del registro puede tener solo 6 campos o 1000 

    El Objeto ExcelCentro tiene una propiedad que está configurada en el class del siguiente modo

        [DataMember]
        public List<NuevoObjeto> ListadoNuevoObjeto{ get; set; }
        public ExcelCentro()
        {
            ListadoNuevoObjeto = new List<NuevoObjeto>();
        }
    }//Aquí acaba el class de ExcelCentro
    [DataContract]
    [Serializable()]
    public class NuevoObjeto
    {
        [DataMember]
        public string DescEmpresa { get; set; }
        [DataMember]
        public string CodigoClienteEmpresa { get; set; }
    
        public NuevoObjeto(string descEmpresa, string codigoClienteEmpresa)
        {
            DescEmpresa = descEmpresa;
            CodigoClienteEmpresa = codigoClienteEmpresa;
        }
    }

    Pero ¿cómo hago para rellenar la propiedad ListadoNuevoObjeto? porque no veo el modo de indicar que si c[6]y c[7] distinto de vacio, null o lleno de espacios ListadoNuevoObjeto.Add(c[6], c[7]) y si un vez se ha ingresado esos c[8] y c[9] lo mismo y así sucesivamente.

    Alguien me puede explicar o mostrar como hacerlo.

    Muchas gracias.

    jueves, 14 de noviembre de 2019 14:07

Respuestas

Todas las respuestas

  • Solo faltó que te pusieran vidrio molido en el teclado para hacerla un poco más penoso....Bueno mi respuesta no condice con tu tecnología ya que ocupo OleDB pero te puede dar una mano, al menos eso espero. El tema es tratar a el Excel como una base de dato y aunque no tenga el formato adecuado, pues lo forzamos a que sí. Las limitaciones dependerán de tu necesidad ya que este método elimina las cabeceras transformándolas por defecto en F2 F2 ..etc. Y hay que poner una longitud de búsqueda, en el ejemplo busca desde "A3:HNC2000" esto da un rango de 5500 columnas por 2000 filas, no interesa si cólicas más valores al rango, mediante DataTable solo toma las que tengan valor como columna o sea se "fitrará" sola, Si quieres que se vean los nombres de las columnas pues el rango comienza en "A2" pero esto hará que el nombre de las columnas sean parte de las filas (prueba y me entenderás). Para el caso de las columnas que estén vacías utilizamos, una vez cargada DataTable, el método Compute("Count(....) esto nos sumará las celdas ocupadas si el valor devuelto es "0" entonces borramos la columna antes de procesarla (en el ejemplo cargando  los datos en un DGV) bueno allí vamos

      private void button21_Click(object sender, EventArgs e)
            {
                string file =  @"C:\Users\DireccionExcel\Dinamico.xlsx";
                System.Data.OleDb.OleDbCommand Olecm = new System.Data.OleDb.OleDbCommand();
                OleConexion = new System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0; " + "data source=" + file + "; Extended Properties='Excel 12.0 Xml;HDR=NO'");
                DataTable Tabla = new DataTable();
                //Como está el código toma el valor de las columnas por defecto, por tal estas se llamaran F1 F2 F3 .... si deseas que se lean los nombres de las columnas deberas tomar el valor desde A2...y estas apareceran como primera fila de la DataTable
                System.Data.OleDb.OleDbDataAdapter OleAdapter = new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " + "[" + "Hoja1$" + "A3:HCN2000" + "]  ", OleConexion);
                OleConexion.Open();
                Olecm.Connection = OleConexion;
                OleAdapter.Fill(Tabla);
                List<String> Lista = new List<string>();
                foreach (DataColumn col in Tabla.Columns)
                {
                 var Datos =   Tabla.Compute("Count(" + col.ColumnName +")",String.Empty);
                  
                    if (Convert.ToString(Datos) == "0")//si quieres que las columnas tomen su valor como la fila 1 entonces el valor para eliminar será 1
                        {
                        Lista.Add(col.ColumnName);
                        }
                }
                foreach (string Lis in Lista)
                {
                    Tabla.Columns.Remove(Lis);
    
                }
                Dgw.Columns.Clear();
                Dgw.DataSource = Tabla;
    
    
            }


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗ pfannkuche2000@yahoo.com.ar



    • Editado Marcelo PF jueves, 14 de noviembre de 2019 19:38
    • Propuesto como respuesta Pablo RubioModerator jueves, 14 de noviembre de 2019 20:33
    • Votado como útil Dudando MH miércoles, 27 de noviembre de 2019 11:42
    jueves, 14 de noviembre de 2019 19:33
  • Buff, te agradezco que me indiques este sistema, pero no he visto el modo de aplicarlo en base a lo que me refería. Es decir archivo dinámico, donde no se me indica el tamaño de las columnas y que como mínimo a 6 en una fila y como máximo el máximo. Y el como voy rellenando el objeto el cual a partir de la columna 6 la 7 y 8 etc son el objeto que definí.

    Saludos.

    lunes, 25 de noviembre de 2019 15:05
  • Claro, tal vez nos falte más información, como por ejemplo cual es el destino de los valores que recolectas, dado que  el destino no debe ser una base de datos ya que, como indicas las columnas varían y esto haría imposible rellenar un destino sin que se carguen en sus respectivos campos. El ejemplo dado alimenta un dataTable con todos los valores que tenga el Excel, con el formato que indicas en el ejemplo,  ya sea el minimo de 6  o  1000 columnas, todos los datos que se encuentren en el excel quedarán cargados a un tataTable de allí habría que ver cual es su tratamiento. Tal vez se desarrollas más lo que se requiere tengamos más claro el panorama, como está el ejemplo todos los datos estan almacenados en la table  de allí en adelante habria que ver como sigue y si sirve el método. No veo la manera, según la tecnología que indicas, de lograr lo que buscas.

    Saludos y lo seguimos viendo


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗

    lunes, 25 de noviembre de 2019 16:44
  • Lo puse en la parte de arriba

    esas columnas que oscilan en si es un listado de un tipo de objeto, que está defnido. este listado se asocia evidentemente a cada fila en exclusiva, por tanto como tiene la misma estructura es decir o tiene 2 columnas o no las tiene y va siempre en pack de dos pues esta claro que el contenido de cada fila se íra luego, a otro sitio, pero mi problema es rellenar el listado, que es lo que pregunté.

    Ya sé que no es una estructura tabla típica, si fuera así, no hubiera preguntado eso sino otras cosas, que ahora mismo no tiene lugar.

    martes, 26 de noviembre de 2019 11:50
  • Pues mil disculpas Dudado, pero sigo sin entender, y al juzgar por la falta de respuesta de los demás colaboradores supongo que están en la misma duda, te propongo que efectues una nueva pregunta y en lo posible agrega más datos.

    Saludos


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗


    • Editado Marcelo PF martes, 26 de noviembre de 2019 17:22
    martes, 26 de noviembre de 2019 17:22
  • Buenas, no hace falta ya lo he solucionado con EPPLUS y con LinToExcel

    Saludos.

    • Marcado como respuesta Dudando MH miércoles, 27 de noviembre de 2019 11:42
    miércoles, 27 de noviembre de 2019 11:41