Agrupar Datos Linq (GroupBy) C# - VB.Net

martes, 28 de agosto de 2012

Siguiendo con ejemplos de linq ahora veremos como funciona el operador GroupBy.

El operador GroupBy nos permite agrupar una secuencia de datos bajo una clave.

Mas información.
group (Cláusula, Referencia de C#)
Group By (Cláusula, Visual Basic)

En este articulo trataremos los siguientes puntos.
  • Mostrar datos de una lista en ListView.
  • Agrupar datos de una lista tipo clase.
  • Mostrar datos agrupados en ListView.

Veamos el diseño que tendrá nuestra aplicacion.

Diseño


Como pueden observar el form solo cuenta con un listview al cual se le definieron 3 columnas en tiempo de diseño y también se tiene un botón.

Ahora agregamos una clase llamada Persona.
public class Persona
{
   public string Nombre { get; set; }
   public int Edad { get; set; }
   public string Pais { get; set; }
   public Persona(string nom, int ed, string pa)
   {
          Nombre = nom;
          Edad = ed;
          Pais = pa;
   }
} 

Public Class Persona
  Public Property Nombre() As String
  Public Property Edad() As Integer
  Public Property Pais() As String

  Public Sub New(ByVal nom As String, ByVal ed As Integer, ByVal pa As String)
      Nombre = nom
      Edad = ed
      Pais = pa
  End Sub

End Class

Es una simple clase que nos servirá para el manejo de nuestros datos.

Ahora creemos una lista de tipo Persona y agreguemos unos registros.
List<persona> personas = new List<persona>
{
   new Persona("Cristian", 21, "El Salvador"),
   new Persona("Fatima", 19, "Argentina"),
   new Persona("Juan", 25, "El Salvador"),
   new Persona("Maria", 18, "España"),
   new Persona("Javier", 40, "Argentina"),
   new Persona("Rosa", 35, "Mexico"),
   new Persona("Josue", 26, "España"),
   new Persona("Karla", 50, "Mexico")
};

Dim personas As New List(Of Persona)() From {
   New Persona("Cristian", 21, "El Salvador"), _
   New Persona("Fatima", 19, "Argentina"), _
   New Persona("Juan", 25, "El Salvador"), _
   New Persona("Maria", 18, "España"), _
   New Persona("Javier", 40, "Argentina"), _
   New Persona("Rosa", 35, "Mexico"), _
   New Persona("Josue", 26, "España"), _
   New Persona("Karla", 50, "Mexico") _
}

En los registros que hemos agregado pueden notar que algunas personas son del mismo país entonces utilizaremos ese dato para agruparlos por país.

Cargar datos en el ListView(cargamos los datos sin agrupar)

Primero cargaremos los datos así como están sin agrupar en listview.
foreach (var p in personas)
{
   ListViewItem item = new ListViewItem(p.Pais);
   item.SubItems.Add(p.Nombre);
   item.SubItems.Add(p.Edad.ToString());
   listView1.Items.Add(item);
}

For Each p In personas
  Dim item As New ListViewItem(p.Pais)
  item.SubItems.Add(p.Nombre)
  item.SubItems.Add(p.Edad.ToString())
  listView1.Items.Add(item)
Next

Recorremos la lista con un ciclo foreach y dentro vamos agregando los datos al listview.

Agrupar los datos y mostrarlos en el ListView.
Agruparemos los datos por país y de una sola vez los mostraremos agrupados dentro del listview.
var agrupar = personas.GroupBy(persona => persona.Pais);
string group = "";
ListViewGroup g = new ListViewGroup();
listView1.Items.Clear();
foreach (var p in agrupar)
{
    if (p.Key.ToString() != group)
    {
         g = new ListViewGroup(p.Key.ToString());
         group = p.Key.ToString();
         listView1.Groups.Add(g);
    }
    foreach (var persona in p)
    {
         ListViewItem item = new ListViewItem("");
         item.SubItems.Add(persona.Nombre);
         item.SubItems.Add(persona.Edad.ToString());
         item.Group = g;
         listView1.Items.Add(item);
    }
}

Dim agrupar = personas.GroupBy(Function(persona) persona.Pais)
Dim group As String = ""
Dim g As New ListViewGroup()
listView1.Items.Clear()
For Each p In agrupar
  If p.Key.ToString() <> group Then
       g = New ListViewGroup(p.Key.ToString())
       group = p.Key.ToString()
       listView1.Groups.Add(g)
  End If
  For Each persona In p
      Dim item As New ListViewItem("")
      item.SubItems.Add(persona.Nombre)
      item.SubItems.Add(persona.Edad.ToString())
      item.Group = g
      listView1.Items.Add(item)
  Next
Next

Lo primero que hacemos es agrupar los datos haciendo uso de linq agrupamos los datos por país, luego declaramos una variable string vacía y también se crea un objeto ListViewGroup esto nos servirá para poder mostrar los datos agrupados en el listview, luego recorremos el resultado de nuestra consulta linq y vamos agregando los datos ya agrupados en el listview.

Datos sin agrupar


Datos agrupados


Eso es todo espero les sirva mucho saludos desde El Salvador...

Descargar Proyecto C#

Descargar Proyecto VB.Net


No olvides suscribirte al blog para estar pendientes de mis últimos artículos.

Mejorar Diseño de Formulario Asp.Net con jqTransform

domingo, 19 de agosto de 2012

Siempre que se desarrollan aplicaciones web el diseño es una parte muy importante y siempre se busca una manera rápida y fácil de darle un bonito diseño a nuestras aplicaciones pues hay buenas noticias ya que con jqTransform un plugin de jquery podemos aplicar un bonito diseño a nuestros formularios asp.net de una forma fácil y rápida.

Primeramente veamos el diseño normal del formulario.

Diseño


Pueden notar que es un simple formulario al que hemos agregado algunos controles.

Ahora cambiaremos el diseño de los controles que hemos agregado usando el plugin jqTransform.




Lo que se hace es hacer referencia a la hoja de estilo que el plugin trae y también necesitamos hacer referencia a jquery y al plugin jqTransform, y en el código jquery lo único que hacemos es aplicar el estilo a todos los controles que estén dentro del formulario.

Ahora lo único que tenemos que hacer es dentro del código del formulario que queramos cambiar el diseño agregamos la clase del plugin jqTransform.

Eso seria todo con estas simples lineas de código estaríamos cambiando el diseño simple de nuestro formulario.

Captura


Captura


Eso seria todo espero les sirva de algo les dejo la descarga del ejemplo ya incluye el plugin jqTransform.

Descargar Ejemplo

Sumar Columnas DataGridView usando Linq

martes, 14 de agosto de 2012

Cuando usamos el control DataGridView muchas veces necesitamos realizar operaciones sobre las filas o columnas del control, ahora veremos la manera de como realizar la suma de una columna del datagriedview usando linq.

El ejemplo esta desarrollado en visual estudio 2010 con los lenguajes c# y vb.net.

El ejemplo es sencillo y usare un datatable que lleno manualmente para el origen de datos, en un ejemplo real este datatable se llenaría con datos de una base de datos.

El diseño de la aplicacion es el siguiente.

Diseño

Ahora veamos la manera como llenamos el datatable con los datos que usaremos.
        private DataTable Datos()
{
DataTable dt = new DataTable();
dt.Columns.Add("Id");
dt.Columns.Add("Producto");
dt.Columns.Add("Total");

DataRow row = dt.NewRow();
row["Id"] = 1;
row["Producto"] = "Arroz";
row["Total"] = 50.00;
dt.Rows.Add(row);

row = dt.NewRow();
row["Id"] = 2;
row["Producto"] = "Pollo";
row["Total"] = 75.25;
dt.Rows.Add(row);

row = dt.NewRow();
row["Id"] = 3;
row["Producto"] = "Frijoles";
row["Total"] = 60.25;
dt.Rows.Add(row);

row = dt.NewRow();
row["Id"] = 4;
row["Producto"] = "Leche";
row["Total"] = 45.25;
dt.Rows.Add(row);

return dt;
}

    Private Function Datos() As DataTable
Dim dt As New DataTable()
dt.Columns.Add("Id")
dt.Columns.Add("Producto")
dt.Columns.Add("Total")

Dim row As DataRow = dt.NewRow()
row("Id") = 1
row("Producto") = "Arroz"
row("Total") = 50.0
dt.Rows.Add(row)

row = dt.NewRow()
row("Id") = 2
row("Producto") = "Pollo"
row("Total") = 75.25
dt.Rows.Add(row)

row = dt.NewRow()
row("Id") = 3
row("Producto") = "Frijoles"
row("Total") = 60.25
dt.Rows.Add(row)

row = dt.NewRow()
row("Id") = 4
row("Producto") = "Leche"
row("Total") = 45.25
dt.Rows.Add(row)

Return dt
End Function

Es un método de tipo datatable que retornara todos los datos en este caso como ya lo dije agrego los datos manualmente en caso de usar una base de datos lo único que cambiaría seria la manera de como se llena el datatable.

Ahora en el evento load del formulario cargamos los datos en el datagriedview y agregamos una nueva fila al datatable.
        private void Form1_Load(object sender, EventArgs e)
{
//agregamos una nueva fila al datatable
DataTable dt = Datos();
DataRow row= dt.NewRow();
dt.Rows.Add(row);

//mostramos los datos en el datagriedview
dataGridView1.AutoGenerateColumns = false;
dataGridView1.DataSource = dt;

//Mostramos el valor de 0 en la fila que agregamos
DataGridViewRow rowtotal = dataGridView1.Rows[dataGridView1.Rows.Count - 1];
rowtotal.Cells["Total"].Value = 0;

}

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'agregamos una nueva fila al datatable
Dim dt As DataTable = Datos()
Dim row As DataRow = dt.NewRow()
dt.Rows.Add(row)

'mostramos los datos en el datagriedview
dataGridView1.AutoGenerateColumns = False
dataGridView1.DataSource = dt

'mostramos el valor de 0 en la fila que agregamos
Dim rowtotal As DataGridViewRow = dataGridView1.Rows(dataGridView1.Rows.Count - 1)
rowtotal.Cells("Total").Value = 0
End Sub

Lo primero que hacemos es agregar una nueva fila al datatable que nos servirá para mostrar el total de la suma de la columna, luego cargamos los datos en el datagriedview y por ultimo le asignamos el valor de 0 a la fila que agregamos para calcular la suma.

Lo ultimo que nos queda por hacer es calcular la suma de la columna del datagriedview que en este caso sera la columna Total y mostrar el resultado.
       private void btntotal_Click(object sender, EventArgs e)
{
//hacemos la suma de la columna total
double resul = dataGridView1.Rows.Cast<DataGridViewRow>().Sum(x => Convert.ToDouble(x.Cells["Total"].Value));

//mostramos la suma en el textbox y en la fila que agregamos
txttotal.Text = Convert.ToString(resul);
DataGridViewRow rowtotal = dataGridView1.Rows[dataGridView1.Rows.Count - 1];
rowtotal.Cells["Total"].Value = resul;
}

    Private Sub btntotal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btntotal.Click
'hacemos la suma de la columna Total
Dim resul As Double = dataGridView1.Rows.Cast(Of DataGridViewRow)().Sum(Function(x) Convert.ToDouble(x.Cells("Total").Value))

'mostramos la suma en el textbox y en la fila que agregamos
txttotal.Text = Convert.ToString(resul)
Dim rowtotal As DataGridViewRow = dataGridView1.Rows(dataGridView1.Rows.Count - 1)
rowtotal.Cells("Total").Value = resul
End Sub

Como pueden observar si se hace uso de linq se puede obtener la suma de la columna del datagriedview en una sola linea de codigo sin necesidad de recorrer el datagriedview, luego que se obtiene el resultado lo único que se hace es mostrarlo en el textbox y en la fila adicional que agregamos.

Captura

Eso es todo espero les sirva mucho saludos desde El Salvador...

Descargar Proyecto C#

Descargar Proyecto VB.Net


No olvides suscribirte al blog para estar pendientes de mis últimos artículos.