Hoy en el trabajo hemos tenido que lidiar con el RadGrid de Telerik,. Llevamos ya bastante tiempo utilizándola y todavía hoy hay un tema que no tenía excesivamente claro, hablo de las agrupaciones y totales en la grilla.
Mi intención con este post es que perdure en el tiempo como referencia rápida para que, cuando vuelva a tener una crisis de identidad con este control, pueda visitar mi propia entrada y calmar mis ánimos.
Vamos a partir de una tabla sencilla que nos sirva para todos nuestros ejemplos, es un tabla de pedidos pendientes de servir a cliente con los siguientes campos:
CustomerID | Código de cliente |
OrderID | Id de pedido |
OrderLineID | Id de línea de pedido |
ProductID | Id de producto |
Units | Unidades |
Price | Precio |
CREATE TABLE [dbo].[MyOpenOrders](
[CustomerID] [nvarchar](20) NOT NULL,
[OrderID] [nvarchar](20) NOT NULL,
[OrderLineID] [nvarchar](50) NOT NULL,
[ProductID] [nvarchar](20) NOT NULL,
[Units] [int] NOT NULL,
[Price] [decimal](18, 2) NOT NULL
CONSTRAINT [PK_MyOpenOrders] PRIMARY KEY CLUSTERED
(
[CustomerID] ASC,
[OrderID] ASC,
[OrderLineID] ASC,
[ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
A continuación, algunas filas de ejemplo para tener datos de muestra:
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'1', N'1', 5, CAST(2.50 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'10', N'10', 10, CAST(4.87 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'11', N'11', 3, CAST(1.00 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'12', N'12', 2, CAST(3.51 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'2', N'2', 7, CAST(3.60 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'3', N'3', 2, CAST(3.00 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'4', N'4', 6, CAST(6.89 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'5', N'5', 7, CAST(0.56 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'6', N'6', 1, CAST(6.23 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'7', N'7', 4, CAST(9.47 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'8', N'8', 8, CAST(1.65 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'1', N'9', N'9', 9, CAST(3.78 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'2', N'1', N'1', 8, CAST(2.50 AS Decimal(18, 2)))
INSERT [dbo].[MyOpenOrders] VALUES (N'1', N'2', N'2', N'2', 7, CAST(3.60 AS Decimal(18, 2)))
Nuestro primer RadGrid será el que se muestra a continuación
<telerik:RadGrid ID="RadGrid1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" GridLines="None" AllowPaging="true">
<MasterTableView DataSourceID="SqlDataSource1">
<RowIndicatorColumn>
<HeaderStyle Width="20px"></HeaderStyle>
</RowIndicatorColumn>
<ExpandCollapseColumn>
<HeaderStyle Width="20px"></HeaderStyle>
</ExpandCollapseColumn>
<Columns>
<telerik:GridBoundColumn DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True"
SortExpression="CustomerID" UniqueName="CustomerID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="OrderID" HeaderText="OrderID" ReadOnly="True"
SortExpression="OrderID" UniqueName="OrderID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="OrderLineID" HeaderText="OrderLineID" ReadOnly="True"
SortExpression="OrderLineID" UniqueName="OrderLineID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="ProductID" HeaderText="ProductID" ReadOnly="True"
SortExpression="ProductID" UniqueName="ProductID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Units" DataType="System.Int32" HeaderText="Units"
SortExpression="Units" UniqueName="Units">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Price" DataType="System.Decimal" HeaderText="Price"
SortExpression="Price" UniqueName="Price">
</telerik:GridBoundColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
Nada nuevo que no sepamos ya hacer con el RadGrid.
Ahora y a partir de aquí, vamos a ver las capacidades de agrupación y cálculo de totales y subtotales que tiene la rejilla.
Lo que queremos hacer es lo siguiente:
1. Sumar en el pie de la rejilla, tanto unidades como precio.
2. Agrupar por OrderID, y tener un sumatorio tanto del pedido agrupado como también de todos los pedidos, todo ello en unidades y en precio.
Para incluir sumatorios en el pie de página, lo que hay que hacer es lo siguiente:
· Agregar ShowFooter="true" en MasterTableView.
· Agregar Aggregate="Sum" y FooterAggregateFormatString="{0:C2}" por cada GridBoundColumn que intervenga en el sumatorio.
<MasterTableView DataSourceID="SqlDataSource1" ShowFooter="true">
<telerik:GridBoundColumn DataField="Units" DataType="System.Int32" HeaderText="Units" SortExpression="Units" UniqueName="Units"
Aggregate="Sum" FooterAggregateFormatString="{0:#,##0}">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Price" DataType="System.Decimal" HeaderText="Price" SortExpression="Price" UniqueName="Price"
Aggregate="Sum" FooterAggregateFormatString="{0:C2}">
</telerik:GridBoundColumn>
Ahora nuestro RadGrid suma correctamente en el pie, tanto unidades como precio, y además esta suma es para todo el conjunto de resultados, no sólo para la página activa.
Nuestro siguiente paso será agrupar por OrderID y tener un sumatorio tanto del pedido agrupado como también de todos los pedidos. Antes de continuar te diré que el pedido 1 tiene 63 unidades y un valor de 47,06 €. Para lograr esta agrupación haremos lo siguiente:
· Agregar ShowGroupFooter="true" en MasterTableView.
· Agregar una expresión de agrupación con GridGroupByExpression.
<MasterTableView DataSourceID="SqlDataSource1" ShowFooter="true" ShowGroupFooter="true">
<GroupByExpressions>
<telerik:GridGroupByExpression>
<GroupByFields>
<telerik:GridGroupByField FieldName="OrderID" SortOrder="Ascending" />
</GroupByFields>
<SelectFields>
<telerik:GridGroupByField FieldName="OrderID" />
</SelectFields>
</telerik:GridGroupByExpression>
</GroupByExpressions>
El resultado es el siguiente:
Si nos fijamos, el sumatorio de grupo del pedido 2 es correcto porque todas las líneas del pedido están en la misma página del RadGrid. Sin embargo, el pedido 1 nos muestra el valor de las líneas que hay en cada página, no el total de todas las líneas. Así, por ejemplo, para la página 1 nos da 47 unidades y para la página 2 nos da 17 unidades, que sumadas dan 63 unidades, pero… en ningún sitio podemos ver esto, así que el total de grupo no parece ser muy acertado.
El porqué de esto no pretendo averiguarlo, pero simplemente te informo de cómo funciona el total de grupo, que quizás podrían haber llamado “total de grupo por página”.
Aun así nosotros somos muy cabezones y queremos dar al usuario el total de unidades del pedido 1 por pantalla (sin que importe la paginación). Para lograrlo hay que hacer lo siguiente:
· Agregar 2 nuevos GridGroupByField en SelectFields.
<telerik:GridGroupByField FieldName="OrderID"/>
<telerik:GridGroupByField FieldName="Units" FieldAlias="Unidades" Aggregate="Sum" />
<telerik:GridGroupByField FieldName="Price" FieldAlias="Precio" Aggregate="Sum" />
Finalmente, ahora ya podemos ver la suma total del pedido, tanto en unidades como en precio. El lugar donde aparecerán estos valores no será en el pie de grupo, sino en el encabezado de grupo (que si toma en cuenta para el cálculo de agregado todos los elementos del origen de datos).
Otras propiedades del RadGrid que podrían resultarte útiles durante la agrupación son:
RetainGroupFootresVisibility, indica si los pies de grupo tienen que ser visibles aun cuando el usuario colapse el grupo. Por defecto, no son visibles, es False
<GroupingSettings RetainGroupFootersVisibility="true" />
GroupsDefaultExpanded (en MasterTableView), indica si los grupos tienen que estar expandidos o colapsados por defecto. Por defecto están expandidos, es True.
GroupsDefaultExpanded="true"
FooterText (en GridBoundColumn), permite escribir un texto literal en el pie de la columna, luego puede servirnos para etiquetar el gran total que aparece en la rejilla en el pie. Por ejemplo, si agregamos el texto “Total global” en la columna ProductID:
Espero que después de esto, ya sepamos todos, agrupar y mostrar totales en un RadGrid de forma más efectiva.
Un saludo!
y que es eso del dataSource??
ResponderEliminarHola , solo una pregunta es posible condicionar la sumatoria?
ResponderEliminarpor ejemplo que solo sume cuando los Units sean mayor a 1??
saludos
Me ayudó. Gracias.
ResponderEliminarGracias
ResponderEliminar