Para saber si un parámetro (Por ejemplo un código de almacén) de un dataset esta seleccionado en la lista de Almacenes de nuestro parámetro multiValue utilizaremos la función Array.IndexOf.
La manera serí así:
Array.IndexOf(Parameters!LISTA_DE_ALMACENES.Value, Fields!CODIGO_DE_ALMACEN.Value)
Devuelve -1 si no esta dentro de la lista.
Con esto, por ejemplo podemos ocultar o mostrar una casilla en función de si han seleccionado en los parámetros el valor de nuestro resultado:
Hidden
IIF(Array.IndexOf(Parameters!DESGLOSEALMACENES.Value, Fields!Almacen.Value) > -1,false,true)
NavisionUtil
Trucos de Navision. Trucos de Reporting Services
lunes, 13 de febrero de 2017
sábado, 24 de diciembre de 2016
Error al exportar Excel desde Navision
Cuando pinchas en el icono de exportar a Excel, si no tienes la librería de Microsoft msxm.dll para parsear XML da el siguiente error
Aunque tengas instalado el office, es posible que no tengas estos componentes que permiten la integración de Excel.
Lo único que hay que hacer es instalar las siguientes librerías:
domingo, 17 de julio de 2016
Sumar en Reporting Services solamente un valor por grupo
Cuando tenemos una consulta que devuelve varios registros por grupo donde tenemos unos datos en el grupo y no en el detalle, tenemos el problema que al mostrarlo en reporting y hacer una suma, nos lo va a sumar tantas veces como detalle tenga y no una vez por grupo.
Se puede solucionar haciendo una sub-consulta pero aquí vamos a explicar como mostrarlo en una única consulta.
Por ejemplo, tenemos la siguiente estructura:
Lo primero, es agregar una columna que cuente el número de registro dentro del grupo con la siguiente línea:
ROW_NUMBER() OVER (PARTITION BY Grupo ORDER BY Hijo ASC) as Fila
De esta manera sabemos cual es la línea dentro del grupo:
Ahora desde reporting es muy sencillo filtrar los datos solamente para la fila 1 de cada grupo.
Por ejemplo, podemos ocultar la línea de detalle primera y mostrarla directamente en la cabecera poniéndole la siguiente expresión de visibilidad en las líneas de detalle:
Para sumar, le agregamos la condición de que solo sume la línea 1 de cada grupo. ojo, para que funcione debéis transformar los valores, bien a int, adecimal o a lo que necesite para que no de error:
=Sum(IIF(Fields!Fila.Value = 1,CDbl(Fields!Horas_Previstas.Value),CDbl(0)))
Se puede solucionar haciendo una sub-consulta pero aquí vamos a explicar como mostrarlo en una única consulta.
Por ejemplo, tenemos la siguiente estructura:
Lo primero, es agregar una columna que cuente el número de registro dentro del grupo con la siguiente línea:
ROW_NUMBER() OVER (PARTITION BY Grupo ORDER BY Hijo ASC) as Fila
De esta manera sabemos cual es la línea dentro del grupo:
Ahora desde reporting es muy sencillo filtrar los datos solamente para la fila 1 de cada grupo.
Por ejemplo, podemos ocultar la línea de detalle primera y mostrarla directamente en la cabecera poniéndole la siguiente expresión de visibilidad en las líneas de detalle:
Para sumar, le agregamos la condición de que solo sume la línea 1 de cada grupo. ojo, para que funcione debéis transformar los valores, bien a int, adecimal o a lo que necesite para que no de error:
=Sum(IIF(Fields!Fila.Value = 1,CDbl(Fields!Horas_Previstas.Value),CDbl(0)))
sábado, 16 de abril de 2016
Merge filas en Reporting Services
El título de esta entrada es engañoso. Realmente no vamos a ver como se combinan celdas de varias filas, lo que vamos a ver es como simularlo para que quede algo así:
Lo primero que hay que hacer es cambiar la propiedad de la celda HideDuplicate y ponerle el ámbito del DataSet.
Esto lo que hará es que no pintará los valores repetidos, pero las líneas de separación siguen apareciendo. Ahora solamente tenemos que ocultar las líneas intermedias para simular una única casilla.
Para esto, nos situamos sobre la celda y ocultamos la línea inferior (None). La línea superior la mostramos supeditada a una función que haremos en la sección de código.
La expresión para el Top es:
=Code.FGrupoSexo(Fields!sexo.Value)
Ahora en Informe - Propiedades del Informe declaramos una variable para controlar el valor del campo sexo en el que estamos. Creamos una función sencilla en vb que pasándole el valor del campo sexo actual lo compara con el anterior y devuelve Solid o None si ha cambiado.
Para finalizalizar, creamos una línea fuera del grupo, únicamente para pintar la línea inferior del último registro de la tabla ya que esta no lo pintará nuestro código personalizado al ser la última
Lo primero que hay que hacer es cambiar la propiedad de la celda HideDuplicate y ponerle el ámbito del DataSet.
Esto lo que hará es que no pintará los valores repetidos, pero las líneas de separación siguen apareciendo. Ahora solamente tenemos que ocultar las líneas intermedias para simular una única casilla.
Para esto, nos situamos sobre la celda y ocultamos la línea inferior (None). La línea superior la mostramos supeditada a una función que haremos en la sección de código.
La expresión para el Top es:
=Code.FGrupoSexo(Fields!sexo.Value)
Ahora en Informe - Propiedades del Informe declaramos una variable para controlar el valor del campo sexo en el que estamos. Creamos una función sencilla en vb que pasándole el valor del campo sexo actual lo compara con el anterior y devuelve Solid o None si ha cambiado.
Para finalizalizar, creamos una línea fuera del grupo, únicamente para pintar la línea inferior del último registro de la tabla ya que esta no lo pintará nuestro código personalizado al ser la última
martes, 16 de febrero de 2016
Gráficos en reporting con las etiquetas en vertical
Para que las etiquetas de un gráfico salgan en vertical. Seleccionamos las etiquetas. Botón de la derecha propiedades del eje horizontal y seleccionamos la opción etiquetas:
Deshabilitamos el eje automático y le ponemos los grados de inclinación para nuestras etiquetas.
Deshabilitamos el eje automático y le ponemos los grados de inclinación para nuestras etiquetas.
miércoles, 25 de noviembre de 2015
Desactivar el Zoom en un formulario
Cuando creamos un formulario elegimos que campos son los que el usuario ve en pantalla. Mediante el Ctrl+F8 puede hacer un zoom y ver la totalidad de los campos del registro.
Si nos encontramos en la situación de que tenemos un campo cuyo valor no queremos que el usuario pueda ver, no disponemos de ningún método a priori sencillo en el formulario para evitarlo.
Se pude desactivar para un usuario concreto el Zoom con el rol object - 5330 Tools, Zoom. Pero esto lo desactiva en todas las pantallas y queremos desactivarla en una pantalla concreta.
Para estos casos, lo que se puede hacer es que en la tabla que contiene el campo con la información sensible se añade en el CaptionClass lo siguiente: '99999,2000000002'
Luego se va a la CodeUnit1 y en la función CaptionClassTranslate se añade lo siguiente:
Una opción nueva donde el CASE es el número del captionclass (En este caso el 99999):
CommaPosition := STRPOS(CaptionExpr,',');
IF (CommaPosition > 0) THEN BEGIN
CaptionArea := COPYSTR(CaptionExpr,1,CommaPosition - 1);
CaptionRef := COPYSTR(CaptionExpr,CommaPosition + 1);
CASE CaptionArea OF
'1' : EXIT(DimCaptionClassTranslate(Language,CaptionRef));
'2' : EXIT(VATCaptionClassTranslate(Language,CaptionRef));
'99999' : ERROR('');//<---------Desactivo el ZOOM
END;
END;
EXIT('');
Si nos encontramos en la situación de que tenemos un campo cuyo valor no queremos que el usuario pueda ver, no disponemos de ningún método a priori sencillo en el formulario para evitarlo.
Se pude desactivar para un usuario concreto el Zoom con el rol object - 5330 Tools, Zoom. Pero esto lo desactiva en todas las pantallas y queremos desactivarla en una pantalla concreta.
Para estos casos, lo que se puede hacer es que en la tabla que contiene el campo con la información sensible se añade en el CaptionClass lo siguiente: '99999,2000000002'
Luego se va a la CodeUnit1 y en la función CaptionClassTranslate se añade lo siguiente:
Una opción nueva donde el CASE es el número del captionclass (En este caso el 99999):
CommaPosition := STRPOS(CaptionExpr,',');
IF (CommaPosition > 0) THEN BEGIN
CaptionArea := COPYSTR(CaptionExpr,1,CommaPosition - 1);
CaptionRef := COPYSTR(CaptionExpr,CommaPosition + 1);
CASE CaptionArea OF
'1' : EXIT(DimCaptionClassTranslate(Language,CaptionRef));
'2' : EXIT(VATCaptionClassTranslate(Language,CaptionRef));
'99999' : ERROR('');//<---------Desactivo el ZOOM
END;
END;
EXIT('');
martes, 25 de agosto de 2015
Renderizar Informes desde NAvision mediante XMLHTTP sin cache
Para llamar a un informe de Reporting (O cualquier página web) utilizamos el Automation XMLHTTP.
Capturamos la respuesta y generamos un pdf (En el caso de Reporting). El problema viene que XMLHTTP guarda en cache la petición por lo que puede darse el caso que no renderice el informe con los últimos datos.
Para forzarlo añadimos en la cabecera la opción Cache-Control:no-cache.
Quedaría así:
CREATE(XMLHTTP);
XMLHTTP.open('GET','Mi_Ruta_Informe_Reporting',FALSE);
XMLHTTP.setRequestHeader('Content-Type','application/pdf');
XMLHTTP.setRequestHeader('Cache-Control', 'no-cache');
XMLHTTP.send();
IF (XMLHTTP.status = 200) THEN BEGIN CLEAR(vRespuesta);
vRespuesta := XMLHTTP.responseStream;
isArchivoRecibido := vRespuesta;
F.CREATE('c:\mifichero.pdf');
F.CREATEOUTSTREAM(osEscribeArchivoRecibido);
COPYSTREAM(osEscribeArchivoRecibido,isArchivoRecibido);
F.CLOSE;
END;
CLEAR(XMLHTTP);
Capturamos la respuesta y generamos un pdf (En el caso de Reporting). El problema viene que XMLHTTP guarda en cache la petición por lo que puede darse el caso que no renderice el informe con los últimos datos.
Para forzarlo añadimos en la cabecera la opción Cache-Control:no-cache.
Quedaría así:
Name | DataType | Subtype |
XMLHTTP | Automation | 'Microsoft XML, v3.0'.XMLHTTP |
isArchivoRecibido | InStream | |
osEscribeArchivoRecibido | OutStream | |
vRespuesta | Variant |
CREATE(XMLHTTP);
XMLHTTP.open('GET','Mi_Ruta_Informe_Reporting',FALSE);
XMLHTTP.setRequestHeader('Content-Type','application/pdf');
XMLHTTP.setRequestHeader('Cache-Control', 'no-cache');
XMLHTTP.send();
IF (XMLHTTP.status = 200) THEN BEGIN CLEAR(vRespuesta);
vRespuesta := XMLHTTP.responseStream;
isArchivoRecibido := vRespuesta;
F.CREATE('c:\mifichero.pdf');
F.CREATEOUTSTREAM(osEscribeArchivoRecibido);
COPYSTREAM(osEscribeArchivoRecibido,isArchivoRecibido);
F.CLOSE;
END;
CLEAR(XMLHTTP);
Suscribirse a:
Entradas (Atom)