Está en la página 1de 13

Generar una consulta de Referencias Cruzadas en C#

Cmo crear una salida en un GridView


de referencias cruzadas en C#
Introduccin
Muchas veces en diversos sistemas, ms aquellos que trabajan con datos histricos o sistemas de
estadsticas, los usuarios requieren visualizar la informacin tanto en filas como en columnas, es
decir, que se requieren realizar una consulta de referencias cruzadas.
Si bien el SQL Server 2005 posee un comando que permite realizar esta tarea mediante el
comando PIVOT, la idea de este cdigo es no sobrecargar al servidor de base de datos demasiado
en convertir filas por columnas.
Para lograr esto, desarrollaremos a continuacin un par de clases que permitirn cumplir este
requerimiento creando un DataTable especial.
Este tipo de consulta permite al usuario realizar un mejor anlisis del historial de ventas en el
tiempo, puede ver mejor el rendimiento entre un perodo.

Autor: Leonardo D. Zulli

Pag. 1

Generar una consulta de Referencias Cruzadas en C#


Diseo de la salida de la informacin
Para comenzar a ver lo que hay que hacer, primero veamos un poco cuales son los datos dados y a
que hay que convertirlos.
Supongamos que deseamos calcular una estadstica de ventas por subrubros de una distribuidora
de repuestos para automotores, donde disponemos de la siguiente informacin:

Veremos que aqu tenemos un conjunto de resultados devuelto del SQL Server mediante un Store
procedure que son los datos a procesar. Ms adelante durante el desarrollo, veremos que
conviene desarrollar un Store para este fin.
Lo que tenemos que lograr con esta informacin es procesarla para convertirla en algo llamado
CrossTable de la siguiente forma:

Autor: Leonardo D. Zulli

Pag. 2

Generar una consulta de Referencias Cruzadas en C#

Como se puede observar los subrubros se encuentran unificados y se cre una columna por mes
que antes nos apareca todo como fila en una tabla plana.

Planteo Lgico en Memoria


Para lograr convertir la estructura plana que se mostr al principio en una tabla de referencias
cruzadas, lo primero que hay que pensar en una matriz de bidimensional, es decir, filas x
columnas, por ejemplo:

0
1
..
n

Como se puede observar, podemos interpretar que cada posicin de una fila, corresponder a un
subrubro y cada posicin de una columna corresponder a un determinado mes y ao. Hay que
tener en cuenta que el rango de fecha es parametrizado por el usuario, con lo que puede cambiar
de ao.
A esta matriz la denomin, matrz de valores, ya que va a contener los valores calculados que hay
que mostrar en cada celda del GridView.
Ahora, tengamos en cuenta que estamos trabajando con C#, con lo que el conjunto de resultados
viene dado a partir de un objeto DataTable y que luego para poder mostrarlo en el gridview,
tenemos que convertirlo en un DataTable especial, con lo que necesitamos un par de vectores
para los nombres de los campos de las columnas a generar, entonces, paralelo a las columnas
generamos la siguiente estructura:

Autor: Leonardo D. Zulli

Pag. 3

Generar una consulta de Referencias Cruzadas en C#


En esta grfica se anexa una lista llamada lColumnas que contendr los nombres de cada columna
que hay que generar en el DataTable resultante. lColumnas tiene que ser una lista dinmica, y
debe ir de la mano con las columnas de la matrz de valores, ya que por el posicionamiento luego
se el programa podr saber donde debe ubicar cada valor.
Luego, como esta estadstica tiene que mostrar el cdigo de subrubro y la descripcin por cada
fila, entonces, se anex dos vectores (listas) en paralelo a cada fila de la matrz de la siguiente
forma:

0
1
..

..

..

lCodSrb es una lista que contiene los cdigos de subrubros y lDesc contiene la descripcin de cada
uno de ellos. De esta forma lgicamente tendramos la estructura completa de una tabla de
referencias cruzadas en memoria.
Recodemos que la asignacin de las posiciones tiene que se dinmica siempre, con lo que en C# en
vez de definir los vectores como array [ ] los definiremos como List<T> que permite generar
posiciones a medida que el programa lo necesita.

Nomenclatura de las variables ndices


Ix

= Indica que es un ndice de un vector o matriz.

ixF

= Indica que es un ndice (ix) que corresponde a una fila de la matriz (F).

ixC

= Indica que es un ndice (ix) que corresponde a una columna de la matriz (C).

Autor: Leonardo D. Zulli

Pag. 4

Generar una consulta de Referencias Cruzadas en C#


Programacin de la tabla de referencias cruzadas.
Una vez que se ha realizado el planteo lgico, pasaremos a desarrollar el cdigo que permitir la
conversin de los datos.
Lo primero que tenemos que tener en cuenta de que nos tenemos que asegurar de que el manejo
de las listas sea precisa, con lo que vamos a crear una clase que contendr funciones genricas
exclusivamente para menejar las listas.
A esta clase la llam ArrayListUtilities donde contiene las siguientes rutinas:

AgregarVector permite agregar un nuevo valor al vector. Esta rutina verifica si el dato a agregar ya
existe. Si existe, entonces, no lo agrega. Esto se debe ya que los vectores paralelos tanto por filas
como por columnas, deben contener datos nicos.

Autor: Leonardo D. Zulli

Pag. 5

Generar una consulta de Referencias Cruzadas en C#

BuscarPos permite localizar a partir de un valor, la posicin de la lista en que se encuentra dicho
valor. La idea es que tenemos que tener en cuenta de que para ubicar los datos en la matriz
bidimensional el programa se basar en las posiciones de sus vectores paralelos.
Devuelve 1 en caso que no haya encontrado el valor.
Por ltimo creamos una rutina para ubicar los valores en la matriz como se muestra a
continuacin:

Autor: Leonardo D. Zulli

Pag. 6

Generar una consulta de Referencias Cruzadas en C#


Mediante esta rutina el programa ubica los valores calculados dentro de la matriz a mostrar. Ver
que cuando se ubica el valor se suma, debido a que si la consulta original tiene registros
duplicados, entonces, debe sumar la cantidad para unificarlo.
A continuacin se debe desarrollar la clase especfica de la consulta que se solicita. Hasta el
momento no encontr una forma genrica de resolver este problema.
A esta clase la llam CTVtasSrb (Cross Table Ventas por SubRubro) y contiene el siguiente cdigo:

Se definen los campos privados de la clase y las propiedades.


Esta clase tiene dos propiedades, la primera es un DataTable de entrada que contiene el conjunto
de resultado tal cual se muestra en la consulta del SQL Server al principio y un DataTable de salida,
que es el datatable convertido. En el constructor inicializo todos los campos de la clase.
Esta clase como se puede observar es una herencia de la clase ArrayListUtilities.
La siguiente rutina permite generar los vectores paralelos a las filas que contienen los Cdigos y las
descripciones unificadas que se toman a partir de los registros del DataTable de entrada. Ver el
siguiente cdigo:
Autor: Leonardo D. Zulli

Pag. 7

Generar una consulta de Referencias Cruzadas en C#

Lo mismo hay que hacer con el vector que contiene las columnas a generar que se deben tomar a
partir de los registros del DataTable de entrada, ver el siguiente cdigo:

Autor: Leonardo D. Zulli

Pag. 8

Generar una consulta de Referencias Cruzadas en C#


A continuacin hay que cargar la matriz de valores, donde se toman los mismos del campo
cantidad, ver el siguiente cdigo:

La siguiente rutina permite crear la estructura que contendr el DataTable resultante. Ver el
siguiente cdigo:

Autor: Leonardo D. Zulli

Pag. 9

Generar una consulta de Referencias Cruzadas en C#


Por ltimo hay que crear una rutina pblica que permitir convertir el DataTable de origen en el
DataTable resultante de la siguiente forma:

Aqu ya se ha finalizado la creacin de la clase. A continuacin hay que hacer uso de ella para crear
el DataTable que permitir generar la consulta de referencias cruzadas.

Autor: Leonardo D. Zulli

Pag. 10

Generar una consulta de Referencias Cruzadas en C#

El objeto se llama cvt_Ventas donde lo nico que recibe es el datatable de entrada, se hace el
llamado al procesar y por ltimo se retorna el DataTable resultante.
El objeto cvt_Ventas se debe instanciar de la siguiente forma:

Si vinculamos el DataTable de salida a un GridView, entonces conseguimos el siguiente resultado:

Autor: Leonardo D. Zulli

Pag. 11

Generar una consulta de Referencias Cruzadas en C#


Programacin del SP en SQL Server 2005
Para que esta estructura funcione, hay que tener en cuenta de generar un Store Procedure que
prepare los datos para lograr este objetivo. Para conseguir esto se cre el siguiente SP:
CREATE Procedure [dbo].[VENTAS_GetEstadBySrb] (
@Id_Proveedor int,
@FecDesde
Datetime,
@FecHasta
Datetime)
As
-- Armo el universo de ventas validando cuando es NC la cantidad
-- lo convierto a nmero negativo.
-- Con este universo creo una tabla temporal llamada vtas_tempo
Select Articulos.IdSrb,
VentasCab.Cpte,
SubRubros.CodSrb,
SubRubros.Descripcion,
Year(VentasCab.FecAlta) As Anio,
Month(VentasCab.FecAlta) As Mes,
CASE VentasCab.Cpte
WHEN 'NC' THEN VentasDet.Cantidad * -1
ELSE VentasDet.Cantidad
END As Cantidad
Into
#vtas_tempo
From
VentasCab, VentasDet, Articulos, SubRubros
Where VentasCab.Id_VentasCab = VentasDet.Id_VentasCab
And VentasDet.Id_Articulo = Articulos.Id_Articulo
And Articulos.IdSrb = SubRubros.IdSrb
And VentasCab.FecAlta >= @FecDesde
And VentasCab.FecAlta <= @FecHasta
And Articulos.Id_Proveedor = @Id_Proveedor
-- Hago la agrupacin sobre la tabla temporal para que el SP
-- devuelva la estadstica que se necesita
Select #vtas_tempo.IdSrb,
#vtas_tempo.Anio,
#vtas_tempo.Mes,
CASE #vtas_tempo.Mes
WHEN 1 THEN 'Ene_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 2 THEN 'Feb_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 3 THEN 'Mar_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 4 THEN 'Abr_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 5 THEN 'May_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 6 THEN 'Jun_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 7 THEN 'Jul_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 8 THEN 'Ago_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 9 THEN 'Sep_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 10 THEN 'Oct_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 11 THEN 'Nov_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
WHEN 12 THEN 'Dic_' + CONVERT(Varchar(4), #vtas_tempo.Anio)
END As Columna,
Max(#vtas_tempo.CodSrb) As CodSrb,
Max(#Vtas_tempo.Descripcion) As Descripcion,
Sum(#vtas_Tempo.Cantidad) As Cantidad
From
#vtas_tempo
Group By
#vtas_tempo.IdSrb,
#vtas_tempo.Anio,
#vtas_tempo.Mes
Order By
#vtas_tempo.IdSrb,
#vtas_tempo.Anio,
#vtas_tempo.Mes
Go

Autor: Leonardo D. Zulli

Pag. 12

Generar una consulta de Referencias Cruzadas en C#


Al ejecutar desde el SQL Server mediante el comando EXEC este store procedure estara
devolviendo un conjunto de resultados como se muestra a continuacin:

Observemos que en este SP se prepara un campo llamado Columna donde unifico el mes y el ao,
donde si el parmetro que pasa el usuario se mueve de ao, no debera haber problemas.
Tener en cuenta que el ordenamiento de los datos es importante para que estas clases funcionen
correctamente, con lo que se debe utilizar la clausula ORDER BY del select resultante.
De esta forma logramos generar una consulta de referencias cruzadas y presentar la informacin
al usuario de una forma ms legible que tener muchas filas. Este tipo de consultas permiten
realizar comparativas y analizar el historial de ventas.

Autor: Leonardo D. Zulli

Pag. 13

También podría gustarte