domingo, 12 de octubre de 2008

QlikView: novedades generales en la versión 8.5

Hoy voy a escribiros las notas que tomé en la presentación de la nueva versión de QlikView del pasado martes en Valencia.


No me centraré en la parte del día que se habló del programa para partners y de la filosofía de Qlikview para con su relación con los clientes y partners. Únicamente hablaré de la última parte de la presentación, la parte más técnica, donde Jose Antonio Miguélez (un saludo) explicaba las mejoras de esta versión.

La primera sensación que recuerdo que me transmitió el evento fue de "desilusión" pues vimos pocas mejoras en esta versión, sobre todo si tenemos en cuenta que yo salto de las versiones 6.07 a la 8.x. Esperaba un cambio brutal al saltar 2 versiones pero el interfaz seguía siendo el mismo, el lenguaje de script el mismo, los objetos los mismos, y poco más.


De vuelta a Alicante comencé a "digerir" los conceptos de los que había hablado José Antonio en su ponencia y empecé a ver la luz al final del túnel. En 2 horas estaba en casa, con la versión 8.5 developer en mi portátil, y empezaba a trastear lo que había visto en la demo.

Esta sensación de la que había hablado antes de desilusión, comenzaba a transformarse en sorpresa y admiración. Sí que es cierto que visualmente habían mejorado muy muy poco, en lo que han hecho un esfuerzo importante la gente de Qliktech ha sido en la parte de detrás del telón, en el back-office, no porque hayan incluído 50 sentencias nuevas (no creo que lleguen a 10 las nuevas) sino por que han conseguido que todo sea dinámico, incluyendo las dimensiones y han incluido un set de instrucciones para el manejo de conjuntos que dota a Qlikview de toda la funcionalidad que se podría pedir (como lo llaman ellos SET ANALYSIS). Pero, ¿qué es esto de los conjuntos?, pues intentaré explicarlo lo más sencillo que pueda.


Set Analysis nos va a permitir comparar selecciones entre ellas mismas. Hasta ahora, Qlikview nos muestra los datos que tenemos seleccionados, reduciendo cada vez más según sumamos selecciones en ciertos campos, dejando fuera de la vista los datos excluídos ¿me seguís?. Si tenemos un documento con ventas de 2 años (2006 y 2007), y seleccionamos el valor 2007 para la dimensión AÑO, la suma de las ventas será igual a las ventas del año 2007 y todo el resto del documento estará filtrado a los registros relacionados con el año 2007, con lo que si tuviéramos una gráfica que nos comparara las ventas de estos 2 años, sólo mostraría la expresión para el año 2007.

Con "Set analysis" podemos tener acceso a cualquier conjunto de datos independientemente de las selecciones del usuario; selecciones para uno o más campos, bookmarks, y variables.

Introducen 3 operadores importantes :
  • {1}: significa el conjunto completo de datos del documento.
  • {0}: o conjunto vacío, sería equivalente a la selección de ningún dato.
  • {$}: la/s selección/es actuales. Ojo!, o una selección especificada por nosotros, no por el usuario (una variable, un bookmark, o un valor o varios para un campo).

Un ejemplo directo en QlikView:


La primera columna "Sum({1} Ventas)" : Calcula el total de las ventas para cada dimensión en todo el conjunto de datos sin selecciones

"Sum({1-$} Ventas)": Calcula el total de las ventas menos las selecciones actuales para cada dimensión.

"Sum({$} Ventas)": El total de ventas según las selecciones actuales (vamos, lo normal), para cada valor de la dimensión.

"Sum({$} Ventas )": El total de ventas según las selecciones actuales teniendo como referencia el año 2008 aunque no esté seleccionado, para cada valor de la dimensión.


Ojo en el ejemplo que tengo la dimensión "Nombre Tienda" seleccionada en un valor. Por eso aparecen las cifras "0" en las tiendas que no son "Alicante 1".

Tradicionalmente esto se podía conseguir (en parte) con el operador IF. Con la 8.5 debemos dejar de recurrir a este operador que es mucho menos eficiente (desde el punto de vista del consumo de memoria y de la velocidad de cálculo) que la lógica de conjuntos.


Hay un buen apartado de ejemplos en la ayuda del programa buscando como "análisis de conjuntos" donde explican de una forma muy buena todo el tema de conjuntos. Realmente interesante.


Ahora voy a citar una lista corrida de mejoras en la versión 8.x a mi entender importantes:
  • Servidor Web integrado en la solución server (no requiere IIS).
  • DSC (Directory Service Connector). Ya no se requiere AD de Microsoft, se puede conectar con otros LDAP.

  • DMS: Gestión Integral de documentos. Esto es realmente un logro y los usuarios os lo van a agradecer (aunque nos va a representar algún curro más). Lo que permite DMS es una centralización de todo lo que crea el usuario, ya no se guarda en el registro del usuario, en carpetas por ahí ocultas. Todo se centraliza, bookmarks, objetos, tablas, gráficos, personalizaciones, ...

  • Los objetos que el usuario crea (no el programador), pueden ser compartidos al resto de los usuarios (por decisión propia del usuario que es propietario de ese objeto).

  • Integración mediante OCX en software de terceros como por ejemplo un PPT (Power Point). (siempre que el usuario que lo abra tenga la licencia correspondiente del cliente).

  • Seguridad a nivel de campo.

  • Mejoras en la potencia de los informes (tampoco para tirar cohetes pero bueno).

  • Búsqueda difusa. Si el usuario maneja y conoce la definición de campos del documento pues se puede hacer búsquedas del tipo "pvp_articulo > 20 and pvp_articulo<40". Por supuesto, siempre que el coco del usuario de para esto ;-)

  • Dimensiones dinámicas: la bomba. Ya no tengo por qué definir varias gráficas (clonando) con diferentes dimensiones o crear grupos cíclicos y que el usuario elija de la lista. Podemos combinar como dimensión el uso de la expansión de dólar o utilizar una variable que el usuario puede definir en tiempo de ejecución, pudiendo así crear un objeto "reutilizable" por el usuario para distintos análisis. Pocas herramientas hay que te permitan hacer esto. Pensad bien quien se haya pegado con cubos OLAP, en el coste de cambiar la estructura de nuestros cubos, ¿qué tiempo tardamos en regenerarlo?,¿debe el usuario pasar por nuestro departamento/consultoría para hacer esa petición?. En Qlikview ya no.

  • Podemos abrir un documento con una selección determinada (por ejemplo un bookmark de documento) en base a la sección de acceso de nuestro documento. Imaginemos un departamento de compras con 3 compradores (uno compra lo referente a la sección de Gimnasio, otro la sección de Running, y el otro la sección de Bicicletas). Pues podemos filtrarle a cada uno el documento con sus secciones de forma predeterminada aunque luego él puede ver el conjunto de datos.

  • Por fin, han introducido el password en el editor de macros. Ya estarán a salvo nuestro código de macro. Una anotación, intentad huir de las macros en la medida de lo posible.

  • Podemos abrir un documento sin cargar los datos en el caso de algún error raro o que nuestro equipo donde desarrollamos no tenga suficiente RAM para cargar cierto documento y queremos rectificar el script.

  • Podemos cargar campos tipo imagen por ODBC e incluso reducir el tamaño en la recarga.

  • Podemos establecer con apenas un par de líneas de código, jerarquías "no-balanceadas" del tipo empleado-superior donde tanto el empleado como su superior se encuentran en la misma tabla. Sentencia "Hierarchy" & "BelongsTo".

  • Si empezamos a tener problemas de falta de memoria en alguna recarga o en el acceso, ya está disponible el software compilado para 64bits. Siempre y cuando tengamos una máquina que lo soporte y lo tenga habilitado.

Bueno, pues una vez más espero haberos ayudado en algo.

Un saludo a tod@s

15 comentarios:

Francisco Páez dijo...

Hola Carlos,

Efectivamente eres un monstruo sintetizando.

Tu exposición me ha ayudado mucho a apreciar las mejoras en la versión 8.5 y el ejemplo de los "conjuntos" es muy clarificador.

Saludos.
Francisco Páez

Carlos Gutierrez dijo...

Gracias, Fran.
Me gusta ser de utilidad. ;-)

Anónimo dijo...

Buenas tardes, genial su comentario pero tengo una pregunta para usted.

Llevo trabajando con QV como algo mas de un mes y me gustaria crear un boton que al pulsarlo el usuario mostrara una seleccion con el valor de un campo de los cargo en el script, he leido que esto se puede hacer con macros pero tambien es cierto que no tengo mucha idea, podria ayudarme????

Carlos Gutierrez dijo...

Buenas Alberto.
Tengo alguna duda de interpretación en tu mail.
Cuando comentas que quieres que se muestre al usuario una selección,¿ a qué te refieres?, ¿a un popup con un texto o quieres que vea una tabla?.
Cuando hablas de que tienes un campo de los que cargas en el script, ¿te refieres a una variable o a un campo de cierta tabla?.
Un saludo

Carlos Gutierrez dijo...

Buenas tardes, Alberto.
Te había preguntado por el blog alguna duda que tenía pero ahora te entiendo mejor.
Lo que necesitas se puede hacer y es "sencillo".
Te explico un ejemplo para seleccionar el valor "INDEFINIDO" para el campo "ClasificacionContratacion"

//

sub SacarMensaje

rem primero buscamos dentro del campo "ClasificacionContratacion" si existe un valor que sea igual a "INDEFINIDO" que es el que nosotros queremos seleccionar.

set f = ActiveDocument.fields("ClasificacionContratacion").GetSelectedValues

for i=0 to f.count-1

if UCASE(TRIM(f.item(i).text)) = "INDEFINIDOS" then encontrado = 1 end if

next

rem como ejemplo, si existe el valor que queremos seleccionar mostramos una pregunta al usuario. Esto en tu caso creo que no haría falta pero te lo puesto por ilustrar otras posibilidades.

if encontrado <> 1 then

MsgBox ("Atención: Para que los datos de esta hoja sean correctos debe estar seleccionado "&chr(13)&"el concepto 'INDEFINIDO' en la pestaña 'SELECTORES'. Pulse en 'SI' si desea que se seleccione ahora mismo", VbYesNo,"ATENCION!!!")

IF resp = vbyes then

rem aquí está el meollo del tema, la parte importante que tú preguntabas...

activedocument.fields("ClasificacionContratacion").select "INDEFINIDOS"

end if

end if

end sub

Espero te sirva, un saludo

Anónimo dijo...

Hola Carlos,

Se nos ha pedido una herramienta para controlar los fichajes diarios obtenidos de un terminal de proximidad.

Hemos pensado en utilizar QlikView para gestionar y visualizar los datos.

Tu crees que es posible y viable hacerlo??

En la tabla hay los siguientes campos: idOperario, Fecha, Hora, Entrada/Salida

Gracias y atentamente,

Carlos Gutierrez dijo...

Hola, Kikiterremoto.

La respuesta a tu pregunta es que sí, no veo ningún inconveniente con los datos que me aportas.

Casi todos los terminales de proximidad que conozco trabajan de ese modo, almacenan los "tiques" y los envían en modo ASCII a algún lugar, carpeta, u otro soft que luego lo almacena en una BD.
Imagino que añadirás también algún dato más para hacerlo más rico, como nombres y datos de los empleados, horarios, turnos, tipos de contrato, jornadas, sexo, y demás que tendrás en cualquier otra BD.
Cuanto más datos relaciones, más análisis podrás hacer lejos de mostrar únicamente los datos en una tabla. Cuanto más azúcar más dulce ;-)

Si este es tu propósito, me parece ok pero, un proyecto hay que saber hacerlo, y saber venderlo (a tus jefes, etc).

QlikView te ofrece unos gráficos y objetos muy ricos que puedes aprovechar.

Un saludo.

Unknown dijo...

Hola Carlos, ¿podrías decirme cómo es que podemos abrir un documento sin cargar los datos? justamente me ha pasado un error extraño, y debo rctificar el script, pero no puedo abrirlo porque comienza a cargar y no alcanza la memoria

Muchas Gracias!!!

Carlos Gutierrez dijo...

Ok, Caro.
Se me ocurren 2 formas.

La más simple aunque no sé si te valdrá es, tener los scripts de carga exportados en ficheros de texto fuera del documento. Luego, con una simple instrucción $(include)=miarchivo.txt Qlikview ejecutará el script perfectamente. Si se produjera algún error solo tienes que editar con el notepad el script y recargarlo otra vez.

La otra opción es llamar con la linea de comandos el ejecutable "qve.exe " pasándole un modificador para que no recargue nada. De memoria no te lo puedo decir pero te lo miro este fin de semana y te escribo un ejemplo.

El metodo del INCLUDE funciona muy bien para más cosas, como por ejemplo para reutilizar partes del script. En el script puedes tener varias instrucciones include.

Espero haberte sido de utilidad,
Gracias por leer el blog.

Unknown dijo...

Gracias Carlos, pude recuperar una versión anterior, pero tendré en cuenta tus opciones si vuelve a ocurrirme.

A ver si puedes ayudarme con esto, quisiera poner un color de texto condicional, dependiendo del color de la barra del gráfico (porque en algunos colores de las barras que tengo definidos el color del número no se visualiza bien). Utilizo este código, para el color calculado de la fuente (en propiedades/ejes/ejes de expresión7fuente)

If(BkgColorExp = rgb(x,x,x),
rgb(y,y,y),
rgb(x,x,x))

Pero BkgColorExp evidentemente no es correcto, o me falta un parámetro...
He buscado en el API guide, pero no encuentro algo que sirva.
Gracias!!!!

Carlos Gutierrez dijo...

Hola Caro.

Puesto que no especificas la versión que tienes de QV entiendo que es la 8.5.

Te estoy mirando si veo algo lo más parecido a lo que dices y si encuentro, te lo pongo.

Si te he entendido bien, quieres que el color del texto sea dinámico sobre el color del fondo de la columna (que entiendo también es dinámico) pero que ambos colores guarden un contraste que te permita que tenga un contraste alto y sean legibles , ¿no?.
Leyendo tu mail comentas que estás accediendo a la propiedad de color del EJE. Si esto es así creo que no vas bien encaminado pues el color del eje es único (no se puede poner varios colores a un eje).
Lo que sí que puedes hacer es definir dentro de una expresión (icono "+" junto al nombre) el color de fondo y del texto de esa expresión.
Si utilizas cierta expresión para aplicar un color de fondo denttro de un "IF", haz lo mismo al definir el color del texto pero a la inversa, es decir:

Expresión de color para el fondo=
IF([EXPRESION]>5000,RGB(0,0,0),RGB(255,255,255))

Expresión de color para el texto=
IF([EXPRESION]>5000,RGB(255,255,255),RGB(0,0,0))

donde EXPRESION puede ser la expresión tal cual o el nombre de la expresión (entre corchetes).

Yo suelo utilizar nombres de expresión en mayúsculas para distinguirlas de las variables cargadas en el script.

Echándole un poco más de imaginación y utilizando los mismos campos, tienes las funciones de color COLORMIX1(), y COLOR(n).

De todos modos el texto definido en la barra nunca sale encima de la barra, sale encima o en el eje o en un pop-up con lo que el fondo no influye.

Por favor, cuéntame si esto te vale o si te referías a otra cosa diferente.

entiendo que estás hablando de un objeto de gráfico de tipo "Combinado" o "Barras", ¿no?

Un saludo y gracias por leer el blog que lo tengo demasiado abandonado aunque me llegan todos vuestros comentarios y los intento atender.

Un saludo

Unknown dijo...

Gracias Carlos por la paciencia y tomarte el tiempo para contestar.
Sí, entendiste bien, es un gráfico de barras, estilo apilado. Quería hacer el color de texto dinámico, los colores de la barra son dinámicos, pero no calculados, toma la paleta de colores. Quería evitar utilizar una fórmula para cada valor de campo, y que el script me sirviera para todos los gráficos. Finalmente utilicé en el color de texto de la expresión:
If(DIMENSIÓN = 'valor_x', rgb(255,255,255),If DIMENSIÓN ='valor_y'(rgb(75,75,75), ....etc.
Y así con varios "if" anidados.
Funciona perfecto, pero debo hacerlo para cada gráfico :(

Saludos, y gracias nuevamente.

Silvia Pérez dijo...

Hola Carlos, estoy empezando a trabajar con los set analysis, y no me aclaro para montar una columna con las ventas del año anterior.

Actualmente lo he montado con un marcador, pero claro la columna queda fija.

Si me pudieras ayudar o referenciarme algún ejemplo de la community de QV.

Gracias

Silvia Pérez dijo...

Ya lo he solucionado, era una tontería.

Si alguien está interesado subo el como lo hice.

Anónimo dijo...

blog desactualizado y falto de datos que sirvan para algo. Uno de muchos.