jueves, 18 de diciembre de 2014

Cómo Hacer un Group By de Objetos usando Linq

En éste artículo veremos como crear un group by usando linq en vb.net.

Para este ejemplo usaremos la función agruparDatos que recibe por parámetro un DataTable, ya que para este ejemplo usaremos un DataTable


Public Function agruparDatos(ByVal dt As DataTable) As DataTable
        //Declaramos nuestro objeto linq donde en este caso sera un grupo por el campo Fecha
       //y los campos en el select hacemos un sum,avg,max para hacer los calculos

        Dim obj =
                   From row
                   In dt
                   Group row By Fecha = row.Field(Of Date)("Fecha")
        Into Merma = Group
                Select New With
                  {
                      Key Fecha,

                        .Monto= Merma.Sum(Function(r) r.Field(Of Integer)("Monto")),
                        .SubTotal= Merma.Sum(Function(r) r.Field(Of Decimal)("SubTotal")),
                        .Total= Merma.Sum(Function(r) r.Field(Of Integer)("Total")),

                        .Cantidad= Merma.Sum(Function(r) r.Field(Of Decimal)("Cantidad")),
                        .Diferencia= Merma.Sum(Function(r) r.Field(Of Decimal)("Diferencia")),
                        .Porcentaje= Merma.Max(Function(r) r.Field(Of Decimal)("Porcentaje")),
                        .Promedio= Merma.Avg(Function(r) r.Field(Of Decimal)("Promedio"))
                        }

        //Declaramos nuestro nuevo dt y colonamos la estructura del dt del parámetro
        Dim dt2 As DataTable = dt.Clone
       
       //Recorremos el objeto e insertamos las filas al nuevo dt
        For i = 0 To obj.Count - 1
            Dim dr As DataRow = dt2.NewRow
            dr("ID") = i + 1
            dr("Fecha") = obj(i).Fecha
            dr("Monto") = obj(i).Monto
            dr("SubTotal") = obj(i).SubTotal
            dr("Total") = obj(i).Total
            dr("Cantidad") = obj(i).Cantidad
            dr("Diferencia") = Math.Abs(obj(i).Diferencia)
            dr("Porcentaje") = obj(i).Porcentaje
            dr("Promedio") = obj(i).Promedio
            dr("Calculado") = ((dr("Monto") - dr("Diferencia")) / dr("Total")) * 100


        Next

       //actualizamos el nuevo dt para que se guarden las nuevas filas agregadas
        dt2.AcceptChanges()

       
        Return dt2
    End Function

viernes, 27 de septiembre de 2013

Creando controles dinamicos en el HeaderTemplate del AspxGridView Error Failed to load ViewState

Cuando creamos columnas dinámicas y agregamos HeaderTemplate de esta manera:

 Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        enlazarGrid()

 End Sub

Private Sub enlazarGrid()
            crearControles()
            _objFunciones.cargarGridView(grdGridView, "Id", _dataSource)

 End Sub

  Sub crearControles()
            grdGridView.Columns.Clear()
            grdGridView.TotalSummary.Clear()

            Dim itemTemplate As New GridViewTemplate()

            agregarCommanColumn()
            grdPlanPagos.Columns(0).HeaderTemplate = itemTemplate
End Sub

  Sub agregarCommanColumn()
        If grdGridView.Columns.IndexOf(grdPlanPagos.Columns("CommandColumn")) <> -1 Then
            Return
        End If

        Dim col As New GridViewCommandColumn()
        col.Name = "CommandColumn"
        col.ShowSelectCheckbox = False
        col.VisibleIndex = 0
        col.ButtonType = ButtonType.Image
        col.DeleteButton.Image.Url = "~/images/Menos.png"
        col.DeleteButton.Visible = True
        col.DeleteButton.Image.ToolTip = "Eliminar"
        grdGridView.Columns.Add(col)

    End Sub

Public Class GridViewTemplate

    Implements ITemplate

 Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn
container.Controls.Add(agregarImagenNuevo("cingrdClientInstanceName"))

 End Sub

 Private Function agregarImagenNuevo(ByVal strNombreInstanciaGrid As String) As ASPxImage
        Dim imgAgregar As New ASPxImage
        With imgAgregar
            .ID = "imgAgregar"
            .ToolTip = "Nuevo"
            .ImageUrl = "~/images/Mas.png"
            .ClientSideEvents.Click = "function(s, e) {" & strNombreInstanciaGrid & ".PerformCallback('Agregar');}"
        End With
        Return imgAgregar

    End Function
End Class

Corriendo la pagina web ser veria de esta manera:


Pero al dar clic en el botón + hay un PerformCallback() y se muesta la siguiente pantalla:

Para solucionar este error lo único que tenemos que hacer es agregar las siguientes propiedades al GridView:

<dx:ASPxGridView EnableRowsCache="false" EnableViewState="false" ... >

</dx:ASPxGridView>


miércoles, 25 de septiembre de 2013

Usando CTE para Sumas Acumulativas SQL SERVER

WITH CTE
AS

(SELECT TOP 1 ROW_NUMBER() OVER(ORDER BY T.IdTransaccion ASC) AS Rn, 
        T.IdTransaccion,T.IdSolicitud,CONVERT(FLOAT,T.Monto)Monto , CONVERT(FLOAT,T.Monto) AS running_sum 
 FROM Prestamo.Transacciones T WHERE t.IdSolicitud=4

UNION ALL

SELECT A.Rn,A.IdTransaccion,A.IdSolicitud,A.Monto,A.Monto + CONVERT(FLOAT,T.running_sum)  running_sum  
FROM (SELECT ROW_NUMBER() OVER(ORDER BY T2.IdTransaccion ASC) AS Rn, T2.IdTransaccion,T2.IdSolicitud,CONVERT(FLOAT,T2.Monto) Monto ,T2.Monto R
          FROM dbo.Transacciones T2 
          WHERE  t2.IdSolicitud=4) A
     INNER JOIN CTE T ON T.Rn +1=A.Rn AND A.Rn>1 
)

SELECT * FROM CTE
ORDER BY RN
OPTION (maxrecursion 0)



domingo, 22 de septiembre de 2013

Usando EntityFramework en Tres Capas

En la Capa de Acceso a Datos



En la Capa de Negocio

Imports DAL 
Imports System.Data.SqlClient

Public Class Producto

    Dim _objEntitidades As New EjemploEntities() 
    Dim _objProducto As New DAL.Producto 
    Dim _objConexion As New DAL.Conexion

    Public Sub GuardarProducto(ByVal strNombreProducto As StringByVal intExistencia As IntegerByVal dblPrecio As Double)
        _objProducto.Nombre = strNombreProducto
        _objProducto.Existencia = intExistencia
        _objProducto.Precio = dblPrecio 
        _objEntitidades.Productoes.Add(_objProducto) 
        _objEntitidades.SaveChanges()
    End Sub

    Public Function CargarProducto() As IList(Of DAL.Producto)
           Return _objEntitidades.Productoes.ToList 
    End Function

    Public Sub ActualizarProducto(ByVal intIdProducto As IntegerByVal  strNombreProducto As StringByVal intExistencia As IntegerByVal dblPrecio As Double
        Using _objEntitidades

            Dim producto = (From p In _objEntitidades.Productoes Where p.IdProducto = intIdProducto).SingleOrDefault()

            producto.Nombre = strNombreProducto
            producto.Existencia = intExistencia 
            producto.Precio = dblPrecio
            _objEntitidades.SaveChanges() 
        End Using 
    End Sub
End Class


En la Capa de Presentación

Imports BLL 

Partial Class Formularios_wfProducto
        Inherits System.Web.UI.Page


    Dim _objProducto As New Producto
    
    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        If Not IsPostBack Then
           Dim dt As Data.DataTable = _objProducto.CargarProducto()
           grdReja.DataSource = dt grdReja.DataBind() 'Cargando Un GridView  
         End If 
    End Sub  

   Protected Sub btnGuardar_Click(sender As Object, e As EventArgs) Handles btnGuardar.Click 
      _objProducto.GuardarProducto(txtNombre.Text, CInt(txtExistencia.Text), CDbl(txtPrecio.Text))
   End Sub
End Class

viernes, 20 de septiembre de 2013

Creando un ABC con ADO.NET con Tres Capas


En la Capa de Acceso a Datos

Imports System.Data.SqlClient
Public Class Conexion
 Dim objConexion As New SqlConnection(Configuration.ConfigurationManager.ConnectionStrings("connectionString").ConnectionString)

 Public Function ObtenerDatos(ByVal strConsulta As String) As DataTable 
  Dim dt As New DataTable 
  Dim da As New SqlDataAdapter(strConsulta, objConexion) 
  Dim ds As New DataSet 
  objConexion.Open() 
  da.Fill(ds) 
  objConexion.Close() 
   dt = ds.Tables(0) 
   Return dt 
 End Function

 Public Sub RealizarComando(ByVal strConsulta As String
   Dim objComando As New SqlCommand(strConsulta, objConexion)
   Dim iResultado As Integer 
   objConexion.Open() ' abrir conexión 
   iResultado = objComando.ExecuteNonQuery() ' ejecutar comando 
   objConexion.Close() ' cerrar conexión 
 End Sub

End Class

En la Capa de Negocios

Public Class Producto

Protected strNombreProducto As String 
Protected intExistencia As Integer 
Protected dblPrecio As Double

Public Property NombreProducto() As String 
   Get Return (strNombreProducto) 
End Get 
Set(ByVal Value As String) 
   strNombreProducto = Value 
End Set 
End Property

Public Property Existencia() As String 
   Get Return (intExistencia) 
End Get 
Set(ByVal Value As String) 
   intExistencia = Value 
End Set 
End Property

Public Property Precio() As String 
   Get Return (dblPrecio) 
End Get 
Set(ByVal Value As String) 
   dblPrecio= Value 
End Set 
End Property

End Class


En la Capa de Presentación

Imports BLL

Partial Class Formularios_wfProducto
        Inherits System.Web.UI.Page

Dim _objProducto As New Producto 
Dim _objConexion As New DAL.Conexion

Private Sub GuardarProducto()
    Dim strConsulta As String = Nothing
    
    _objProducto.NombreProducto = txtNombre.Text 
    _objProducto.Existencia = CInt(txtExistencia.Text)
    _objProducto.Precio = CDbl(txtPrecio.Text)

    With _objProducto 
          strConsulta = String.Format("EXEC SpInsertarProducto '{0}',{1},{2}", .NombreProducto, .Existencia, .Precio) 
    End With
   _objConexion.RealizarComando(strConsulta)
End Sub

Private Sub CargarProducto() 
   Dim dt As Data.DataTable = _objConexion.ObtenerDatos("SELECT * FROM Producto"
   grdReja.DataSource = dt 
   grdReja.DataBind() 
End Sub

End Class