Aquí os dejo un interesante enlace donde podréis encontrar varios tutoriales sobre programación ABAP sobre HANA.
En el momento que nuestro SAP corre sobre base de datos HANA tenemos una serie de nuevas herramientas muy poderosas. En estos tutoriales podréis ver por ejemplo como pasar a programar ABAP desde eclipse con HANA STUDIO, conocer el concepto de las CDS Views y OPEN SQL,....
Aunque vuestro sistema aun no corre sobre base de datos HANA es importante que todos estos conceptos comiencen a sonaros.....
Un lugar para compartir conocimiento con todas las personas interesadas en el universo SAP
Mostrando entradas con la etiqueta ABAP. Mostrar todas las entradas
Mostrando entradas con la etiqueta ABAP. Mostrar todas las entradas
lunes, 8 de julio de 2019
miércoles, 20 de enero de 2016
BADI ME_PURCHDOC_POSTED para Pedidos de Compra
En este post vamos a ver otra BADI a la que podemos recurrir para incluir nuestra lógica dentro del proceso de creación o modificación de un pedido de compras (ME21N, ME22N, ME22N ). Se trata de la BADI ME_PURCHDOC_POSTED.
Para los que queráis implementar la BADI y no sabéis como, os remito al anterior post donde explicamos los pasos a seguir con el ejemplo de la BADI PROCESS_PO_CUST:
Para los que queráis implementar la BADI y no sabéis como, os remito al anterior post donde explicamos los pasos a seguir con el ejemplo de la BADI PROCESS_PO_CUST:
Volviendo a nuestra BADI, diremos que solo dispone de un único método (POSTED) que se dispara cuando se ha genera el documento del pedido de compra tras grabar.
Digamos que en este punto sabemos ya, por ejemplo, si estamos creando el pedido, el numero de pedido de compras que nos va a devolver el sistema. Si ponemos un break-point en el método y creamos un pedido de compras, podremos ver que por ejemplo en la tabla interna IM_EKKO ya aparece el numero de pedido de compra que ha generado el sistema.
Si revisamos los parámetros que tiene el método nos llevaremos una agradable sorpresa. Tenemos disponible toda la información del pedido, pero ademas, tenemos todas las tablas internas desdobladas con una versión "OLD". ¿Esto que quiere decir? Pues por ejemplo, podremos saber si nos han modificado un campo en concreto durante la modificación de un pedido. Imaginaros que si detectamos que el usuario modifica el precio de alguna de las lineas automáticamente el sistema debe enviar un mail al responsable de compras para que lo revise. Sin duda esta sería nuestra BADI.
Desde luego que es una BADI muy potente que nos puede dar mucho juego. Muy recomendable conocerla y saber como poder sacarle partido.
sábado, 16 de enero de 2016
BADI ME_PROCESS_PO_CUST para pedidos de compra
En este post vamos a ver una de las BADI´s mas utilizadas dentro de SAP. No es otro que la BADI ME_PROCESS_PO_CUST que se utiliza para incluir funcionalidad dentro de los pedidos de compra (ME21N, ME22N, ME23N) a través de los diferentes métodos que pone a nuestra disposición.
Para los que no tengáis claro que es una BADI os dejo el siguiente link del blog donde ya hablamos sobre ellas:
Para los que no tengáis claro que es una BADI os dejo el siguiente link del blog donde ya hablamos sobre ellas:
El primer paso si queremos utilizar esta BADI sería implementarla y activarla. Para ello debemos utilizar la transacción SE19. Aquí introduciremos el nombre de la BADI y pulsaremos sobre el botón "IMPLEMENTAR" como se ve en la siguiente imagen:
Tras esto el sistema nos pedirá que asignemos un nombre a nuestra implementación.
Tras aceptar el sistema nos mostrará la implementación que se va a crear. Podremos ver todos los métodos que están disponibles y en los que vamos a poder introducir código. Además nos va a mostrar la clase sobre la que vamos a trabajar para introducir nuestra lógica. En nuestro caso la clase se va a llamar ZCL_IM_ME_PROCESS_PO_CUST.
Finalmente grabamos y activamos. Ahora ya tenemos implementada la BADI y vamos a poder comenzar a introducir nuestro código a través de la clase que hemos comentado anteriormente. Para modificar la clase ejecutamos la transacción SE24.
Dentro veremos todos los metodos disponibles sobre los que vamos a poder trabajar.
En este punto ya lo que hace falta es identificar cual de los método se adecua mas a lo que necesitamos. Como veis hay unos cuentos y cada uno se ejecuta en un punto diferente de la ejecución. Os comento algunos de ellos:
- IF_EX_ME_PROCESS_PO_CUST~PROCESS_HEADER: Se lanza cuando modificamos algún dato de cabecera y por ejemplo el usuario presiona enter.
- IF_EX_ME_PROCESS_PO_CUST~PROCESS_ITEM: Se lanza cuando modificamos algún dato a nivel de linea y por ejemplo el usuario presiona enter.
- IF_EX_ME_PROCESS_PO_CUST~PROCESS_ACCOUNT: Se utiliza para tratar los datos de imputación que haya introducido el usuario. Por ejemplo podemos utilizarlo para chequear un centro de coste o una cuenta en función del material.
- IF_EX_ME_PROCESS_PO_CUST~CHECK: Como su nombre indica es un método marcado para realizar controles. Tiene un parámetro de salida que nos permite marcar la ejecución como errónea.
Podéis ir explorando el resto. Mi recomendación es que cuando necesitéis incluir lógica marquéis breakpoints en los diferentes métodos y ejecutéis la creación ó modificación de un pedido de compras. De esta forma veréis donde para cada método y que información traen sus parámetros. De está forma va a ser mas sencillo decidir donde introducir vuestro código.
martes, 7 de julio de 2015
Como "burlar" la falta de autorización a una transacción SAP
A veces nos podemos encontrar con la necesidad de ejecutar una transacción a la que no tenemos permisos. Si eres un usuario de negocio, lamentablemente, deberás pedir acceso a quien corresponda dentro de tu compañía y si tienes suerte puede que consigas los permisos necesarios.
Si estamos hablando de usuarios desarrolladores seguramente tengamos privilegios para utilizar nuestro querido "/h" y haciendo debugging lleguemos a conseguir ejecutar la transacción que necesitamos. Evidentemente, si somo puristas, lo correcto sería solicitar acceso de manera formal.
Lo que os quiero enseñar en este post es otra alternativa, el modulo de funciones ALINK_CALL_TRANSACTION.
Imaginemos que queremos acceder a la transacción IW31 y nos encontramos con que no tenemos autorización para acceder.
Para conseguir la autorización para ejecutar la transacción no tenemos mas que modificar el valor de la variable sy-subrc tras la ejecución del modulo de funciones AUTHORITY_CHECK_TCODE
Si estamos hablando de usuarios desarrolladores seguramente tengamos privilegios para utilizar nuestro querido "/h" y haciendo debugging lleguemos a conseguir ejecutar la transacción que necesitamos. Evidentemente, si somo puristas, lo correcto sería solicitar acceso de manera formal.
Lo que os quiero enseñar en este post es otra alternativa, el modulo de funciones ALINK_CALL_TRANSACTION.
Imaginemos que queremos acceder a la transacción IW31 y nos encontramos con que no tenemos autorización para acceder.
Ejecutaríamos la transacción SE37 e introduciríamos el modulo de funciones ALINK_CALL_TRANSACTION. Tras esto ejecutamos.
Como parámetro de entrama introducimos el código de la transacción a la que no tenemos acceso. Ejecutamos en modo Debugging.
Para conseguir la autorización para ejecutar la transacción no tenemos mas que modificar el valor de la variable sy-subrc tras la ejecución del modulo de funciones AUTHORITY_CHECK_TCODE
Finalizamos la ejecución del modulo de funciones y veremos como podemos acceder a la transacción deseada.
Por ultimo remarcar que el uso de esta opción debe realizarse con cuidado. Es responsabilidad de quien lo ejecuta las posibles consecuencias que puede tener. Siempre lo mas correcto es solicitar de manera formal que nos concedan el acceso.
viernes, 24 de abril de 2015
Como crear y usar funciones de acceso remoto RFC en SAP
En este post os voy a explicar como podemos crear y utilizar módulos de funciones con acceso remoto. ¿Esto que quiere decir? Que el módulo de funciones que creemos será accesible desde otros sistemas SAP.
Por ejemplo, si tenemos SAP BW, podríamos llamar a un módulos de funciones que tengamos definido en SAP R/3 y utilizarlo. Para ello el módulo de funciones debe estar definido de una forma determinada. Es una buena opcion, por ejemplo, si necesitamos obtener cierta información que se encuentra en otro sistema.
Cuando nosotros queramos utilizar esta funcionalidad lo primero que debemos hacer es definir una RFC entre los dos sistemas. Para ello utilizamos la transacción SM59. Realizamos los siguientes pasos:
Por ejemplo, si tenemos SAP BW, podríamos llamar a un módulos de funciones que tengamos definido en SAP R/3 y utilizarlo. Para ello el módulo de funciones debe estar definido de una forma determinada. Es una buena opcion, por ejemplo, si necesitamos obtener cierta información que se encuentra en otro sistema.
Cuando nosotros queramos utilizar esta funcionalidad lo primero que debemos hacer es definir una RFC entre los dos sistemas. Para ello utilizamos la transacción SM59. Realizamos los siguientes pasos:
- Ejecutamos la transacción SM59.
- Pulsamos sobre el botón "CREAR" en la barra de menú.
- Damos un nombre a nuestra RFC
- Seleccionamos la opción "CONNECTION TO ABAP SYSTEM" en el campo tipo de conexión.
- Marcamos una descripción (Pequeña explicación de la RFC)
- Rellenamos la pestaña con los datos técnicos del sistema con el que vamos a montar el RFC
- Finalmente en la pestaña de logon insertamos un usuario y contraseña validos para poder establecer la conexión.
Una vez hemos definido la RFC podemos utilizar el botón "Test de conexión" para comprobar que funciona correctamente.
Una vez tenemos definida la RFC entre los dos sistemas podemos llamar a los módulos de funciones que tengan acceso remoto. Para ello, simplemente tenemos que añadir a la llamada de la función la clausula "DESTINATION" y el nombre del sistema fuente.
No podemos llamar a cualquier modulo de funciones, solo aquellos que estén definidos como funciones de acceso remoto. Para ello debe tener marcada la opción que vemos en la siguiente imagen:
martes, 3 de marzo de 2015
Como guardar datos de test cuando probamos un módulo de funciones
En este post vamos a ver como podemos guardar un juego de datos cuando estamos testando un módulo de funciones. En muchas ocasiones ejecutamos desde la transacción SE37 módulos de funciones, ya sean estándar o construidos por nosotros mismos. Cada vez que queremos ejecutarlo debemos escribir los parámetros necesarios.
Si repetimos la ejecución varias veces se vuelve muy tedioso escribir cada vez los parámetros. Por está razón SAP nos permite guardar los juegos de datos y cargarlos siempre que queramos ejecutar el módulo de funciones. Lo vemos con un ejemplo.
Ejecutamos la transacción SE37 y seleccionamos el modulo de funciones que vamos a ejecutar en test. Presionamos sobre
para comenzar la ejecución en test. En está primera ejecución rellenamos todos los parámetros a mano. Una vez tenemos todos los parámetros cargados presionamos sobre el botón "SAVE" de la barra de menú. Se nos abrirá un pop-up pidiéndonos que escribamos una descripción para el juego de datos.
Si repetimos la ejecución varias veces se vuelve muy tedioso escribir cada vez los parámetros. Por está razón SAP nos permite guardar los juegos de datos y cargarlos siempre que queramos ejecutar el módulo de funciones. Lo vemos con un ejemplo.
Ejecutamos la transacción SE37 y seleccionamos el modulo de funciones que vamos a ejecutar en test. Presionamos sobre
para comenzar la ejecución en test. En está primera ejecución rellenamos todos los parámetros a mano. Una vez tenemos todos los parámetros cargados presionamos sobre el botón "SAVE" de la barra de menú. Se nos abrirá un pop-up pidiéndonos que escribamos una descripción para el juego de datos.
Una vez escrita la descripción, grabamos. Podemos grabar cuantos juegos de datos sean necesarios. Cuando volvamos a ejecutar el módulo de funciones abriremos el directorio de datos de test que nos mostrará un listado con todos los que estén disponibles.
Damos doble clic sobre el que queramos cargar y automáticamente nos rellenará todos los parámetros para que podamos ejecutar el módulo de funciones.
sábado, 7 de febrero de 2015
Como crear plantillas de código ABAP utilizado frecuentemente
Es muy frustrante para un desarrollador escribir los mismos bloques de código una y otra vez. Para resolver este problema, el editor ABAP tiene una función de plantilla de código que te permite utilizar plantillas predefinidas o crear tus propias plantillas interactivas. También nos da la posibilidad de crear plantillas con porciones de código que ya tenemos escritas.
En este post vamos a ver cómo utilizar esta función para reducir la cantidad de tiempo que dedicamos a escribir bloques de código de uso frecuente.
Por defecto en el editor ABAP tenemos activada la característica de plantillas de código. Por ejemplo cuando utilizamos palabras clave como WHILE, LOOP, IF, etc. el editor nos marca con una flechita roja la palabra clave indicándonos que por defecto se dispone de una plantilla.
Se nos abrirá un editor donde podremos insertar el código que queramos. Lo insertamos y grabamos.
En este post vamos a ver cómo utilizar esta función para reducir la cantidad de tiempo que dedicamos a escribir bloques de código de uso frecuente.
Por defecto en el editor ABAP tenemos activada la característica de plantillas de código. Por ejemplo cuando utilizamos palabras clave como WHILE, LOOP, IF, etc. el editor nos marca con una flechita roja la palabra clave indicándonos que por defecto se dispone de una plantilla.
Cuando aparece este símbolo, podemos presionar la combinación de teclas Ctrl + Enter o TAB para que se nos inserte la plantilla de código. Por ejemplo si utilizamos la palabra clave CASE el resultado sería el siguiente:
Por ejemplo tenemos algunos comandos que nos habilitan plantillas para comentarios. Si escribimos *** o *-- el editor nos propondrá plantillas.
Podemos ver la lista de plantillas predefinidas si pulsamos sobre el botón "Opciones" que se encuentra en la esquina inferior derecha del editor ABAP.
Desde esta misma pantalla podemos crear y tratar nuestras propias plantillas predefinidas. Para ello tenemos las opciones disponibles de "Añadir", "Modificar" y "Borrar".
Otra interesante opción que nos da está funcionalidad es la de poder introducir tags o variables predefinidas que nos aportan algo de funcionalidad a nuestra plantilla.
Las opciones disponibles son:
- Date Time
- Clipboard
- Surrounded Text
- Document Name
- Interactive
Estas opciones nos permitirán insertar automáticamente Fecha/Hora o el nombre del progrma. Incluso podemos insertar variables en la plantilla. Cuando insertemos la plantilla en nuestro código el sistema muestra un popup para que marquemos el valor de dichas variables.
Un ejemplo de plantilla podría ser el siguiente:
"<Y0UR NAME %Date Time% >
“%Additional Info %
% Surrounded Text %
"</Y0UR NAME %Date Time%>
Sería interesante por ejemplo cuando hacemos un cambio en el código y lo queremos dejar marcado. Utilizaríamos la variable "Additional Info" para introducir la explicación del cambio.
Otra forma, también muy interesante, para crearnos plantillas es utilizar la funcionalidad de modelos que nos proporciona SAP. De por si esta funcionalidad nos permite insertar casi cualquier objeto que esté creado en el sistema (Módulos de funciones, métodos de clases, etc.). Pero además nos deja crear nuestros propias plantillas. Para crearnos una debemos seguir la siguiente ruta:
Le damos un nombre a nuestro patrón.
Se nos abrirá un editor donde podremos insertar el código que queramos. Lo insertamos y grabamos.
El último paso sería cargar en nuestro programa la plantilla creada a través de la funcionalidad de "Modelo".
lunes, 26 de enero de 2015
Como buscar objetos en la ordenes y tareas de transporte
En este post vamos a ver como podemos buscar objetos de desarrollo en las ordenes y tareas de transporte. Cuando modificamos objetos de desarrollo SAP organiza estos cambios en la ordenes de transporte. Durante la vida de un desarrollo pueden llegar a producirse múltiples modificaciones y por lo tanto tener múltiples ordenes de transporte. Es en estos casos cuando puede llegar a ser necesario tener una traza de todas las modificaciones que se han producido sobre un determinado objeto. Un ejemplo podría ser una auditoria, donde se nos pide la traza de todas las modificaciones sobre un determinado programa.
SAP nos proporciona una herramienta para poder realizar estas búsquedas. Para ejecutarla debemos acceder a la transacción SE03. Dentro de esta debemos ejecutar la opción "Buscar objetos en órdenes/tareas".
SAP nos presenta una pantalla de selección con diferentes parámetros a rellenar. En la primera parte podemos indicar el tipo de objeto que queremos buscar (Programas, grupos de funciones, tablas, etc.), además de poder filtrar por el nombre del objeto.
Podemos elegir cualquier tipo de objeto disponible en el sistema. También es posible buscar objetos de Customazing.
Además de poder indicar el tipo del objeto a buscar y su nombre, la transacción nos proporciona otros parámetros de selección como son:
- Nº de Orden/Tarea
- Titular
- Fecha
- Status de la orden/tarea
Tras hacer nuestra selección ejecutamos y la transacción nos devuelve un listado don todas las ordenes donde se ha encontrado el objeto buscado.
jueves, 22 de enero de 2015
Creación de documentación para los objetos de desarrollo en SAP
En este post vamos a ver como podemos crear documentación sobre los objetos que vamos desarrollando en SAP, por ejemplo un programa ABAP. Primero veremos como podemos crearla y finalmente como acceder a ella posteriormente.
Preparar una buena documentación técnica es una de las fases más importantes de los proyectos de desarrollo (Aunque muchas veces por las prisas es una de las grandes olvidadas....). Por ejemplo, cuando tenemos que modificar un programa que nosotros mismos u otra persona desarrolló hace mucho tiempo, es de agradecer tener una buena documentación del programa antes de modificar el código fuente. Sin embargo, no siempre es fácil encontrar las especificaciones técnicas de los programas de después de mucho tiempo.
Para crear la documentación debemos abrir nuestro programa, por ejemplo con la transacción SE38 y utilizar la siguiente ruta:
Preparar una buena documentación técnica es una de las fases más importantes de los proyectos de desarrollo (Aunque muchas veces por las prisas es una de las grandes olvidadas....). Por ejemplo, cuando tenemos que modificar un programa que nosotros mismos u otra persona desarrolló hace mucho tiempo, es de agradecer tener una buena documentación del programa antes de modificar el código fuente. Sin embargo, no siempre es fácil encontrar las especificaciones técnicas de los programas de después de mucho tiempo.
Para crear la documentación debemos abrir nuestro programa, por ejemplo con la transacción SE38 y utilizar la siguiente ruta:
Hay diferentes versiones del Editor de textos en función de la versión de SAP que tengamos instalada. Os dejo un pantallazo de diferentes tipos:
Como podéis ver en cada versión el entorno del editor es mucho mas agradable. La primera vez que abrimos la documentación de un programa, por defecto, SAP nos propone diferentes secciones donde poder incluir diferente información sobre nuestros programa. Introducimos toda la información que creemos necesaria y finalmente grabamos.
La siguiente vez que volvamos a abrir la documentación SAP nos mostrará la información. A modo de ejemplo os dejo la siguiente imagen:
martes, 20 de enero de 2015
Comparar dos programas ABAP en entornos diferentes
A veces nos encontramos con que el mismo programa tiene un comportamiento diferente en el entorno de Producción y el de Integración, por ejemplo. Puede ser muy útil comparar el código de este programa en cada entorno con el fin de encontrar posibles errores o inconsistencias en el código.
Puede suceder también que el programa tenga diferente nivel de parches en un entorno que en otro.
De cualquiera de las formas SAP nos da la posibilidad de comprar el código del programa utilizando la gestión de versiones.
El primer paso sería abrir nuestro programa a través de la transacción SE38. Tras esto navegamos por el menú hasta la gestión de versiones.
Puede suceder también que el programa tenga diferente nivel de parches en un entorno que en otro.
De cualquiera de las formas SAP nos da la posibilidad de comprar el código del programa utilizando la gestión de versiones.
El primer paso sería abrir nuestro programa a través de la transacción SE38. Tras esto navegamos por el menú hasta la gestión de versiones.
En este punto pulsamos sobre "Comparación REMOTE".
Nos aparecerá un popup donde debemos indicar contra que sistema vamos a comparar. Tenemos dos opciones:
- Sistema Dest: Podremos indicar cualquiera de los sistemas SAP que tenemos disponibles (Desarrollo, Integración, Producción, etc.)
- Destino RFC: Podremos indicar una RFC que se comunique con algún otro sistema.
En este ejemplo vamos a indicar otro sistema que tenemos disponible, por ejemplo Integración
Finalmente el sistema nos muestra el resultado de la comparación. Hará una separación de aquellas líneas del código en las que encuentre diferencias.
Tenemos diferentes opciones para ir recorriendo el programa. Por ejemplo podemos ir pasando por las diferentes secciones del código que presentas diferencias, por las que son idénticas. También te da la posibilidad de configurar algunos aspectos como ignorar los comentarios, las secciones idénticas, etc.
miércoles, 10 de diciembre de 2014
Como incluir un editor de texto en nuestro programa
En este post os voy a enseñar una sencilla función que nos permite habilitar un editor de textos donde podremos mostrar un texto (Por ejemplo leido con la funcion READ_TEXT) o simplemente habilitar al usuario un espacio donde el pueda escribir lo que desee.
La función que vamos a utilizar es CATSXT_SIMPLE_TEXT_EDITOR. Como veis los parámetros a pasar son muy sencillos:
En la tabla CH_TEXT será donde insertaremos el texto a mostrar o de donde recogeremos el texto introducido por el usuario. Por ejemplo puede que queramos mostrar un texto en modo no editable, simplemente a nivel informativo, o puede que queramos dejar en blanco el editor de texto para que el usuario introduzca lo que quiera.
El resultado final de ejecutar el módulo de función es el siguiente:
En otro post veremos como podemos incluir en una dynpro un editor de texto como un elemento mas de la ventana. En este caso el editor de textos realmente se lanza como si fuera un pop-up. Es una alternativa mas.
La función que vamos a utilizar es CATSXT_SIMPLE_TEXT_EDITOR. Como veis los parámetros a pasar son muy sencillos:
- Titulo
- Modo de edición: Editable/No Editable
- Posición relativa de la ventana
En la tabla CH_TEXT será donde insertaremos el texto a mostrar o de donde recogeremos el texto introducido por el usuario. Por ejemplo puede que queramos mostrar un texto en modo no editable, simplemente a nivel informativo, o puede que queramos dejar en blanco el editor de texto para que el usuario introduzca lo que quiera.
El resultado final de ejecutar el módulo de función es el siguiente:
En otro post veremos como podemos incluir en una dynpro un editor de texto como un elemento mas de la ventana. En este caso el editor de textos realmente se lanza como si fuera un pop-up. Es una alternativa mas.
lunes, 8 de diciembre de 2014
Introducción ABAP. Instrucciones básicas
Continuamos en este post con la introducción a ABAP. En este caso vamos a comentar las instrucciones mas básicas que podemos realizar.
Asignación
Existen varias formas de asignar a una variable:
-Asignación directa: <variable> = valor.
El valor se puede especificar como un literal, el contenido de una constante o el contenido de una variable.
-Sentencia MOVE: Asigna un valor a una variable.
MOVE <valor> TO <variable>.
-Sentencia MOVE-CORRESPONDING: Mueve el contenido de los campos de una estructura a los campos que tengan el mismo nombre de otra estructura.
MOVE-CORRESPONDING <origen> TO <destino>.
-Sentencia CLEAR: Inicializa el contenido de un campo a su valor inicial según el tipo de dato.
CLEAR <campo>.
-OFFSETS: Se puede hacer referencia parcial a una parte de un campo, indicando el número de posiciones que hay hasta la posición en la que se comienza a referenciar utilizando + y la cantidad de posiciones que se referencia entre paréntesis.
MOVE <campo1> + <posiciones>(longitud) TO <campo2>.
Ejemplo: DATA: d_dato1(8) TYPE c VALUE ‘ABCDEF’,
d_dato2(4) TYPE c.
d_dato2 = d_dato1+2(4).
Ahora d_dato2 = ‘CDEF’.
Condicionales
Operadores condicionales.
Igual: <valor1> EQ <valor2>
<valor1> = <valor2>
No igual: <valor1> NE <valor2>
<valor1> <> <valor2>
Mayor: <valor1> GT <valor2>
<valor1> > <valor2>
Menor: <valor1> LT <valor2>
<valor1> < <valor2>
Mayor o igual: <valor1> GE <valor2>
<valor1> >= <valor2>
Menor o igual: <valor1> LE <valor2>
<valor1> <= <valor2>
<valor1> BETWEEN <valor2> AND <valor3>.
<valor1> IS INITIAL. Si tiene el valor inicial.
<valor> IN <rango>. Si <valor> tiene un valor comprendido en el rango <rango>
Operadores lógicos.
<condicion1> AND <condicion2>
< condicion1> OR <condicion2>
NOT <condición>.
Sentencias IF <condición> ..... ENDIF.
Ejemplo: IF NOT d_dato IS INITIAL.
WRITE d_dato.
ENDIF.
Escribe por pantalla el valor introducido en d_dato si se recibe un valor distinto del inicial.
Sentencias CASE <variable>.......ENDCASE.
Permiten ejecutar diferentes grupos de sentencias en función del valor contenido en <variable>, delimitando las sentencias con la cláusula WHEN <valor>.
El valor OTHERS comprende todos los valores que no hayan sido especificados en las anteriores cláusulas WHEN.
Ejemplo: CONSTANTS: c_centrado TYPE c VALUE ‘c’,
c_izquierda TYPE c VALUE ‘i’,
c_derecha TYPE c VALUE ‘d’.
DATA: d_alineación TYPE c,
d_texto(100) TYPE c.
CASE d_alineación.
WHEN c_centrado.
WRITE d_texto CENTERED.
WHEN c_izquierda.
WRITE d_texto LEFT-JUSTIFIED.
WHEN c_derecha.
WRITE d_texto RIGHT-JUSTIFIED.
WHEN OTHERS.
WRITE d_texto.
ENDCASE.
Operadores condicionales para cadenas de texto.
<cadena1> CO <cadena2> Si todos los caracteres, incluidos los espacios de 1, están en 2.
Si la condición es cierta, la variable SY-FDPOS contendrá la longitud de <cadena1>, sino, contiene el OFFSET del primer carácter de <cadena1> que no existe en <cadena2>.
<cadena1> CN <cadena2> Si existe algún carácter en 1 que no está en 2, incluido espacios.
Si la condición es cierta, la variable SY-FDPOS contendrá el OFFSET del primer carácter de <cadena1> que no existe en <cadena2>, sino, contiene la longitud de <cadena1>.
<cadena1> CA <cadena2> Si alguno de 1 incluido espacios, está en <cadena2>.
Si la condición es cierta, la variable SY-FDPOS contendrá el OFFSET del primer carácter de <cadena1> que existe en <cadena2>, sino, contiene la longitud de <cadena1>.
<cadena1> NA <cadena2> Si ninguno de los caracteres de <cadena1>, está en <cadena2>.
Si la condición es cierta, la variable SY-FDPOS contendrá la longitud de <cadena1>, sino, contendrá el OFFSET del primer carácter de <cadena1> que existe en <cadena2>.
<cadena1> CS <cadena2> La condición se cumple si <cadena1> contiene a <cadena2>.
Si la condición es cierta, la variable SY-FDPOS contendrá el OFFSET del primer carácter de <cadena2> que existe en <cadena1>, sino, contiene la longitud de <cadena1>.
<cadena1> NS <cadena2>. La condición se cumple si <cadena1> no contiene a <cadena2>.
Si la condición es cierta, la variable SY-FDPOS contendrá la longitud de <cadena1>, sino, contendrá el OFFSET del primer carácter de <cadena2> que existe en <cadena1>.
<cadena> CP <patrón>. La condición se cumple si <cadena> contiene el patrón de búsqueda <patrón>. Este patrón permite utilizar el carácter * para representar cualquier cadena de caracteres y + para representar cualquier carácter.
Si la condición es cierta, la variable SY-FDPOS contendrá el OFFSET del primer carácter de <patrón> que existe en <cadena>, sino, contiene la longitud de <cadena>.
Ejemplo: La condición ‘Jose Luis Diaz’ CP ‘Jose*Diaz’ es verdadera y devuelve 0 en SY-FDPOS. La condición ‘JoseLuisDiaz’CP ‘Jose+Luis’ es falsa y devuelve 12 en SY-FDPOS.
<cadena> NP <patrón>. La condición se cumple si <cadena> no contiene el patrón de búsqueda <patrón>.
Si la condición es cierta, la variable SY-FDPOS contendrá la longitud de <cadena>, sino, contendrá el OFFSET del primer carácter de <patrón> que existe en <cadena>.
Asignación
Existen varias formas de asignar a una variable:
-Asignación directa: <variable> = valor.
El valor se puede especificar como un literal, el contenido de una constante o el contenido de una variable.
-Sentencia MOVE: Asigna un valor a una variable.
MOVE <valor> TO <variable>.
-Sentencia MOVE-CORRESPONDING: Mueve el contenido de los campos de una estructura a los campos que tengan el mismo nombre de otra estructura.
MOVE-CORRESPONDING <origen> TO <destino>.
-Sentencia CLEAR: Inicializa el contenido de un campo a su valor inicial según el tipo de dato.
CLEAR <campo>.
-OFFSETS: Se puede hacer referencia parcial a una parte de un campo, indicando el número de posiciones que hay hasta la posición en la que se comienza a referenciar utilizando + y la cantidad de posiciones que se referencia entre paréntesis.
MOVE <campo1> + <posiciones>(longitud) TO <campo2>.
Ejemplo: DATA: d_dato1(8) TYPE c VALUE ‘ABCDEF’,
d_dato2(4) TYPE c.
d_dato2 = d_dato1+2(4).
Ahora d_dato2 = ‘CDEF’.
Condicionales
Operadores condicionales.
Igual: <valor1> EQ <valor2>
<valor1> = <valor2>
No igual: <valor1> NE <valor2>
<valor1> <> <valor2>
Mayor: <valor1> GT <valor2>
<valor1> > <valor2>
Menor: <valor1> LT <valor2>
<valor1> < <valor2>
Mayor o igual: <valor1> GE <valor2>
<valor1> >= <valor2>
Menor o igual: <valor1> LE <valor2>
<valor1> <= <valor2>
<valor1> BETWEEN <valor2> AND <valor3>.
<valor1> IS INITIAL. Si tiene el valor inicial.
<valor> IN <rango>. Si <valor> tiene un valor comprendido en el rango <rango>
Operadores lógicos.
<condicion1> AND <condicion2>
< condicion1> OR <condicion2>
NOT <condición>.
Sentencias IF <condición> ..... ENDIF.
Ejemplo: IF NOT d_dato IS INITIAL.
WRITE d_dato.
ENDIF.
Escribe por pantalla el valor introducido en d_dato si se recibe un valor distinto del inicial.
Sentencias CASE <variable>.......ENDCASE.
Permiten ejecutar diferentes grupos de sentencias en función del valor contenido en <variable>, delimitando las sentencias con la cláusula WHEN <valor>.
El valor OTHERS comprende todos los valores que no hayan sido especificados en las anteriores cláusulas WHEN.
Ejemplo: CONSTANTS: c_centrado TYPE c VALUE ‘c’,
c_izquierda TYPE c VALUE ‘i’,
c_derecha TYPE c VALUE ‘d’.
DATA: d_alineación TYPE c,
d_texto(100) TYPE c.
CASE d_alineación.
WHEN c_centrado.
WRITE d_texto CENTERED.
WHEN c_izquierda.
WRITE d_texto LEFT-JUSTIFIED.
WHEN c_derecha.
WRITE d_texto RIGHT-JUSTIFIED.
WHEN OTHERS.
WRITE d_texto.
ENDCASE.
Operadores condicionales para cadenas de texto.
<cadena1> CO <cadena2> Si todos los caracteres, incluidos los espacios de 1, están en 2.
Si la condición es cierta, la variable SY-FDPOS contendrá la longitud de <cadena1>, sino, contiene el OFFSET del primer carácter de <cadena1> que no existe en <cadena2>.
<cadena1> CN <cadena2> Si existe algún carácter en 1 que no está en 2, incluido espacios.
Si la condición es cierta, la variable SY-FDPOS contendrá el OFFSET del primer carácter de <cadena1> que no existe en <cadena2>, sino, contiene la longitud de <cadena1>.
<cadena1> CA <cadena2> Si alguno de 1 incluido espacios, está en <cadena2>.
Si la condición es cierta, la variable SY-FDPOS contendrá el OFFSET del primer carácter de <cadena1> que existe en <cadena2>, sino, contiene la longitud de <cadena1>.
<cadena1> NA <cadena2> Si ninguno de los caracteres de <cadena1>, está en <cadena2>.
Si la condición es cierta, la variable SY-FDPOS contendrá la longitud de <cadena1>, sino, contendrá el OFFSET del primer carácter de <cadena1> que existe en <cadena2>.
<cadena1> CS <cadena2> La condición se cumple si <cadena1> contiene a <cadena2>.
Si la condición es cierta, la variable SY-FDPOS contendrá el OFFSET del primer carácter de <cadena2> que existe en <cadena1>, sino, contiene la longitud de <cadena1>.
<cadena1> NS <cadena2>. La condición se cumple si <cadena1> no contiene a <cadena2>.
Si la condición es cierta, la variable SY-FDPOS contendrá la longitud de <cadena1>, sino, contendrá el OFFSET del primer carácter de <cadena2> que existe en <cadena1>.
<cadena> CP <patrón>. La condición se cumple si <cadena> contiene el patrón de búsqueda <patrón>. Este patrón permite utilizar el carácter * para representar cualquier cadena de caracteres y + para representar cualquier carácter.
Si la condición es cierta, la variable SY-FDPOS contendrá el OFFSET del primer carácter de <patrón> que existe en <cadena>, sino, contiene la longitud de <cadena>.
Ejemplo: La condición ‘Jose Luis Diaz’ CP ‘Jose*Diaz’ es verdadera y devuelve 0 en SY-FDPOS. La condición ‘JoseLuisDiaz’CP ‘Jose+Luis’ es falsa y devuelve 12 en SY-FDPOS.
<cadena> NP <patrón>. La condición se cumple si <cadena> no contiene el patrón de búsqueda <patrón>.
Si la condición es cierta, la variable SY-FDPOS contendrá la longitud de <cadena>, sino, contendrá el OFFSET del primer carácter de <patrón> que existe en <cadena>.
viernes, 28 de noviembre de 2014
Introducción ABAP. Subrutinas
Continuamos repasando los conceptos básicos de ABAP, el lenguaje de programación de SAP. En este post vamos a hablar de las subrutinas.
Las subrutinas son conjuntos de instrucciones que pueden ser llamadas desde el programa en diversas ocasiones.
Para definirlas se utilizan las palabras clave FORM y ENDFORM que se especifican al inicio y final de las instrucciones que forman la subrutina. Para llamarla se utiliza la sentencia PERFORM.
Ejemplo: PERFORM ejemplo. Llama a la subrutina.
.......
FORM ejemplo. Definición de la subrutina.
-----
ENDFORM.
El programa principal y la subrutina se pueden comunicar mediante parámetros pasados por valor o referencia, siendo recomendable especificar el tipo de dato al definirlo.
Pase de parámetros por referencia
PERFORM <nombre> USING parametro1 parametro2.
.....
FORM <nombre> USING parametro1 parametro2.
----
ENDFORM.
Los parámetros que son pasados a la subrutina en la llamada (FORMALES), se actualizan con los parámetros (ACTUALES) definidos en la subrutina.
Ejemplo: DATA: d_numero1 TYPE i VALUE 1,
d_numero2 TYPE i VALUE 2.
PERFORM sumar USING d_numero1 d_numero2.
….
FORM sumar USING l_numero1 type i
l_numero2 type i.
l_numero1 = l_numero1 + l_numero2.
ENDFORM.
Ahora: d_numero1 = 3 y d_numero2 = 2.
Pase de parámetros por referencia
PERFORM <nombre> USING parametro1 parametro2.
.....
FORM <nombre> USING VALUE (parametro1) VALUE(parametro2).
----
ENDFORM.
Los parámetros que son pasados a la subrutina no se actualizan con el valor de los parámetros definidos en la subrutina.
Ejemplo: DATA: d_numero1 TYPE i VALUE 1,
d_numero2 TYPE i VALUE 2.
PERFORM sumar USING d_numero1 d_numero2.
….
FORM sumar USING l_numero1 type i
Value( l_numero2) type i.
l_numero2 = 3.
l_numero1 = l_numero1 + l_numero2.
ENDFORM.
Ahora: d_numero1 = 4 y d_numero2 = 2.
Utilizando STRUCTURE se puede pasar como parámetro una estructura y hace referencia a sus campos en la subrutina.
Ejemplo: DATA: BEGIN OF r_provincias,
Codigo LIKE lfa1-lifnr,
Nombre LIKE lfa1-name1,
END OF r_provincias.
PERFORM informar USING r_provincias.
FORM informar USING rs_provincias STRUCTURE r_provincias.
rs_provincias-nombre = ‘JOSE’.
ENDFORM.
También se puede pasar como parámetro una tabla interna. Para hacer referencia se utiliza TABLES:
Ejemplo: DATA d_contador TYPE i VALUE 1.
DATA: BEGIN OF i_provincias OCCURS 0,
Codigo LIKE lfa1-lifnr,
Nombre LIKE lfa1-name1,
END OF i_provincias.
PERFORM informar TABLES i_provincias
USING d_contador.
FORM informar TABLES is_provincias STRUCTURE i_provincias
USING VALUE(l_contador).
is_provincias-codigo = d_contador.
is_provincias-nombre = ‘JOSE’.
APPEND is_provincias.
ENDFORM.
Se inserta el registro en la tabla interna i_provincias.
Las subrutinas son conjuntos de instrucciones que pueden ser llamadas desde el programa en diversas ocasiones.
Para definirlas se utilizan las palabras clave FORM y ENDFORM que se especifican al inicio y final de las instrucciones que forman la subrutina. Para llamarla se utiliza la sentencia PERFORM.
Ejemplo: PERFORM ejemplo. Llama a la subrutina.
.......
FORM ejemplo. Definición de la subrutina.
-----
ENDFORM.
El programa principal y la subrutina se pueden comunicar mediante parámetros pasados por valor o referencia, siendo recomendable especificar el tipo de dato al definirlo.
Pase de parámetros por referencia
PERFORM <nombre> USING parametro1 parametro2.
.....
FORM <nombre> USING parametro1 parametro2.
----
ENDFORM.
Los parámetros que son pasados a la subrutina en la llamada (FORMALES), se actualizan con los parámetros (ACTUALES) definidos en la subrutina.
Ejemplo: DATA: d_numero1 TYPE i VALUE 1,
d_numero2 TYPE i VALUE 2.
PERFORM sumar USING d_numero1 d_numero2.
….
FORM sumar USING l_numero1 type i
l_numero2 type i.
l_numero1 = l_numero1 + l_numero2.
ENDFORM.
Ahora: d_numero1 = 3 y d_numero2 = 2.
Pase de parámetros por referencia
PERFORM <nombre> USING parametro1 parametro2.
.....
FORM <nombre> USING VALUE (parametro1) VALUE(parametro2).
----
ENDFORM.
Los parámetros que son pasados a la subrutina no se actualizan con el valor de los parámetros definidos en la subrutina.
Ejemplo: DATA: d_numero1 TYPE i VALUE 1,
d_numero2 TYPE i VALUE 2.
PERFORM sumar USING d_numero1 d_numero2.
….
FORM sumar USING l_numero1 type i
Value( l_numero2) type i.
l_numero2 = 3.
l_numero1 = l_numero1 + l_numero2.
ENDFORM.
Ahora: d_numero1 = 4 y d_numero2 = 2.
Utilizando STRUCTURE se puede pasar como parámetro una estructura y hace referencia a sus campos en la subrutina.
Ejemplo: DATA: BEGIN OF r_provincias,
Codigo LIKE lfa1-lifnr,
Nombre LIKE lfa1-name1,
END OF r_provincias.
PERFORM informar USING r_provincias.
FORM informar USING rs_provincias STRUCTURE r_provincias.
rs_provincias-nombre = ‘JOSE’.
ENDFORM.
También se puede pasar como parámetro una tabla interna. Para hacer referencia se utiliza TABLES:
Ejemplo: DATA d_contador TYPE i VALUE 1.
DATA: BEGIN OF i_provincias OCCURS 0,
Codigo LIKE lfa1-lifnr,
Nombre LIKE lfa1-name1,
END OF i_provincias.
PERFORM informar TABLES i_provincias
USING d_contador.
FORM informar TABLES is_provincias STRUCTURE i_provincias
USING VALUE(l_contador).
is_provincias-codigo = d_contador.
is_provincias-nombre = ‘JOSE’.
APPEND is_provincias.
ENDFORM.
Se inserta el registro en la tabla interna i_provincias.
sábado, 15 de noviembre de 2014
Introducción ABAP. Definición de datos
Voy a comenzar a publicar varios post sobre los conceptos básicos del lenguaje de programación de SAP, ABAP.
El primer apartado lo vamos a dedicar a la definición de datos. El primer caso es conocer que tipos de datos nos proporciona el lenguaje. Os voy a presentar los tipos básicos que nos proporciona ABAP:
Variables
Las variables se definen por defecto de tipo carácter Texto con longitud 1.
Con la cláusula LIKE podemos declarar una variable con los mismos atributos de longitud y tipo que un campo del diccionario de datos o que otra variable definida anteriormente.
Constantes
Las constantes se definen con la sentencia CONSTANTS:
Mismas reglas que para variables, excepto que siempre hay que inicializarlo y no puede ser modificado durante la ejecución.
Estructuras
Una estructura es un conjunto de campos relacionados lógicamente y se define con DATA:
También se puede incluir en la definición de una estructura, la de una tabla del diccionario de datos o una estructura definida previamente en el programa utilizando la instrucción INCLUDE ESTRUCTURE ......... .
Para llamar a los campos de una estructura se especifica el nombre de la estructura y del campo, separados por guión.
Rangos
Los rangos son tablas internas con una estructura determinada que se utilizan para almacenar rangos de valores para un tipo de campo y se definen con RANGES:
La estructura de un rango se compone de los siguientes campos:
-OPTION: Campo de tipo carácter de dos posiciones que indica el operador lógico que une los valores especificados en el rango. Los valores que puede tomar son:
-HIGH: Valor final del rango. Es del mismo tipo que el campo al que hace referencia el rango.
Los rangos se utilizan para chequear valores válidos en sentencias condicionales del campo en cuestión. Si el rango no tiene ningún registro, se asume que cualquier valor del campo es válido.
Field-Symbols
Los Field-Symbols son campos simbólicos que se pueden referenciar a un campo concreto, en tiempo de ejecución del programa y se definen con FIELD-SYIBOLS:
Utilizando ASSIGN se asigna un campo al field-symbol y a partir de entonces, las operaciones que se realicen sobre el field-symbol, hacen referencia al campo asignado.
Ejemplo: FIELD-SYMBOLS: <campo>.
ASSIGN d_contador1 to <campo>.
Ahora d_contador1 tiene el valor 1 y d_contador2 tiene el valor 2.
El primer apartado lo vamos a dedicar a la definición de datos. El primer caso es conocer que tipos de datos nos proporciona el lenguaje. Os voy a presentar los tipos básicos que nos proporciona ABAP:
Variables
Las variables se definen por defecto de tipo carácter Texto con longitud 1.
Ejemplo: DATA d_caracter. (Vble de texto con long 1)
DATA d_caracter(8). (Vble de texto con long 8)
DATA: d_numero_car(5) TYPE N,
d_numero TYPE I,
d_fecha TYPE D.
DATA d_contador TYPE I VALUE 1.
Con la cláusula LIKE podemos declarar una variable con los mismos atributos de longitud y tipo que un campo del diccionario de datos o que otra variable definida anteriormente.
Ejemplo: DATA d_dato LIKE lfa1-lifnr.
Constantes
Las constantes se definen con la sentencia CONSTANTS:
CONSTANTS <constante> (longitud) TYPE <tipo> VALUE <valor>.
Mismas reglas que para variables, excepto que siempre hay que inicializarlo y no puede ser modificado durante la ejecución.
Ejemplo: CONSTANTS c_dato LIKE lfa1-lifnr VALUE ‘JOSE’.
Estructuras
Una estructura es un conjunto de campos relacionados lógicamente y se define con DATA:
DATA: BEGIN OF <estructura>
………………,
END OF <estructura>.
Ejemplo: DATA: BEGIN OF r_estructura
Codigo LIKE lfa1-lifnr,
Fecha TYPE d,
END OF r_estructura.
Ejemplo: DATA BEGIN OF r_sociedades OCCURS 0.
INCLUDE STRUCTURE T001.
DATA: contador(20) TYPE N,
END OF r_sociedades.
Ejemplo: r_sociedades-nombre = ‘JOSE’.
Rangos
Los rangos son tablas internas con una estructura determinada que se utilizan para almacenar rangos de valores para un tipo de campo y se definen con RANGES:
RANGES: <rango> FOR <campo>.
La estructura de un rango se compone de los siguientes campos:
-SIGN: Campo de tipo carácter de longitud 1, que indica si los valores especificados en el rango se incluyen (I) o se excluyen (E) del mismo.
- EQ = equal
- NE = not equal
- GE = greater or equal
- GT = greater than
- LE = less or equal
- LT = less than
- CP = contains pattern
- NP = not contains pattern
Los rangos se utilizan para chequear valores válidos en sentencias condicionales del campo en cuestión. Si el rango no tiene ningún registro, se asume que cualquier valor del campo es válido.
Ejemplo: TABLES: LFA1.
RANGES: r_rango FOR lfa1-lifnr.
r_rango-sign = ‘I’.
r_rango-option = ‘BT’. (entre)
r_rango-low = ‘1’.
r_rango-high = ‘9’.
APPEND r_rango.
El rango creado hace referencia a los valores del campo lfa1-lifnr comprendidos entre el 1 y el 9, ambos inclusive por tener ‘I’.
FIELD-SYMBOLS <nombre>. ¡¡Poner <........>!!
Utilizando ASSIGN se asigna un campo al field-symbol y a partir de entonces, las operaciones que se realicen sobre el field-symbol, hacen referencia al campo asignado.
DATA: d_contador1 TYPE i,
d_contador2 TYPE i.
<campo> = <campo> + 1.
ASSIGN d_contador2 to <campo>.
<campo> = <campo> + 2.
Ahora d_contador1 tiene el valor 1 y d_contador2 tiene el valor 2.
jueves, 13 de noviembre de 2014
Ejecutar transacción en un modo nuevo
En este post seguimos viendo algunos módulos de funciones intersantes que pueden sernos útiles en muchos desarrollo. En este caso os voy mostrar el FM ABAP4_CALL_TRANSACTION que ejecuta una transacción en un modo nuevo. Podemos pasarle parámetros a la transacción. En el ejemplo vamos a ejecutar la transacción VA03 (Visualizar Pedido de Ventas). A continuación el ejemplo:
DATA: msg_text(80) TYPE c, "Message text
itab_spa TYPE STANDARD TABLE OF rfc_spagpa,
wa_spa TYPE rfc_spagpa.
* Fill out parameters
wa_spa-parid = 'AUN'.
wa_spa-parval = '0006012345'.
APPEND wa_spa TO itab_spa.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION' STARTING NEW TASK 'SORD'
DESTINATION 'NONE'
EXPORTING
tcode = 'VA03'
TABLES
spagpa_tab = itab_spa
EXCEPTIONS
communication_failure = 1
system_failure = 2 .
DATA: msg_text(80) TYPE c, "Message text
itab_spa TYPE STANDARD TABLE OF rfc_spagpa,
wa_spa TYPE rfc_spagpa.
* Fill out parameters
wa_spa-parid = 'AUN'.
wa_spa-parval = '0006012345'.
APPEND wa_spa TO itab_spa.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION' STARTING NEW TASK 'SORD'
DESTINATION 'NONE'
EXPORTING
tcode = 'VA03'
TABLES
spagpa_tab = itab_spa
EXCEPTIONS
communication_failure = 1
system_failure = 2 .
miércoles, 12 de noviembre de 2014
Obtener con ABAP el texto de un mensaje a partir del ID y del Número
En este post os voy a dejar un módulo de funciones muy sencillo que nos devuele el texto de un mensaje devuelto por el sistema. Muchas veces cuando ejecutamos BAPI´s o FM estas nos devuelven mensajes en la tabla RETURN. Tenemos el ID del mensaje, su número y los parametros que le acompañen, pero no tenemos el texto completo del mensaje.
Para solucionar esto podemos utilizar el FM SAPTRX/GET_MESSAGE_TEXT. Le pasamos los parámetros correspondientes y nos devuelve el texto completo del mensaje. Como ejemplo:
Con el mensaje completo que nos devuelve pordemos, por ejemplo, mostrarselo al usuario por pantalla.
Para solucionar esto podemos utilizar el FM SAPTRX/GET_MESSAGE_TEXT. Le pasamos los parámetros correspondientes y nos devuelve el texto completo del mensaje. Como ejemplo:
CALL FUNCTION '/SAPTRX/GET_MESSAGE_TEXT'
EXPORTING
MSGID = return-MSGID
MSGNO = numero
MSGV1 = m1
MSGV2 = m2
MSGV3 = m3
MSGV4 = m4
IMPORTING
MESSAGETEXT = i_mensaje
EXCEPTIONS
NO_MESSAGE_RETRIEVED = 1
OTHERS = 2.
Con el mensaje completo que nos devuelve pordemos, por ejemplo, mostrarselo al usuario por pantalla.
domingo, 9 de noviembre de 2014
Tratar ficheros de un servidor FTP en SAP
En este post os voy a explicar como podemos tratar ficheros que se encuentran almacenados en un servidor FTP.
El primer paso va a ser crearnos una RFC que nos permita conectarnos al servidor FTP. Ejecutamos la transacción SM59 y creamos una nueva RFC dentro de "Conexiones TCP/IP". Le damos el nombre "SAPFTP". Es importante rellenar los parámetros tal cual los marco en la siguiente imagen:
Una vez realizados todos los pasos previo esté sería el programa a ejecutar:
El primer paso va a ser crearnos una RFC que nos permita conectarnos al servidor FTP. Ejecutamos la transacción SM59 y creamos una nueva RFC dentro de "Conexiones TCP/IP". Le damos el nombre "SAPFTP". Es importante rellenar los parámetros tal cual los marco en la siguiente imagen:
A continuación os voy a dejar el código de ejemplo. Vamos a realizar los siguientes pasos:
- Listar los documentos del directorio.
- Leemos los ficheros
- Copiamos los ficheros a una carpeta de nuestra red
- Borramos los ficheros tratados del FTP.
Una vez realizados todos los pasos previo esté sería el programa a ejecutar:
l_login = 'usuario'.
l_password = 'Contraseña'.
l_direction = 'Dirección FTP'.
l_strlen = STRLEN( l_password ).
l_password = 'Contraseña'.
l_direction = 'Dirección FTP'.
l_strlen = STRLEN( l_password ).
* Realizamos la conexión al FTP
CALL FUNCTION 'HTTP_SCRAMBLE'
EXPORTING
SOURCE = l_password
sourcelen = l_strlen
key = l_scr_key
IMPORTING
destination = l_password.
CALL FUNCTION 'FTP_CONNECT'
EXPORTING
user = l_login
password = l_password
host = l_direction
rfc_destination = l_rfc_dst
IMPORTING
handle = l_handle
EXCEPTIONS
not_connected = 1.
IF sy-subrc = 0.
REFRESH: mtab_data.
* Listamos los ficheros en el ftp
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = l_handle
command = 'ls'
TABLES
data = mtab_data
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
* Marcamos el directorio local sobre el que vamos a trabajar y copiar los ficheros
local = '\\Ruta\Carpeta_Ficheros\'.
CONCATENATE 'lcd' local INTO cmd SEPARATED BY space.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = l_handle
command = cmd
TABLES
data = mtab_lcd
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
* Leemos los ficheros en el ftp
LOOP AT mtab_ficheros.
REFRESH: mtab_fich,
mtab_rename,
mtab_get.
CALL FUNCTION 'FTP_SERVER_TO_R3'
EXPORTING
handle = l_handle
fname = mtab_ficheros-fichero
character_mode = 'X'
TABLES
text = mtab_fich
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
* Copiamos el archivo al directorio marcado
CONCATENATE 'get' mtab_ficheros-fichero INTO cmd SEPARATED BY ' '.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = l_handle
command = cmd
TABLES
data = mtab_get
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
* Borramos los ficheros leidos
CONCATENATE 'del' mtab_ficheros-fichero INTO cad SEPARATED BY space.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = l_handle
command = cad
TABLES
data = mtab_del
EXCEPTIONS
command_error = 1
tcpip_error = 2.
ENDLOOP.
* Cerramos la conexión con el FTP
CALL FUNCTION 'FTP_DISCONNECT'
EXPORTING
handle = l_handle
EXCEPTIONS
OTHERS = 1.
ENDIF.
CALL FUNCTION 'HTTP_SCRAMBLE'
EXPORTING
SOURCE = l_password
sourcelen = l_strlen
key = l_scr_key
IMPORTING
destination = l_password.
CALL FUNCTION 'FTP_CONNECT'
EXPORTING
user = l_login
password = l_password
host = l_direction
rfc_destination = l_rfc_dst
IMPORTING
handle = l_handle
EXCEPTIONS
not_connected = 1.
IF sy-subrc = 0.
REFRESH: mtab_data.
* Listamos los ficheros en el ftp
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = l_handle
command = 'ls'
TABLES
data = mtab_data
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
* Marcamos el directorio local sobre el que vamos a trabajar y copiar los ficheros
local = '\\Ruta\Carpeta_Ficheros\'.
CONCATENATE 'lcd' local INTO cmd SEPARATED BY space.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = l_handle
command = cmd
TABLES
data = mtab_lcd
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
* Leemos los ficheros en el ftp
LOOP AT mtab_ficheros.
REFRESH: mtab_fich,
mtab_rename,
mtab_get.
CALL FUNCTION 'FTP_SERVER_TO_R3'
EXPORTING
handle = l_handle
fname = mtab_ficheros-fichero
character_mode = 'X'
TABLES
text = mtab_fich
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
* Copiamos el archivo al directorio marcado
CONCATENATE 'get' mtab_ficheros-fichero INTO cmd SEPARATED BY ' '.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = l_handle
command = cmd
TABLES
data = mtab_get
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
* Borramos los ficheros leidos
CONCATENATE 'del' mtab_ficheros-fichero INTO cad SEPARATED BY space.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = l_handle
command = cad
TABLES
data = mtab_del
EXCEPTIONS
command_error = 1
tcpip_error = 2.
ENDLOOP.
* Cerramos la conexión con el FTP
CALL FUNCTION 'FTP_DISCONNECT'
EXPORTING
handle = l_handle
EXCEPTIONS
OTHERS = 1.
ENDIF.
Suscribirse a:
Entradas (Atom)
Integración SAP
Cuando hablamos de SAP como sistema integrado que cubre toda la casuística de nuestro negocio estamos siendo bastante osados. Casi cualquier...
-
En este post un ejemplo de creación de un ALV con objetos en SAP. Para crear un ALV OO tenemos que crearnos una nueva DYNPRO y dentro de ...
-
En este post vamos a ver una de las BADI´s mas utilizadas dentro de SAP. No es otro que la BADI ME_PROCESS_PO_CUST que se utiliza para inc...








































