miércoles, 2 de diciembre de 2009

[ADO.NET] Excel y Linq (Union)

 

Introducción

El objetivo del articulo es demostrar como poder procesar distintos documentos Excel mediante la utilización del provider para Excel de ADO.NET, a su vez las limitaciones de esta tecnología es superada por la potencia de Linq, el cual otorga poder de procesamiento una vez que se tiene la información recuperada de los documentos y se necesita trabajar con los datos.

La idea del ejemplo es poder mostrar una lista de pedidos, informando el numero y cantidad de ítems solicitados. Pero se debe consolidar la lista agrupando y sumando aquellos numero de pedidos se aparezcan en ambos listados.

Lectura de los documentos Excel
DataTable dtExcel1 = new DataTable();
DataTable dtExcel2 = new DataTable();

using (OleDbConnection cnn = new OleDbConnection(ConfigurationManager.ConnectionStrings["Excel1"].ToString()))
{
    string sql = @"SELECT pedido, 
                          cantidad 
                    FROM [Sheet1$]";

    OleDbCommand command = new OleDbCommand(sql, cnn);

    OleDbDataAdapter da = new OleDbDataAdapter(command);

    
    da.Fill(dtExcel1);

}

using (OleDbConnection cnn = new OleDbConnection(ConfigurationManager.ConnectionStrings["Excel2"].ToString()))
{
    string sql = @"SELECT pedido, 
                          cantidad 
                    FROM [Sheet1$]";

    OleDbCommand command = new OleDbCommand(sql, cnn);

    OleDbDataAdapter da = new OleDbDataAdapter(command);


    da.Fill(dtExcel2);

}

Si se analiza el Excel utilizado en le procesamiento se vera que este cuanta con dos columnas pero en el primer registro de cada una se ha escrito el nombre que se asigna a cada una de ellas, estos nombres coinciden con los utilizados en la consulta sql que será ejecutada.

Para este trabajo se hacen uso de dos dataset los cuales contendrán la información proveniente de cada Excel por separado, que en el próximo paso será usada para trabarla y poder adecuarla a la información que se necesita visualizar.

Uso de Linq para unir la información
var query = from item in
                 (from item in dtExcel1.AsEnumerable()
                  select item).Union(from item in dtExcel2.AsEnumerable()
                                     select item)
             group item by Convert.ToInt32(item["pedido"]) into g
             select new
             {
                 Pedido = g.Key,
                 Cantidad = g.Sum(x=>Convert.ToInt32(x["cantidad"]))
             };

La consulta linq realiza varias operaciones para poder adecuar la información proveniente del Excel y que en este punto se encuentra contendida en cada dataset.

El primer paso que realiza es la unión de los dos dataset, o sea la información de los Excel, unificando en un solo grupo de datos los pedidos de ambas listas.

El segundo paso es la realización del Group by, el cual permitirá unir números de pedidos que se encuentren repetidos en ambos listados.

Por ultimo crea un nueva entidad anónima, es por ellos que utiliza el “select new”, en donde define de forma dinámica las propiedades y si contenido.

En este caso solo son dos las propiedades necesarias, el valor Key del objeto que actuó como agrupador y el cual contiene la lista de ítems sin repetir del listado. Y la suma de la cantidad reportada de cada ítem agrupado.

 

[C#]
 

5 comentarios:

  1. Hola Leandro me llama mucho la atención de lo que expones el problema que tengo es que lo quiero hacer en vb.net y al transformar el código tengo problemas en la consulta linq los convertidores de lenguaje no lo traducen bien puedes orientarme por favor o si pudieras colocar este mismo ejemplo pero en vb.net que funcione. De ante mano gracias

    ResponderEliminar
  2. hola Wladimir

    en que parte del linq te falla ?

    porque ahora que lo analizo quizas hasta se pdria reducir el linq

    porque se podria aplciar el Union directo sobre el AsEnumerable()
    quedando

    From item In (dtExcel1.AsEnumerable().Union(dtExcel2.AsEnumerable())) ...

    asi se evitaria usas dos subqueries de linq

    saludos

    ResponderEliminar
  3. Hola leandro otra vez preguntando,, tengo un problema actualmente exportaba a excel creandio el objecto ("excel.application), el problemas que desinstale office e instale un openoffice,, y no funciono el exportar. alguna idea de como hacerlo funcionar ya sea cuando tenga el office, openoficcem kingoffice?

    ResponderEliminar
  4. hola germanRive

    me temo que requieres de office instalado para poder usar las api que permiten crear un excel desde codigo, con openoffice no va a funciona

    sino la otra es usar open xml, como ser
    https://closedxml.codeplex.com/
    para poder exportar sin necesidad de office, pero esto solo crea .xslx o sea office 2007 o superior

    saludos

    ResponderEliminar