jueves, 10 de septiembre de 2009

Comando AT y Schtasks, crear o ejecutar tarea programada en otro equipo




Como podemos ejecutar una aplicacion en otra maquina?

Como podemos recargar nuestra aplicacion Qlikview en un equipo que no es nuestro(local)?

bueno, encontre estos dos comando que me solucionaron el problema

el primero AT:

AT nos permite crear, ver y borrar tareas programadas en un equipo remoto
por ejemplo

AT \\HOST HORA /interactive Comando(tarea) a ejecutar

AT \\192.168.1.2 12:00 /interactive "C:\Program Files\QlikView\Qv.exe" /r C:\QlikView\recarga.qvw"

AT: es el comando que permite agregar una tarea programada en otro equipo
si ejecutamos AT en la consola nos listara todas las tareas que se han agregado a la maquina local.
si ejecutamos AT \\HOST nos listara las tarea del HOST

\\HOST: es el nombre o IP de la maquina a la que queremos agregar la tarea programada

12:00: es la hora en que se ejecutara la tarea programada

/interactive: nos permite ver en primer plano la aplicacion o la tarea que se esta ejecutando, si omitimos este parametro se ejecutara en segundo plano.

"C:\Program Files\QlikView\Qv.exe" /r C:\QlikView\recarga.qvw": es la tarea que necesito que se ejecute, que en este caso es realizar la recarga de la aplicacion "recarga.qvw".

AT tiene algunos inconvenietes:
necesitas los permisos adecuados para poder agregar tareas en otra maquinas
cuando agrega una tarea el propietario de la tarea es el sistema y esto fue un gran problema, pues Qlikview tiene sus licencia por cada usuario del equipo, por lo que cuando intentaba hacer la recarga me pedia ingresar la licencia para el usuario del sistema.

Solucion?

finalmente el comando AT lo tuve que sustituir por el comando Schtasks que nos permite ejecutar en ese minuto una tarea programada en un equipo remoto.

significa que primero debemos crear en la maquina remota, con el usuario valido para qlikview, una tarea programada que no se debe ejecutar nunca por si solo, sino que cuando se le hace una llamada.
Con el comando Schtasks podemos realizar esto:

SCHTASKS /run /S \\192.168.1.2 /TN "Qv"

lo que ejecutara en el host 192.168.1.2 la tarea programada llamada "Qv"

/run: realiza la ejecucion de una tarea programada

/S \\HOST: indica que se ejecutara en ese host, si se omite se ejecutara en la maquina local

/tn "Qv": indica que se ejecutara la tarea programada llamada "Qv"

el comando SCHTASKS reemplazó al comando AT
ademas permite la ejecucion de una tarea programada /run, ademas de crear, borrar, terminar.

para mas info de este comando en SCHTASKS


para mas info de comando AT en AT

martes, 7 de julio de 2009

Archivo QVD - Qlikview

Los archivos QVD son archivos que almacenan datos que pueden ser de diferentes fuentes de datos, diferentes BD, archivos planos TXT, archivos Excel, etc.

Porqué utilizar archivos qvd?

-Son una forma de optimizar el tiempo de carga de los datos
-Permiten carga incremental
-Son recomendados por Qlikview (será una razón válida?)
-etc, ya se me ocurrirán

Cómo crear un archivo qvd?

en nuestro scrip :


//Nombre que le asignamos a la tabla
Nombre_Tabla:
//Permite carga desde la base de datos, permite las mismas intrucciones que se puedes
//realizar en la BD, notar que Antecede la palabra SQL antes de nuestro Select común
SQL SELECT *
FROM Nombe_Tabla_BD;

//Permite guardar la tabla antes cargada, notar que se debe indicar el nombre de la
//tabla que le asignamos a la tabla y no el nombre que tiene en la BD
STORE Nombre_Tabla
INTO Nombre_Archivo_QVD.qvd;
//es posible indicarle un directorio a esta ruta
//por ejemplo guardar en la carpeta ArchivosQVD
//INTO ArchivosQVD\Nombre_Archivo_QVD.qvd;


-La primer instrucción permite obtener datos desde nuestra Base de Datos
-La segunda guardar la tabla obtenida en un archivo QVD Nombre_Archivo_QVD.qvd

Como podemos invocar nuestro archivo QVD generado?

Desde cualquier aplicacion QVW podemos invocar desde nuestro Script de la siguiente froma:


Nombre_Tabla:
LOAD *
FROM Nombre_Archivo_QVD.qvd (QVD);


Notar que podemos volver a cambiar el nombre de la tabla asignado en nuestra nueva aplicacion QVW

Pero qué son realmente los archivo QVD?

Son archivos que en su estructura interna mantinene la forma de un archivo XML


<qvdtableheader>
<qvbuildno>#numero#</qvbuildno>
<creatordoc></creatordoc>
<createutctime>#fecha#</createutctime>
<sourcecreateutctime></sourcecreateutctime>
<sourcefileutctime></sourcefileutctime>
<sourcefilesize>-1</sourcefilesize>
<staleutctime></staleutctime>
<tablename>#nombre qvd#</tablename>
<fields>
<qvdfieldheader>
<fieldname>#titulo columna 1#</fieldname>
<bitoffset>#?#</bitoffset>
<bitwidth>#?#</bitwidth>
<bias>#?#</bias>
<numberformat>
<type>#Tipo#</type>
<ndec>#?#</ndec>
<usethou>#?#</usethou>
<fmt>#formato#</fmt>
<dec>,</dec>
<thou></thou>
</numberformat>
<noofsymbols>#numero de simbolo ?#</noofsymbols>
<offset>#?#</offset>
<length>#largo#</length>
</qvdfieldheader>

....
...
..
.
ETC




Pero si son archivos Qvd generados y mantiene la info en su interior,No tendremos la información actualizada?

Es uno de los inconvenientes de esta forma de utilizar los datos en nuestras aplicaciones.

Posible solución para tener datos(Archivos QVD) actualizados?

Solucion 1:
Crear una tarea programada en windows que nos actualice los datos, extrayendo automaticamente los datos de la Base de Datos a nuestro archivos QVD sin nuestra intervención por ejemplo todos los días en la mañana, para que todos los días podamos usar los datos completos al día de ayer.

Solucion 2:
Actualizar manualmente los archivos QVD, podremos usar los datos actulizados recientemente, pero si nuestros datos es una base de datos muy grande o se manejan instrucciones sobre funciones, vistas, procedimientos almacenados, triggers, u otra, nuestra carga puede tardar mucho tiempo (horas).

miércoles, 15 de abril de 2009

Qlikview - Habilitar o Deshabilitar Expresion en Tabla o Graficos

Si tenemos 10 Expresiones y queremos ver solo 1 o 4 o 8, etc a traves de una macro podemos habilitar o deshabilitar la expresion, lo que nos permite tener 1 tabla o grafico con distintas expresiones y asi no tenemos que crean n tablas o graficos segun las expresiones que deseamos ver.

para esto cree un campo INLINE en el script que se llama Expression

LOAD * INLINE [
Expression '->nombre campo
Expresion1
Expresion2
Expresion3

];

y le aplique en las propiedades de documento->macros->Field Event Triggers cuando OnLoad y OnChange la siguiente macro TypeExpr


sub TypeExpr
'obtengo los campos que deseo ver
set val=ActiveDocument.Fields("Expression").GetSelectedValues
'instancio el grafico o tabla que deseo habilita o deshabilitar las expresiones
set chart = ActiveDocument.GetSheetObject("CH15")
set cp = chart.GetProperties
'reviso cuales expresiones estan seleccionadas
a1=0
a2=0
a3=0
for i=0 to val.Count-1
if a1=0 then
if val.Item(i).Text="Expresion1" then
a1=1
end if
end if
if a2=0 then
if val.Item(i).Text="Expresion3" then
a2=1
end if
end if
if a3=0 then
if val.Item(i).Text="Expresion2" then
a3=1
end if
end if
next
'si la expresion1 esta seleccionada
if a1=1 then
set expr0 = cp.Expressions.Item(0).Item(0).Data.ExpressionData
expr0.Enable = true
else
set expr0 = cp.Expressions.Item(0).Item(0).Data.ExpressionData
expr0.Enable = false
end if
'si la expresion2 esta seleccionada
if a2=1 then
set expr1 = cp.Expressions.Item(1).Item(0).Data.ExpressionData
expr1.Enable = true
else
set expr1 = cp.Expressions.Item(1).Item(0).Data.ExpressionData
expr1.Enable = false
end if
'si la expresion3 esta seleccionada
if a3=1 then
set expr2 = cp.Expressions.Item(2).Item(0).Data.ExpressionData
expr2.Enable = true
else
set expr2 = cp.Expressions.Item(2).Item(0).Data.ExpressionData
expr2.Enable = false
end if

'habilito o deshabilito las expresiones seleccionada
chart.SetProperties cp

end sub

miércoles, 25 de febrero de 2009

Qlikview - Include para VBscript

Utilizando el Qlikview necesito unificar para muchos archivos qvw el mismo Modulo (donde se agregan las subrutinas y las funciones), por lo que tengo que crear un archivo vbs, donde tenga todo lo que requiero y desde los archivos qvw tengo que llamar, incluir o importar estas funciones.

En VBscript no existe una instrucción donde yo pueda incluir desde un archivo vbs otro vbs.

Si tenemos el archivo1.vbs que imprime un mensaje "Hello Word"


sub HolaMundo
msgbox("Hello Word")
end sub


y queremos llamar desde otro archivo vbs(Archivo2.vbs) este mensaje, no existe una funcion como la de php por ejemplo
include("nombre.php");


ahora, buscando en la web encontre una solución a esto, pero tenemos que crear una subrutina que lo simule.

entonces debemos hacer lo siguiente, tenemos nuestras funciones o subrutinas en

archivo1.vbs



sub holaMundo
msgbox("Hello World")
end sub


entonces debemos agregar en nuestro qrchivo2.vbs lo siguienre para poder utilizar las funciones o subrutinas de Archivo1.vbs.
archivo2.vbs

Import "C:\Archivo1.vbs"

Sub Import(ByVal strFile)
Set objFs = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")
strFile = WshShell.ExpandEnvironmentStrings(strFile)
file = objFs.GetAbsolutePathName(strFile)
Set objFile = objFs.OpenTextFile(strFile)
strCode = objFile.ReadAll
objFile.Close
ExecuteGlobal(strCode)
End Sub



Como yo estoy aplicando esto a Qlikview, realizo lo siguiente

creo el archivo1.vbs con todas las funciones y subrutinas y desde los archivos qlikview(qvw) agrego en el módulo lo que se debe agregar en el archivo2.vbs y asi puedo modificar una funcion en el archivo1.vbs y cambiara en todos los archivos Qlikview (qvw).


Asi soluciono mi problema de modificar todos los archivos con las mismas funcionalidades cada vez que se hace un cambio.






fuente: asp free.com <-- aqui

martes, 20 de enero de 2009

QlikView - Seleccion y Creación de carpeta

Para Seleccionar y Crear una carpeta en el sistema es necesario ralizar lo siguiente

BrowseForFolder = ""
Dim objSHL
Set objSHL = CreateObject("Shell.Application")
Dim objB4F
On Error Resume Next
Set objB4F = objSHL.BrowseForFolder(&H0,sPMT,&H0031,&H0011)
BrowseForFolder = objB4F.Self.Path
if (not objB4F is nothing) then
Dim fso, fldr
Set fso = CreateObject("Scripting.FileSystemObject")
Set fldr = fso.CreateFolder(BrowseForFolder&"\NombreCarpeta")
'Aqui agregar codigo donde se hace algo
'dentro de la carpeta creada
'como por ejemplo exportar todos los objetos
'de una hoja como xml
For i = lBound(Objects) To uBound(Objects)
id = Objects(i).GetObjectId
Objects(i).WriteXmlPropertiesFile BrowseForFolder&"\NombreCarpeta\ObjBM"&i&".xml"
next
'Mensaje de finalización
MyValue= MsgBox ("Process Export is sucessfull in "&BrowseForFolder&"\NombreCarpeta\*",64,"Export")
end if

lunes, 19 de enero de 2009

QlikView - NetworkDays

La función NetworkDays sirve para evaluar fechas tomando en cuenta dias laborales, es decir, de lunes a viernes y se utiliza de la siguiente manera.

como expresión o dimensión (calculada)


networkdays(fechaInicio,FechaFinal)-1


es decir si tenemos las siguientes fechas.
Viernes: 16-01-2009 a Lunes: 19-01-2009

si obtenemos la diferencia real es

'19-01-2009'-'16-01-2009' = 3 días (Sábado, Domingo, Lunes)


pero con la función

networkdays('16-01-2009','19-01-2009')-1 = 1 día (Viernes a Lunes)


notar que se debe restar por -1 pues la función toma la diferencia con las fecha de incio y final inclusive.

miércoles, 14 de enero de 2009

QlikView - Carga Incremental




Qlikview es una herramienta de bussines intelligence, que no utiliza cubos OLAP, por lo que utiliza una nueva metodologia creada por ellos mismos llamada, AQL, descrita en post anterior de Qlikview que maneja finalmente la Nube de Datos (Cloud Data).

Esta nube de datos se debe recargar para actualizar la información y poder manejarla en la aplicación.
La carga simple, en casos donde se manejan grandes cantidades de información se puede demorar un tiempo considerable, por lo que existen tecnicas para reducir este tiempo de racarga y se llama "Carga Incremental".

Elementos necesarios para la recarga
- Archivos QVD.
- En la tabla de la base de datos un campo con la fecha de la ultima actualizacion.

un ejemplo para recarga incremental en el script es el siguiente:

Si se desea hacer la carga incremental de la tabla [NombreTabla], por campo [UltimaActualizacion]


Let FechaActual = now();
//fecha donde se hizo la ultima recarga
Let UltimaRecarga = ReloadTime();

[NombreTabla]:
//hasta aqui se cargaran los registros nuevos
//que fueron insertados y los modificados
SQL SELECT
*
FROM
[NombreTabla] as NT
WHERE
NT.[UltimaActualizacion] >= $(UltimaRecarga)
AND NT.[UltimaActualizacion] < $(FechaActual);
//aqui se uniran los registros nuevos con los
//previamente cargados en los archivos qvd
CONCATENATE
LOAD * FROM [NombreTabla].qvd (qvd)
WHERE NOT EXISTS( [ClavePrimaria] );
//finalmente se eliminaran los que ya no existen
INNER JOIN
SQL SELECT [ClavePrimaria]
FROM [NombreTabla]
//if no se producjo ningun error
if ScriptError = 0 then
//se guarda el archivo QVD con los datos actualizados
STORE [NombreTabla]
INTO [NombreTabla].qvd;
//se actualiza la fecha de la ultima recarga
Let UltimaRecarga = FechaActual;
end if