Decision Cube y las fechas
Cuando en un Decision Cube se utiliza un campo de tipo fecha como dimensión para el análisis, este componente agrupa los valores por años, por omisión. Este comportamiento es lógico: una dimensión de un cubo de decisión debe contener un número pequeño de valores posibles. ¿Cuántas celdas tendrá un cubo? Para cada dimensión hay que estimar el número de valores de su dominio, y multiplicarlos a todos entre sí. Si implementamos un cubo con dos dimensiones: formas de pago y provincia, y tenemos 10 formas de pago y 50 provincias, nuestro cubo contendrá finalmente 500 celdas.
He visto ejemplos de otros programadores que intentan mostrar una rejilla de decisión siendo el nombre de cliente una de las dimensiones. Se trata, por supuesto, de un disparate total. El total de clientes puede crecer desorbitadamente, y TDecisionCube se protegerá limitándose a almacenar un número predeterminado de celdas como máximo. En uno de esos malos ejemplos, además, el nombre de cliente era la única dimensión. Este tipo de información se muestra de forma más adecuada en un TDBGrid corriente, o en un TDBChart si necesitamos una representación gráfica.
Volvamos a las fechas. ¿Qué pasa si necesitamos un mayor nivel de detalles en el análisis por fechas? Como sabemos, podemos controlar el grado de agrupación de las fechas en tiempo de diseño haciendo doble clic sobre el componente TDecisionCube, seleccionando la dimensión correspondiente y asignando el valor deseado mediante el combo Grouping. Pero, ¿cómo modificar este parámetro dinámicamente?
MODIFICACION DINAMICA DE PARAMETROS DE DIMENSIONES
No se trata de algo evidente: mi primera intención fue modificar directamente el valor dentro del cubo. Un TDecisionCube tiene una propiedad DimensionMap, que a su vez contiene una lista de componentes de tipo TCubeDim. Estos últimos son los que contienen datos de cada dimensión o estadística. En particular, la propiedad BinType es la que determina cómo se agrupan las fechas. Pues bien, si modificamos directamente dicha propiedad, no pasará nada: el cubo ignorará nuestros intentos. La técnica correcta consiste en crear un duplicado de DimensionMap, modificar la copia y llamar entonces al método Refresh del cubo para que actualice su contenido.
El siguiente procedimiento muestra cómo aplicar la técnica explicada. Hay que incluir la unidad MxCommon para que pueda ser compilado:
procedure ModificarCubo(ACube: TDecisionCube; ItemNo: Integer;
Grouping: TBinType);
var
DM: TCubeDims;
begin
DM := TCubeDims.Create(nil, TCubeDim);
try
DM.Assign(ACube.DimensionMap);
DM.Items[ItemNo].BinType := Grouping;
ACube.Refresh(DM, False);
finally
DM.Free;
end;
end;
Los valores que puede asumir el parámetro Grouping son los siguientes:
type
TBinType = (binNone, binYear, binQuarter, binMonth,
binSet, binCustom);
Por supuesto, los que nos interesan son binYear, binQuarter (trimestre) y binMonth.
PERO ...
Siempre hay un "pero". En este caso, el procedimiento provoca un fallo general y catastrófico si existe un componente TDecisionGraph visible y acoplado al cubo. Este fallo viene arrastrándose desde hace varias versiones; parece ser que a la gente de Borland (tan humanas) les da lástima matar al viejo bicho, y esperan que muera de melancolía.
|