10.08.2010

Haciendo Sumatorias con Listas de Entidades con VB.NET

Una de las tantas excelentes funcionalidades que tienen las listas genéricas en .NET es la capacidad de hacer sumatorias basado en un predicado que se le pasa al método Sum como parámetro. Este predicado es una expresión lambda. En este post vamos a crear un par de entidades {proyecto y tarea} y vamos a proceder a crear una sumatoria en base a la relación entre estas entidades. Este post voy a desarrollarlo en VB.NET con el fin de no obligar a todos los que no programan en C# a buscar programas de traducción de código entre VB.NET y C# tal como este.

En primer lugar, vamos a crear una clase { poco – entidad } que me permita manejar cada una de las tareas de un proyecto.

Public Class Tarea
Public Property Id As Integer
Public Property
Nombre As String
Public Property
FechaInicio As DateTime
Public Property FechaFinal As DateTime

Public Sub New(ByVal pId As Integer, ByVal pNombre As String, ByVal pFechaInicio As DateTime, ByVal pFechaFinal As DateTime)
Id = pId
Nombre = pNombre
FechaInicio = pFechaInicio
FechaFinal = pFechaFinal
End Sub

Public Function
TotalHoras() As Double
Return
FechaFinal.Subtract(FechaInicio).TotalHours
End Function

End Class


En esta clase además de las propiedades – automáticas – y el constructor de la clase tenemos un método que calcula el total de horas de la tarea basado en la fecha de inicio de la tarea y la fecha final {la resta entre ambos}. La siguiente clase es la que encapsula todo el estado del proyecto.



Public Class Proyecto
Public Property Id As Integer
Public Property
Nombre As String
Public Property
FechaInicio As DateTime
Public Property FechaFinal As DateTime

Public Property TareasDelProyecto As New List(Of Tarea)

Public Sub New(ByVal pId As Integer, ByVal pNombre As String, ByVal pFechaInicio As DateTime, ByVal pFechaFinal As DateTime)
Id = pId
Nombre = pNombre
FechaInicio = pFechaInicio
FechaFinal = pFechaFinal
End Sub

End Class


En esta clase tenemos una lista de tareas, las cuales son las que al final vamos a utilizar para realizar la sumatoria a través de la clase List(of T).  Seguidamente vamos a hacer un método que nos permite crear una lista de tareas dummy para utilizarla en el proyecto.



Public Class GeneradorDeDatos
'Generar Tareas
Public Shared Function GenerarTareas() As List(Of Tarea)
Dim m_Lista As New List(Of Tarea)

Dim m_Tarea1 As New Tarea(1, "Entrevistar Usuarios", DateTime.Now, DateTime.Now.AddHours(4))
Dim m_Tarea2 As New Tarea(2, "Tabular Requerimientos", m_Tarea1.FechaFinal, m_Tarea1.FechaFinal.AddHours(4))
Dim m_Tarea3 As New Tarea(3, "Priorizar Requerimientos", m_Tarea2.FechaFinal, m_Tarea2.FechaFinal.AddHours(4))
Dim m_Tarea4 As New Tarea(4, "Filtrar Requerimientos", m_Tarea3.FechaFinal, m_Tarea3.FechaFinal.AddHours(4))

m_Lista.Add(m_Tarea1)
m_Lista.Add(m_Tarea2)
m_Lista.Add(m_Tarea3)
m_Lista.Add(m_Tarea4)

Return m_Lista
End Function
End Class


En este caso estamos utilizando el método AddHours para establecer el tiempo de cada tarea. En este proyecto en específico todas las tareas son secuenciales, es decir una tarea inicia hasta que la precede termine. Para mostrar las tareas del proyecto y para calcular el total de horas que dura el proyecto vamos a crear una pantalla igual a esta.



image



En el evento Load de la forma vamos a agregar el código necesario para poder desplegar las tareas en el grid y para poner el total de horas del proyecto en el text box de total de horas.



Public Class Form1

Property ProyectoActual As Proyecto

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ProyectoActual = New Proyecto(1, "Desarrollo de Sistema X", DateTime.Now, DateTime.Now) 'No conocemos la fecha final, no hemos agregado las tareas
ProyectoActual.TareasDelProyecto.AddRange(GeneradorDeDatos.GenerarTareas())
dgProductos.DataSource = ProyectoActual.TareasDelProyecto

'Generar el total de horas del proyecto
Dim m_TotalHoras As Double = ProyectoActual.TareasDelProyecto.Sum(Function(t As Tarea) t.TotalHoras)

txtTotales.Text = m_TotalHoras.ToString()
End Sub
End Class



Como podemos ver en la línea con negrita, estamos usando la función sum de la lista de T. Esta función recibe como parámetro un predicado el cual se va a ejecutar. En este caso no vamos a aplicar ninguna operación en la expresión lambda, pero perfectamente podríamos hacerlo. El resultado de ejecutar la forma es el siguiente.



image



Technorati Tags: ,

1 comentario:

Ronald_88 dijo...

Buen Ejemplo.

Fuente de datos Personalizados.

Para manejar los tipos de datos de cada campo.

al tener la lista con Linq se puede hacer de todo.