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


miércoles, 4 de septiembre de 2013

Exportar a Excel un Grid o PivotGrid con valores calculados desde vb.net


Para solucionar el problema de exportar valores calculados en el GridView desde Código Vb.Net se soluciona de la Siguiente manera:

Protected Sub ASPxPivotGridExporter_CustomExportCell(ByVal sender As Object, ByVal e As DevExpress.XtraPivotGrid.Web.WebCustomExportCellEventArgs) Handles ASPxPivotGridExporter.CustomExportCell
        Dim brick As DevExpress.XtraPrinting.TextBrick = e.Brick
        If e.DataField.FieldName = "Budget_Dif" Or e.DataField.FieldName = "LY_Dif" Or e.DataField.FieldName = "SumBudget_Dif" Or e.DataField.FieldName = "SumLY_Dif" Then
            brick.TextValue = ConvertToDouble(brick.Text)
        End If
    End Sub

Pivote Dinámico para Ejemplo Anterior


CREATE PROCEDURE [Tutorial].[UspPivoteDinamicoEjemplo]
@IdValorParametro INT
AS
DECLARE @Pivotiar VARCHAR(MAX) = ''
DECLARE @PivotiarSuma VARCHAR(MAX) = ''

 --DECLARACION DE LA TABLA PARA INSERTAR LOS CAMPOS COLUMNAS
  DECLARE @TblColumnas TABLE 
  (
Id INT IDENTITY(1,1),
Columna VARCHAR(20)
  )

--RELLENANDO LA TABLA 
INSERT INTO @TblColumnas
SELECT [Description] FROM Tutorial.Catalogos
WHERE  IdCatalogo = @IdValorParametro
ORDER BY [Description] DESC

SET @Pivotiar = @Pivotiar +  (SELECT ',['+ Columna + ']'  FROM @TblColumnas FOR XML PATH(''))--PARA CONVERTIR LAS FILAS A UNA SOLA VARIABLE CONCATENANDO CON COMA
SET @Pivotiar = SUBSTRING(@Pivotiar,2,LEN(@Pivotiar)) --PARA QUITAR LA PRIMAR COMA 
SET @PivotiarSuma = REPLACE(@Pivotiar,',','+')--PARA HACER CALCULOS EN EL SELECT CON LAS COLUMNAS

   EXEC('SELECT ROW_NUMBER() OVER(ORDER BY IdCampo DESC) AS Id,*,('+@PivotiarSuma+') AS Total
FROM ( 
SELECT * FROM Tutorial.VwVistaConValores WHERE IdParametro = '+@IdValorParametro +
') Pvt
PIVOT (SUM(Monto) FOR [Description] IN ('+@Pivotiar+')) AS Pivote')

Crear un AspxGridView Dinámico haciendo uso de un Pivot SQL Server

En este ejemplo haremos un gridview la cual las columnas son dinámicas de acuerdo a las columnas de un Pivot Grid. Desde código crearemos las columnas con su tipo de datos.

Primeramete solamente arrastramos el GridView, se verá de esta menera:



Luego creamos las columnas que obtenemos del origen de datos:


 Sub crearControles()

        Try
            grdGridView.Columns.Clear() 'Limpiamos las columnas del grid porque por cada postback se crean las columnas nuevamente.

            agregarCommanColumn() 'Si necesitamos hacer uso del Select,New,Update,Delete

            'Si necesitamos agregar template a nuestras colunas
            'se utiliza para mostrar campos no editables y mostrar un label
            Dim labelTemplate As New GridViewTemplate()

            For Each column As DataColumn In dtOrigenDatos.Columns

                Select Case column.ColumnName
                    
                    Case "Id" 'las columnas que no necesitamos agregar al grid
                     'las columnas con propiedades especificas y para agregar el labeltemplate
                     'para las columnas no editables
                    Case "Columna1"
                        Dim txtColumn As New GridViewDataTextColumn()
                        txtColumn.Name = column.ColumnName
                        txtColumn.FieldName = column.ColumnName
                        txtColumn.Settings.HeaderFilterMode = HeaderFilterMode.CheckedList
                        txtColumn.Settings.AutoFilterCondition = AutoFilterCondition.Contains
                        txtColumn.EditFormSettings.Visible = DevExpress.Utils.DefaultBoolean.False
                        txtColumn.EditItemTemplate = labelTemplate
                        grdMontosLimites.Columns.Add(txtColumn)
                    Case "columna2"
                        Dim cmbColumn As New GridViewDataComboBoxColumn()
                        cmbColumn.Name = column.ColumnName
                        cmbColumn.FieldName = column.ColumnName
                        cmbColumn.Settings.HeaderFilterMode = HeaderFilterMode.CheckedList
                        cmbColumn.CellStyle.HorizontalAlign = HorizontalAlign.Center
                        cmbColumn.Width = 50
                        grdMontosLimites.Columns.Add(cmbColumn)
                    Case "Columna4" 'Para valores numéricos no editables
                        Dim txtColumn As New GridViewDataTextColumn()
                        txtColumn.Name = column.ColumnName
                        txtColumn.FieldName = column.ColumnName
                        txtColumn.Settings.HeaderFilterMode = HeaderFilterMode.CheckedList
                        txtColumn.Settings.AutoFilterCondition = AutoFilterCondition.Contains
                        txtColumn.PropertiesTextEdit.DisplayFormatString = "N2"
                        txtColumn.EditItemTemplate = labelTemplate
                        grdMontosLimites.Columns.Add(txtColumn)
                    Case Else   'Si con el mismo tipo de datos en este caso SpinEdit Editables
                        Dim spnColumn As New GridViewDataSpinEditColumn()
                        spnColumn.Name = column.ColumnName
                        spnColumn.FieldName = column.ColumnName
                        spnColumn.PropertiesSpinEdit.DisplayFormatString = "N2"
                        spnColumn.PropertiesSpinEdit.SpinButtons.ShowIncrementButtons = False
                        spnColumn.Settings.HeaderFilterMode = HeaderFilterMode.CheckedList
                        grdMontosLimites.Columns.Add(spnColumn)

                End Select

            Next

        Catch ex As Exception
             Throw ex
        End Try
    End Sub


Sub agregarCommanColumn()

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

        Dim col As New GridViewCommandColumn()
        col.Name = "CommandColumn"
        col.ShowSelectCheckbox = True
        col.Caption = " "
        col.ButtonType = ButtonType.Image
        col.EditButton.Visible = True
        col.EditButton.Image.Url = "~/images/note_edit.png"
        col.CancelButton.Visible = True
        col.CancelButton.Image.Url = "~/images/Cancel_Icon_64.png"
        col.UpdateButton.Visible = True
        col.UpdateButton.Image.Url = "~/images/data_floppy_disk.png"
        col.VisibleIndex = 0
        grdMontosLimites.Columns.Add(col)
    End Sub

Por Ultimo hacemos nuestro llenado del GridView:


 ''' <summary>

    ''' Método para llenar un grid view devexpress
    ''' </summary>
    ''' <param name="grdControl">Control devexpress</param>
    ''' <param name="strCampoLlave">campos llave separado por coma</param>
    ''' <param name="objRecursoDeDato">objeto recurso para llenar el control</param>
    ''' <remarks></remarks>
    Public Sub cargarGridView(ByVal grdControl As ASPxGridView, ByVal strCampoLlave As String, ByVal objRecursoDeDato As Object)

Try

            With grdControl
                .DataSource = objRecursoDeDato
                .KeyFieldName = strCampoLlave
                .DataBind()
            End With
 Catch ex As Exception
       Throw ex
 End Try
End Sub

Clase del GridViewTemplate:

Imports DevExpress.Web.ASPxGridView
Imports DevExpress.Web.ASPxEditors
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class GridViewTemplate

    Implements ITemplate

    ''' <summary>
    ''' Agrega label para campos no editables
    ''' </summary>
    ''' <remarks></remarks>
    Private Function agregarLabel(ByVal strValor As Object) As ASPxLabel
        Dim lbl As New ASPxLabel
        lbl.Text = If(IsDBNull(strValor), "", strValor)
        Return lbl
    End Function

  Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn

                Dim strNombreColumna = TryCast(container, GridViewDataItemTemplateContainer).Column.FieldName
                container.Controls.Add(agregarLabel(DataBinder.Eval(TryCast(container, GridViewDataItemTemplateContainer).DataItem, strNombreColumna)))

       
    End Sub

End Class

lunes, 17 de junio de 2013

Suma de Totales en el Footer del ASPXGridView DevExpress por Pagina y por Todos los registros.

El GridView de DevExpress solo nos ofrece la suma de todos los registros del grid, pero si queremos los totales por pagina lo hacemos de la siguiente manera:

1- Creamos nuestros Total Summary: 
Aqui seleccionamos la columna donde se mostrará  y el nombre del campo del origen de dato (FieldName) a sumar. 

En el SummaryType establecemos Custom para que el GridView llame el evento CustomSummaryCalculate. 

En Tag una etiqueta que representa la suma por pagina y la suma del Total, esta propidad nos sirve para poner varias valores en la misma columna(SUM,AVERAGE,COUNT,ETC).


2- Creamos el evento CustomSummaryCalculate:

 Dim _dblTotal As Double
 Dim _dblPagina As Double
 Protected Sub grdResumen_CustomSummaryCalculate(ByVal sender As Object, ByVal e As DevExpress.Data.CustomSummaryEventArgs) Handles grdResumen.CustomSummaryCalculate

        Dim item As ASPxSummaryItem = TryCast(e.Item, ASPxSummaryItem)

        ' Initialization.
        If e.SummaryProcess = DevExpress.Data.CustomSummaryProcess.Start Then

            _dblTotal = 0
            _dblPagina = 0

        End If
        ' Calculation.
        If e.SummaryProcess = DevExpress.Data.CustomSummaryProcess.Calculate Then
        ' Validacion si el registro no esta revertido cuando se maneja esta acción.
            If Not e.GetValue("Revertido") Then
                _dblTotal += e.GetValue("Monto")
            End If

            'Valores de la pagina actual
            If grdResumen.GetCurrentPageRowValues("IdLlave").Contains(e.GetValue("IdLlave")) Then
                _dblPagina += e.GetValue("Monto")
            End If

        End If

        ' Finalization.
        If e.SummaryProcess = DevExpress.Data.CustomSummaryProcess.Finalize Then
            If item.Tag = "MontoTotal" Then
                e.TotalValue = String.Format("∑ {0:N2}", _dblTotal)
            End If
            If item.Tag = "MontoPagina" Then
              ' Verificamos si la suma de los montos son distinto que nos indica que hay mas de
                  una página para ocultarlo cuando solo hay una página.
                If _dblTotal <> _dblPagina Then
                    e.TotalValue = String.Format("∑ {0:N2}", _dblPagina)
                End If
            End If
        End If


    End Sub

' Este metodo tiene un la debilidad que al paginar pone la suma de la pagina que se estaba 
viendo por lo que muestra la suma de la pagina anteror. Mas adelante publicaré la solución 
de este bug.

Lo prometido es deuda y aquí les dejo la solución:

Creamos los eventos al cambiar al cambiar el tamaño de la página o al cambiar de página.
Asignamos una propiedad de JSProperties para luego leerla en el EndCallback de los Client-Side-Event del GridView para ejecutar el PerformCallback del GridView y refrescar los valores.

Protected Sub grdResumen_PageIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles grdResumen.PageIndexChanged
        grdResumen.JSProperties("cpPaginacion") = True
    End Sub

Protected Sub grdResumen_PageSizeChanged(ByVal sender As Object, ByVal e As EventArgs) Handles grdResumen.PageSizeChanged
        grdResumen.JSProperties("cpPaginacion") = True
    End Sub



miércoles, 8 de mayo de 2013

Obtener Primer y Ultimo Dia del Mes VB


  If Not IsPostBack Then
            Dim firstDay = New Date(Now.Year, Now.Month, 1)
            Dim lastDay = firstDay.AddMonths(1).AddDays(-1)
            deFecha1.Value = firstDay
            deFecha2.Value = lastDay
  End If

sábado, 20 de abril de 2013

Como Actualizar Campos en la Bases de Datos con JQuery y ASHX

La función del ASHX es comunicarse con nuestra pagina web por medio de funciones javascript para hacer pedidos al servidor como los son el $.get(), $.load(), $.ajax().

En nuestro caso utilizaremos la función $.get(), la cual quedará de la siguiente manera:
Donde los parámetros son el campo que se va actualizar, el nombre del campo en la tabla y el nuevo valor. Los parámetros son enviados por QueryString al nuestro ASHX.

Luego generamos los eventos a los controles para hacer el efecto de edición los controles, aquí al momento de cargar la pagina web asignamos los con las teclas ESC para cancelar Edición.


Creamos la función que hace el llamado a actualizar campos. Esta función recibe la opción que va a realizar si es cuando dió clic en Editar o cuando dió Enter para Actualizar o simplemente el control perdió el focus para cancelar Edición. Este caso es para el Editar Nombre:


Creamos nuestro formulario:





Adjunto el archivo ASHX, debe estar en la misma carpeta donde esta el formulario: