jueves, 26 de septiembre de 2013

Convertir filtro de navision a SQL

Navegando por en este blog encontre una funcion de SQL para convertir un filtro de navision en una clausula where de SQL. He modificado la funcion para que tenga en cuenta los condicionantes "| ". La cuelgo a continuacion:
ALTER FUNCTION [dbo].[CONVERT_NAV_FILTER]

(

-- Add the parameters for the function here

@parFieldName VARCHAR(MAX),

@parFilter VARCHAR(MAX)

)

RETURNS VARCHAR(MAX)

AS

BEGIN



DECLARE
@CurrentStringPOSPoints INT

DECLARE @CurrentStringPOSPipe INT

DECLARE @CurrentStringPOSAmp INT

DECLARE @CurrentStringPOSAt INT

DECLARE @CurrentStringPOSNot INT

DECLARE @CurrentStringPOSHaakOpen iNT

DECLARE @CurrentStringPOSHaaksluit int

DECLARE @CurrentStringPOSStar int

DECLARE @From VARCHAR(MAX)

DECLARE @To VARCHAR(MAX)

Declare @IndexToRead INT

Declare @ObjectToRead INT

Declare @IndexRead INT

Declare @ObjectRead INT

DECLARE @NextIndexToRead INT

Declare @NextObjectToRead INT

DECLARE @FirstRun INT

DECLARE @ReturnValue VARCHAR(MAX)

SET @ReturnValue = ''

SET @IndexToRead = 0

SET @CurrentStringPOSPoints = 0

SET @CurrentStringPOSPipe = 0

SET @CurrentStringPOSAmp = 0

SET @CurrentStringPOSAt = 0

SET @CurrentStringPOSNot = 0

SET @CurrentStringPOSHaakOpen = 0

SET @CurrentStringPOSHaaksluit = 0

SET @ObjectToRead = 0

SET @IndexRead = 0

SET @FirstRun = 1

WHILE 1 = 1

BEGIN

SET
@NextIndexToRead = LEN(@parFilter)

SET @IndexToRead = LEN(@parFilter)

SET @ObjectToRead = 0

SET @NextObjectToRead = 0

--Find the index to read

IF @IndexToRead >= Charindex('..', @parFilter, @IndexRead + 1) and (Charindex('..', @parFilter, @IndexRead + 1) > 0)

BEGIN

SET @IndexToRead = Charindex('..', @parFilter, @IndexRead+1)

SET @ObjectToRead = 1

END

IF @IndexToRead >= Charindex('', @parFilter, @IndexRead + 1) and (Charindex('', @parFilter, @IndexRead + 1) > 0)

BEGIN

SET @IndexToRead = Charindex('', @parFilter, @IndexRead+1)

SET @ObjectToRead = 2

END

IF @IndexToRead >= Charindex('&', @parFilter, @IndexRead + 1) and (Charindex('&', @parFilter, @IndexRead + 1) > 0)

BEGIN

SET @IndexToRead = Charindex('&', @parFilter, @IndexRead+1)

SET @ObjectToRead = 3

END



IF @IndexToRead >= Charindex('|', @parFilter, @IndexRead + 1) and (Charindex('|', @parFilter, @IndexRead + 1) > 0)

BEGIN

SET @IndexToRead = Charindex('|', @parFilter, @IndexRead+1)

SET @ObjectToRead = 30

END



IF @IndexToRead >= Charindex('<>', @parFilter, @IndexRead + 1) and (Charindex('<>', @parFilter, @IndexRead + 1) > 0)

BEGIN

SET @IndexToRead = Charindex('<>', @parFilter, @IndexRead+1)

SET @ObjectToRead = 5

END

IF @IndexToRead >= Charindex('(', @parFilter, @IndexRead + 1) and (Charindex('(', @parFilter, @IndexRead + 1) > 0)

BEGIN

SET @IndexToRead = Charindex('(', @parFilter, @IndexRead +1)

SET @ObjectToRead = 6

END

IF @IndexToRead >= Charindex(')', @parFilter, @IndexRead + 1) and (Charindex(')', @parFilter, @IndexRead + 1) > 0)

BEGIN

SET @IndexToRead = Charindex(')', @parFilter, @IndexRead +1)

SET @ObjectToRead = 7

END

-- Find the next index to read

IF @NextIndexToRead >= Charindex('..', @parFilter, @IndexToRead + 1) and (Charindex('..', @parFilter, @IndexToRead + 1) > 0)

BEGIN

SET @NextIndexToRead = Charindex('..', @parFilter, @IndexToRead+1)

SET @NextObjectToRead = 1

END

IF @NextIndexToRead >= Charindex('', @parFilter, @IndexToRead + 1) and (Charindex('', @parFilter, @IndexToRead + 1) > 0)

BEGIN

SET @NextIndexToRead = Charindex('', @parFilter, @IndexToRead+1)

SET @NextObjectToRead = 2

END

IF @NextIndexToRead >= Charindex('&', @parFilter, @IndexToRead + 1) and (Charindex('&', @parFilter, @IndexToRead + 1) > 0)

BEGIN

SET @NextIndexToRead = Charindex('&', @parFilter, @IndexToRead+1)

SET @NextObjectToRead = 3

END

IF @NextIndexToRead >= Charindex('|', @parFilter, @IndexToRead + 1) and (Charindex('|', @parFilter, @IndexToRead + 1) > 0)

BEGIN

SET @NextIndexToRead = Charindex('|', @parFilter, @IndexToRead+1)

SET @NextObjectToRead = 30

END



IF @NextIndexToRead >= Charindex('<>', @parFilter, @IndexToRead + 1) and (Charindex('<>', @parFilter, @IndexToRead + 1) > 0)

BEGIN

SET @NextIndexToRead = Charindex('<>', @parFilter, @IndexToRead+1)

SET @NextObjectToRead = 5

END

IF @NextIndexToRead >= Charindex('(', @parFilter, @IndexToRead + 1) and (Charindex('(', @parFilter, @IndexToRead + 1) > 0)

BEGIN

SET @NextIndexToRead = Charindex('(', @parFilter, @IndexToRead+1)

SET @NextObjectToRead = 6

END

IF @NextIndexToRead >= Charindex(')', @parFilter, @IndexToRead + 1) and (Charindex(')', @parFilter, @IndexToRead + 1) > 0)

BEGIN

SET @NextIndexToRead = Charindex(')', @parFilter, @IndexToRead+1)

SET @NextObjectToRead = 7

END

-- *********************************************

-- Checks Complete start converting

-- *********************************************



-- If this is the first time the conversion is done and there is a or & sign,

-- Set a filter on the first part

IF @FirstRun = 1 and @IndexToRead > 1

BEGIN

IF @ObjectToRead = 2 --

BEGIN

SET @From = Substring(@parFilter, 1, @IndexToRead - 1)

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%'), '@', '')) + ''') OR '

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''') OR '

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''') OR '

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''') OR '

END

IF @ObjectToRead = 3 -- &

BEGIN

SET @From = Substring(@parFilter, 1, @IndexToRead - 1)

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%'), '@', '')) + ''') AND '

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''') AND '

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''') AND '

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''') AND '

END

IF @ObjectToRead = 30 -- |

BEGIN

SET @From = Substring(@parFilter, 1, @IndexToRead - 1)

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%'), '@', '')) + ''') OR '

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''') OR '

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''') OR '

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''') OR '

END

END

SET @FirstRun = 0

IF @ObjectToRead = 1 -- 1 = ..

BEGIN

SET @From = Substring(@parFilter, @IndexRead + 1, @IndexToRead - (@IndexRead + 1))

IF @nextobjecttoread = 0

SET @To = substring(@parFilter, @IndexToRead + 2 , @NextIndexToRead -(@IndexToRead + 1))

else

SET @To = substring(@parFilter, @IndexToRead + 2 , @NextIndexToRead -(@IndexToRead + 2))

if charindex('@', @From, 0) > 0 or charindex('@', @To, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') BETWEEN ''' + lower(replace(@From, '@', '')) + ''' AND ''' + lower(replace(@To,'@','')) + ''')'

ELSE

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' BETWEEN ''' + @From + ''' AND ''' + @To + ''')'

IF @NextObjectToRead = 2 --

SET @ReturnValue = @ReturnValue + ' OR '

IF @NextObjectToRead = 3 -- &

SET @ReturnValue = @ReturnValue + ' AND '



IF @NextObjectToRead = 30 -- &

SET @ReturnValue = @ReturnValue + ' OR '

END

IF @ObjectToRead = 2 -- 2 =

BEGIN

IF @NextObjectToRead <> 6 and @NextObjectToRead <> 5 and @NextObjectToRead <> 1

BEGIN

if @NextObjectToRead = 0

SET @From = substring(@parFilter, @IndexToRead + 1, @NextIndexToRead - @IndexToRead)

else

SET @From = substring(@parFilter, @IndexToRead + 1, @NextIndexToRead - (@IndexToRead + 1))

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%'), '@', '')) + ''')'

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''')'

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''')'

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''')'

END

IF @NextObjectToRead = 2 --

SET @ReturnValue = @ReturnValue + ' OR '

IF @NextObjectToRead = 3 -- &

SET @ReturnValue = @ReturnValue + ' AND '



IF @NextObjectToRead = 30 -- &

SET @ReturnValue = @ReturnValue + ' OR '

END

IF @ObjectToRead = 3 -- 3 = &

BEGIN

IF @NextObjectToRead <> 6 and @NextObjectToRead <> 5 and @NextObjectToRead <> 1

BEGIN

if @NextObjectToRead = 0

SET @From = substring(@parFilter, @IndexToRead + 1, @NextIndexToRead - @IndexToRead)

else

SET @From = substring(@parFilter, @IndexToRead + 1, @NextIndexToRead - (@IndexToRead + 1))

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%') , '@', '')) + ''')'

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''')'

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''')'

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''')'

END

IF @NextObjectToRead = 2 --

SET @ReturnValue = @ReturnValue + ' OR '

IF @NextObjectToRead = 3 -- &

SET @ReturnValue = @ReturnValue + ' AND '



IF @NextObjectToRead = 30 -- &

SET @ReturnValue = @ReturnValue + ' OR '

END

IF @ObjectToRead = 30 -- 3 = &

BEGIN

IF @NextObjectToRead <> 6 and @NextObjectToRead <> 5 and @NextObjectToRead <> 1

BEGIN

if @NextObjectToRead = 0

SET @From = substring(@parFilter, @IndexToRead + 1, @NextIndexToRead - @IndexToRead)

else

SET @From = substring(@parFilter, @IndexToRead + 1, @NextIndexToRead - (@IndexToRead + 1))

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%') , '@', '')) + ''')'

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''')'

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''')'

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''')'

END

IF @NextObjectToRead = 2 --

SET @ReturnValue = @ReturnValue + ' OR '

IF @NextObjectToRead = 3 -- &

SET @ReturnValue = @ReturnValue + ' AND '



IF @NextObjectToRead = 30 -- &

SET @ReturnValue = @ReturnValue + ' OR '

END



IF @ObjectToRead = 4 -- 4 = @

BEGIN

SET @ReturnValue = @ReturnValue

END

IF @ObjectToRead = 5 -- 5 = <>

BEGIN

SET @ReturnValue = @ReturnValue + ' NOT '

SET @From = substring(@parFilter, @IndexToRead + 2, @NextIndexToRead - (@IndexToRead + 2))

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%'), '@', '')) + ''')'

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''')'

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''')'

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''')'

IF @NextObjectToRead = 2 --

SET @ReturnValue = @ReturnValue + ' OR '

IF @NextObjectToRead = 3 -- &

SET @ReturnValue = @ReturnValue + ' AND '

END

IF @ObjectToRead = 6 -- 6 = (

BEGIN

SET @ReturnValue = @ReturnValue + '('

SET @From = Substring(@parFilter, @IndexToRead + 1, @NextIndexToRead - (@IndexToRead +1))

IF @NextObjectToRead = 2 --

BEGIN

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%'), '@', '')) + ''') OR '

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''') OR '

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''') OR '

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''') OR '

END

IF @NextObjectToRead = 3 -- &

BEGIN

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%'), '@', '')) + ''') AND '

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''') AND '

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''') AND '

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''') AND '

ENd



IF @NextObjectToRead = 30 -- &

BEGIN

if charindex('@', @From, 0) > 0

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@From, '*', '%'), '@', '')) + ''') OR '

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@From, '@', '')) + ''') OR '

else

if charindex('*', @From, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@From, '*', '%') + ''') OR '

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @From + ''') OR '

ENd

END

IF @ObjectToRead = 7 -- 7 = )

BEGIN

SET @ReturnValue = @ReturnValue + ')'

IF @NextObjectToRead = 2 --

SET @ReturnValue = @ReturnValue + ' OR '

IF @NextObjectToRead = 3 -- &

SET @ReturnValue = @ReturnValue + ' AND '



IF @NextObjectToRead = 30 -- &

SET @ReturnValue = @ReturnValue + ' OR '

END

IF @ObjectToRead = 8 -- 8 = *

BEGIN

SET @ReturnValue = @ReturnValue

END

-- Nothing found? => BREAK loop

IF @IndexToRead = LEN(@parFilter)

BREAK

SET @ObjectRead = @ObjectToRead

SET @IndexRead = @IndexToRead

SET @IndexToRead = @NextIndexToRead

END -- LOOP

IF @ReturnValue = ''

BEGIN

if charindex('@', @parFilter, 0) > 0

if charindex('*', @parFilter, 0) > 0

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') LIKE ''' + lower(replace(replace(@parFilter, '*', '%'), '@', '')) + ''')'

else

SET @ReturnValue = @ReturnValue + '(lower(' + @parFieldName + ') = ''' + lower(replace(@parFilter, '@', '')) + ''')'

else

if charindex('*', @parFilter, 0) > 0

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' LIKE ''' + replace(@parFilter, '*', '%') + ''')'

else

SET @ReturnValue = @ReturnValue + '(' + @parFieldName + ' = ''' + @parFilter + ''')'

END

-- Return the result of the function

RETURN '(' + @ReturnValue + ')'

END







martes, 24 de septiembre de 2013

Mensajes elegantes con Navision

En este post vamos a ver un tema referente a los mensajes que muestra navision con la funcion MESSAGE. Que aunque la mayoria de programadores tienen esta funcion y su manejo más que trillado, vamos a ver como estructurando el contenido a mostrar podemos hacer un mensaje elegantes utilizando un simple salto de línea.
NameDataType
c1Char
c2Char

c1:=10;
c2:=13;

MESSAGE('%1','Las opciones que estan sumando son:' + FORMAT(c1) + FORMAT(c2) + 'Amortización' + FORMAT(c1) + FORMAT(c2) +
'Indirectos Producción' + FORMAT(c1) + FORMAT(c2) + 'Mantenimiento Matricería' + FORMAT(c1) + FORMAT(c2) + 'Cargas Estructura');

El resultado sería así:

miércoles, 18 de septiembre de 2013

Recorrer registros de una tabla temporal en un Formulario

La posibilidad de definir tablas temporales en los Formularios nos permite ampliar la funcionalidad de manera que con un formulario podemos hacer casi todo lo que necesitamos para interactuar con el usuario. Este post esta pensado para ver como tratar estos datos temporales que el usuario a manipulado desde el formulario. Esta claro que en la mayoria de veces necesitaremos recorrer los datos, ahora veremos como hacer el bucle de una manera correcta.
//RangoActual es una variable de tipo record del mismo tipo que el record del formulario
RangoActual := Rec;
CurrForm.SAVERECORD;

CurrForm.UPDATE(FALSE);
RESET;
IF FINDFIRST THEN BEGIN   REPEAT
     //HAGO MIS OPERACIONES
   UNTIL NEXT = 0;
END;

GET(RangoActual.Clave);

jueves, 12 de septiembre de 2013

Crear nuestra propia funcion split en Navision

En más de una ocasión, programando con navision me he lamentado de la falta de funciones para trabajar con variables que facilita el C/AL en general y la falta de funciones para trabajar con cadenas de texto en particular. No voy a hablar en este post la de veces que me toca ir a ver  como se manipulan los Stream en ejemplos porque su manipulacion en mi opinion es enfarragosa.
En este post vamos a tratar algo tan sencillo como es simular la funcion split (Que tantos lenguajes utilizan) en Navision.
El resultado por supuesto no va a ser el mismo pero nos puede ser muy util a la hora de manejar cadenas de texto.
Cuantas veces nos ha tocado tratar de una direccion de un archivo sacar las carpetas, o el archivo en si, por ejemplo:
'C:\CARPETA\ARCHIVOS\PDF\MIPDF.pdf' nos devuelva MIPDF.pdf o 'C:\CARPETA\ARCHIVOS\PDF' o ARCHIVOS

La primera de las funciones la he llamado ExtraeSubcadena. La funcionalidad consiste en pasarla una cadena de texto con unos parámetros y que nos devuelva unaporcion de texto de esta cadena.
A esta funcion le pasaremos:
  1. Un Texto: Sera el texto que deseamos tratar.
  2. Un Caracter Separador: Nos servira de delimitador.
  3. Direccion: Es un indicador que nos informa si deseamos trocear:
    1. '<' desde el principio a la aparicion del texto deseada indicada en el parametro Posicion.
    2. '>' desde la aparicion del texto deseada indicada en el parametro Posicion hasta el final
    3. '<>' desde la aparicion del texto deseada indicada en el parametro Posicion hasta la siguiente aparición
  4. Posición: El número de aparición del texto delimitador
Funcion ExtraeSubcadena()
Parámetros:
NameDataTypeSubtype
Length
txtTextoText1024
txtSeparadorText1
DireccionText2
PosicionInteger

Variables:
NameDataTypeSubtypeTemporary
SeparadoresRecordIntegerYes
iInteger
//Buscamos las apariciones del carácter separador
Separadores.RESET;
Separadores.DELETEALL;
FOR i:=1 TO STRLEN(txtTexto) DO BEGIN
   IF COPYSTR(txtTexto,i,1) = txtSeparador THEN BEGIN
      Separadores.INIT;
      Separadores.Number := i;
      Separadores.INSERT;
   END;
END;

//Ahora tratamos el textoSeparadores.RESET;
IF Separadores.FINDFIRST THEN BEGIN   Separadores.NEXT(Posicion-1);
   IF Direccion = '<>' THEN BEGIN

     //De la posicion deseada hasta la siguiente
      txtTexto := ExtraeSubcadena(txtTexto,txtSeparador,'>',Posicion);
      IF STRPOS(txtTexto,txtSeparador) > 0 THEN BEGIN         txtTexto := ExtraeSubcadena(txtTexto,txtSeparador,'<',1);
      END;
      EXIT(txtTexto);
   END ELSE BEGIN      IF Direccion = '>' THEN BEGIN

         //De la posicion deseada hasta el final         EXIT(COPYSTR(txtTexto,Separadores.Number+1));
      END ELSE BEGIN

         //Del principio a la posicion deseada         EXIT(COPYSTR(txtTexto,1,Separadores.Number-1));
      END;
   END;
END;

EXIT('');

Una vez tenemos esta función, podemos hacer otra que nos indique cuantas veces aparece nuestro separador, la
Funcion ContarApariciones()
Parámetros:
NameDataTypeSubtype
Length
txtTextoText1024
txtSeparadorText1
DireccionText2
PosicionInteger

Variables:
NameDataTypeSubtypeTemporary
SeparadoresRecordIntegerYes
iInteger
//Buscamos las apariciones del carácter separador
Separadores.RESET;
Separadores.DELETEALL;
FOR i:=1 TO STRLEN(txtTexto) DO BEGIN
    IF COPYSTR(txtTexto,i,1) = txtSeparador THEN BEGIN
       Separadores.INIT;
       Separadores.Number := i;
      Separadores.INSERT;
    END;
END;

//Devolvemos las veces que aparece
Separadores.RESET;
IF Separadores.FINDFIRST THEN BEGIN   EXIT(Separadores.COUNT);
END;
EXIT(0);


Ahora, con la conjuncion de ambas funciones podemos de una manera elegante devolver la carpeta y el archivo de contenido en un texto de la sigiente manera:
MESSAGE('El Archivo es: %1',ExtraeSubcadena('C:\ARCHIVO\MI PDF.pdf','\','>',ContarApariciones('C:\ARCHIVO\MI PDF.pdf','\')));
MESSAGE('La carpeta es: %1',ExtraeSubcadena('C:\ARCHIVO\MI PDF.pdf','\','<',ContarApariciones('C:\ARCHIVO\MI PDF.pdf','\')));

En futuros posts veremos como hacer (Con la misma filosofia, es decir, utilizando recursividad y una tabla temporal del sistema) una funcion que sustituya uno o varios caractéres por uno o varios caractéres.

jueves, 5 de septiembre de 2013

Cambiar Impresora por defecto al imprimir un report de Navision

En este post vamos a tratar un tema que es más que sabido por desarrolladores con experiencia pero por el contrario puede venir bien a más de uno que comience a programar en Navision.
Para esto vamos a utilizar 2 tablas que hay en navision:
  1. La tabla 78 Seleccion Impresora
  2. La tabla Printer que es una tabla virtual y no esta accesible en el object designer.
La primera contiene una relación de usuario, report e impresora para definir como se imprimen los informes para los usuarios. La segunda es una tabla virtual que tiene una relacion de las impresoras del usuario y esta accesible en tiempo de ejcucion.
Con la combinacion de ambas tablas no es complicado ver la manera de asignar una impresora concreta antes de ejecutar un informe.



NameDataTypeSubtype
recImpresoraRecordPrinter
recImpresoraSeleccionRecordSelección impresora
recImpresoraSeleccionPreviaRecordSelección impresora
//Comprueba a ver si la impresora existe en el cliente, si no existe muestro un error
recImpresora.SETFILTER(Name,'EL NOMBRE DE MI IMPRESORA');
IF NOT recImpresora.FIND('-') THEN
   EXIT(FALSE);

//Buscamos una asignación previa, la guardamos para dejarlo todo como estaba y la borramos
IF recImpresoraSeleccion.GET(UPPERCASE(USERID), 50000) THEN BEGIN
   recImpresoraSeleccionPrevia.RESET;
   recImpresoraSeleccionPrevia.INIT;
   recImpresoraSeleccionPrevia.TRANSFERFIELDS(recImpresoraSeleccion);
   recImpresoraSeleccionPrevia.INSERT;
   recImpresoraSeleccion.DELETE;
END;

//Insertamos nuestra asignacion de impresora al report 50000
recImpresoraSeleccion.INIT;
recImpresoraSeleccion."Nº informe"       := 50000;
recImpresoraSeleccion."Id. usuario"      := UPPERCASE(USERID);
recImpresoraSeleccion."Nombre impresora" := 'EL NOMBRE DE MI IMPRESORA';
recImpresoraSeleccion.INSERT;


//Imprimimos nuestro informe
ReportFacturaVenta.RUNMODAL;

//Borramos nuestra asignacion
IF recImpresoraSeleccion.GET(UPPERCASE(USERID), 50000) THEN BEGIN
   recImpresoraSeleccion.DELETE;

  //Restauramos la asignacion previa
   IF DELCHR(recImpresoraSeleccionPrevia."Nombre impresora",'<>',' ') <> '' THEN BEGIN
      recImpresoraSeleccion.INIT;
      recImpresoraSeleccion."Nº informe"       := 50000;
      recImpresoraSeleccion."Id. usuario"      := UPPERCASE(USERID);
      recImpresoraSeleccion."Nombre impresora" := recImpresoraSeleccionPrevia."Nombre impresora";
      recImpresoraSeleccion.INSERT;
   END;
END;