Existe una clase estándard en SAP, CL_ABAP_ZIP, que permite crear archivos de texto comprimidos en ZIP. Existen varios modos de conseguir dicho fin. Un objeto de la clase CL_ABAP_ZIP puede contener más de un archivo. Todos los archivos que contengan deben estar codificados en binario (XSTRING).
A continuación se muestra un ejemplo de cómo convertir el contenido de una tabla interna a un fichero ZIP.
Si lo que se desea es comprimir un archivo que se encuentra en una ubicación determinada, lo que deberemos hacer es, en primer lugar, leer el contenido del archivo en una variable de tipo binaria (xstring) y a continuación pasarle el contenido de esa variable al objeto de la clase CL_ABAP_ZIP que la vaya a contener.
jueves, julio 31, 2008
miércoles, julio 30, 2008
SAP Netweaver Developer Studio
Se trata de una herramienta de utilidad para el desarrollo en XI. Se puede descargar, junto a una serie de herramientas complementarias, desde los siguientes enlaces:
Etiquetas:
XI
martes, julio 29, 2008
RFC vs. Proxy
En el presente post he querido reflejar las ventajas y contras que aparecen al utilizar RFCs y al utilizar ABAP Proxies. Es por ello que antes de decirdir qué método utilizar será recomendable que tengamos en cuenta las siguientes caracteríscitas:
A continuación muestro 2 enlaces que pueden ser de interés:
ABAP Proxies
Ventajas
- Permite definir todas las estructuras necesarias a partir de esquemas XSD o ficheros WSDL.
- Funcionan sin problemas con estructuras anidadas (tablas dentro de otras tablas).
Inconvenientes
- Al importar el proxy en el ERP se generan numerosos objetos con nombres muy largos. Si se desea renombrar dichos objetos habrá que tener en cuenta que cada vez que sea necesario importar de nuevo el proxy (debido a cambios) los nombres de los objetos deberán ser cambiados de nuevo.
- Es necesario configurar la conexión desde el sistema ERP al sistema XI para que la transacción SPROXY pueda importar los proxies correctamente.
- El acceso a los métodos de las clases y las llamadas a éstos es más tediosa que con las RFCs.
RFCs
Ventajas
- La definición del código es mucho más directa que a través de los proxies.
- La llamada a las funciones RFCs es más sencilla.
- La actualización de las estructuras que utiliza es más directa.
Desventajas
- Requiere que definamos las estructuras enteras en el sistema ERP a pelo. Si éstas disponen de muchos campos, la cosa se complica.
- No funciona bien con estructuras de tipo tabla que contienen campos que a la vez son de tipo tabla.
A continuación muestro 2 enlaces que pueden ser de interés:
- XI: RFC or ABAP Proxy ? ....ABAP Proxies with attachments
- Choose the Right Adapter to integrate with SAP systems
Etiquetas:
XI
lunes, julio 28, 2008
Controlar tiempos de ejecución
Si lo que se desea conocer es cuánto se tarda en ejecutar una porción de código, la sentecia GET RUN TIME FIELD nos vendrá como anillo al dedo. A continuación muestro un ejemplo de utilización:
Los tiempos t1 y t2 vienen dado en microsegundos por lo que será necesario dividirlos por 1.000 para pasarlos a milisegundos y por 1.000.000 si se desea tener en segundos.
Los tiempos t1 y t2 vienen dado en microsegundos por lo que será necesario dividirlos por 1.000 para pasarlos a milisegundos y por 1.000.000 si se desea tener en segundos.
Etiquetas:
ABAP
miércoles, julio 09, 2008
EAN-128
A la hora de tratar con códigos EAN-128 existen módulos de funciones estándar que permiten tanto codificar como decodificar de este modo.
Dentro del grupo de funciones LE_EAN128 se encuentran los módulos:
Hay que tener en cuenta que para que el proceso de codificación se realice correctamente será necesario tener parametrizado de forma correcta las secciones comprendidas en el área de customizing (SPRO) Logistics - General --> Handling Unit Management --> Basics --> Define EAN128.
Existe otro grupo de funciones que también debe tenerse en cuenta y es el LE_BARCODE. Dentro del cual el módulo de función más significativo es el:
Más info: http://www.scribd.com/doc/3262714/EAN128-E
Dentro del grupo de funciones LE_EAN128 se encuentran los módulos:
- LE_EAN128_ENCODE: Crear un código de barras estándar para ean128
- LE_EAN128_DECODE: Descodificación de un código de barras estándar para ean128
- LE_EAN128_LABEL_OUTPUT: EAN128 etiqueta: Edición impresa
- LE_EAN128_LABEL_READ: EAN128 etiqueta: datos
Hay que tener en cuenta que para que el proceso de codificación se realice correctamente será necesario tener parametrizado de forma correcta las secciones comprendidas en el área de customizing (SPRO) Logistics - General --> Handling Unit Management --> Basics --> Define EAN128.
Existe otro grupo de funciones que también debe tenerse en cuenta y es el LE_BARCODE. Dentro del cual el módulo de función más significativo es el:
- LE_BARCODE_AI_READ: Lee la descripción de códigos de barras
- (02)08470006043066(17)150400(37)006(10)1022134
- ]C102084700060430661715040037006#101022134
Más info: http://www.scribd.com/doc/3262714/EAN128-E
Etiquetas:
ABAP
jueves, julio 03, 2008
ccBPM
A través del cross-component BPM se permiten definir procesos de negocios automatizados ampliando así la potencia de componente de integración de procesos de SAP. El ccBPM permite, entre otras cosas, recibir mensajes individuales a través de una determinada interfaz para postermiormente unificarlos en una lista y distribuirlos a las máquinas correspondiente, por ejemplo.
Los procesos definidos a través del ccBPM están basados en el estándard BPEL4WS, definido entre otros por SAP, IBM y Microsoft. Es por ello que dichos procesos pueden ser exportados a otros sistemas y, por otra parte, se pueden importar procesos de negocios definidos en otros sistemas, siempre y cuando sigan este estándar.
Antes de definir los procesos de integración mediante el ccBPM, se deberá configurar el entorno XI de manera correcta (diseño y configuración), tal como se especifica en éste enlace.
Para más información: http://help.sap.com/saphelp_nw04/helpdata/en/3c/831620a4f1044dba38b370f77835cc/frameset.htm
Los procesos definidos a través del ccBPM están basados en el estándard BPEL4WS, definido entre otros por SAP, IBM y Microsoft. Es por ello que dichos procesos pueden ser exportados a otros sistemas y, por otra parte, se pueden importar procesos de negocios definidos en otros sistemas, siempre y cuando sigan este estándar.
Antes de definir los procesos de integración mediante el ccBPM, se deberá configurar el entorno XI de manera correcta (diseño y configuración), tal como se especifica en éste enlace.
Para más información: http://help.sap.com/saphelp_nw04/helpdata/en/3c/831620a4f1044dba38b370f77835cc/frameset.htm
Etiquetas:
XI
Anteponer el signo de los números
El siguiente código vuelca el contenido de un número real (negativo) a una variable alfanumérica, poniendo el signo como prefijo de la misma.
Etiquetas:
ABAP
jueves, junio 05, 2008
Obtener el siguiente número secuencial
Donde el parámetro NR_RANGE_NR es de tipo INRI-NRRANGENR y el parámetro OBJETO es de tipo INRI-OBJECT.
Etiquetas:
ABAP
lunes, junio 02, 2008
Convertir campos del ALV en totalizables
Para que los botones de sumatoria y subtotales se activen en un listado se deberán especificar los campos que se deseen totalizar a partir de referencias a campos de tablas estándar. De este modo SAP conocerá el tipo (decimales, signo, etc.) y podrá realizar las sumas de manera correcta.
Si, además, marcamos el campo "DO_SUM", esto hará que se muestra una línea de totales al final del listado.
Si, además, marcamos el campo "DO_SUM", esto hará que se muestra una línea de totales al final del listado.
Etiquetas:
ABAP
Ocultar campos de pantalla
Hay veces en las que se hace necesario ocultar ciertos campos de la pantalla de selección. Sobre todo cuando se utilizan bases de datos lógicas que incluyen campos propios. En estos casos habrá que saber en primer lugar cuál es el nombre de los campos que deseamos ocultar. Ésto se puede lograr visualizando la pantalla de selección estándar del sistema (dynpro nº 1000). Los campos se recogen en la pestaña Lista de elementos y dentro de ésta deberemos ir a la pestaña Grupos modif./Funciones para conocer los grupos a los que están asignados.
Supongamos que deseamos ocultar aquellos campos que pertenezcan al GRUPO1 YB1. El lugar donde debemos codificar ésto es en el evento AT SELECTION-SCREEN OUTPUT. Y el código sería el siguiente:
Nótese que el campo INPUT puesto a 0 sirve para aquellos campos de entrada salida, ya que si no especificamos este valor, aunque se pongan invisibles se seguirán mostrando.
Supongamos que deseamos ocultar aquellos campos que pertenezcan al GRUPO1 YB1. El lugar donde debemos codificar ésto es en el evento AT SELECTION-SCREEN OUTPUT. Y el código sería el siguiente:
Nótese que el campo INPUT puesto a 0 sirve para aquellos campos de entrada salida, ya que si no especificamos este valor, aunque se pongan invisibles se seguirán mostrando.
Etiquetas:
ABAP
Llamadas a listados con retorno
Algunas veces se crean programas que, en función de unas opciones de selección, permiten visualizar un tipo de listado u otro. Lo ideal es que el usuario no tenga salir del programa y volver a cada vez que quiera cambiar de listado, sino volver a la pantalla de selección y desde ahí elegir el nuevo listado que desea visualizar.
Esto se consigue mediante la combinación CALL SCREEN + LEAVE TO SCREEN 0. A continuación se muestra un ejemplo.
En el programa principal habrá un código del siguiente estilo:
Y los módulo PAI de las pantallas deberán contener un código similar a éste:
Es importante hacer uso del CALL SCREEN ya que si utilizamos la sentencia LEAVE TO SCREEN 0 con SET SCREEN nos echará del programa.
Esto se consigue mediante la combinación CALL SCREEN + LEAVE TO SCREEN 0. A continuación se muestra un ejemplo.
En el programa principal habrá un código del siguiente estilo:
Y los módulo PAI de las pantallas deberán contener un código similar a éste:
Es importante hacer uso del CALL SCREEN ya que si utilizamos la sentencia LEAVE TO SCREEN 0 con SET SCREEN nos echará del programa.
Etiquetas:
ABAP
viernes, mayo 23, 2008
Delimitaciones dinámicas en LDB_PROCESS
Cuando usamos bases de datos lógicas de partidas de FI hay campos que no aparecen directamente en la pantalla de selección, pero sí a través del botón de delimitaciones opcionales. los programas estándar que incluyen la LDB en los atibutos gestionan correctamente estas delimitaciones, pero... ¿cómo las especificaríamos si utilizamos la función LDB_PROCESS? aquí va un ejemplillo.
Funciones relacionadas con los días de los períodos
PERIOD_DAY_DETERMINE: devuelve primer/último días de período
- Entrada: I_GJAHR, I_MONAT, I_PERIV (de sociedad en T001)
- Salida: E_FDAY, E_LDAY, E_SPERIOD (indicador período especial)
FIRST_DAY_IN_PERIOD_GET / LAST_DAY_IN_PERIOD_GET
- Entrada: I_GJAHR, I_PERIV (de sociedad en T001) , I_POPER (período)
- Salida: E_DATE (primer / último día)
Gracias a Lucas León.
- Entrada: I_GJAHR, I_MONAT, I_PERIV (de sociedad en T001)
- Salida: E_FDAY, E_LDAY, E_SPERIOD (indicador período especial)
FIRST_DAY_IN_PERIOD_GET / LAST_DAY_IN_PERIOD_GET
- Entrada: I_GJAHR, I_PERIV (de sociedad en T001) , I_POPER (período)
- Salida: E_DATE (primer / último día)
Gracias a Lucas León.
Etiquetas:
ABAP
Esperar 'n' segundos
Si se desea meter un retardo de 'n' segundos en el código se puede utilizar la siguiente instrucción:
Etiquetas:
ABAP
Opciones del DELETE ADJACENT
El motivo de este post es para explicarles unas opciones del DELETE de las tablas internas, que puede resultar de gran ayuda. Supongo que los más experimentados en Abap ya sabrán de ellas, pero el resto puede que no lo hayan visto.
Supongamos que nos pasan una tabla con muchísimos registros, de los cuales pueden haber duplicados. Necesitamos tener un solo registro de cada tipo, por lo que nos interesa eliminar de la tabla los duplicados. Para ello, podemos hacer lo siguiente:
Este delete eliminaría los duplicados de los registros, pero sólo aquellos que coincidan en todos los campos. Si cada registro se compone de varios campos, tienen que coincidir en todos para ser eliminados.
Si lo que nos interesa es eliminar registros que coincidan sólo en uno, dos, ... n campos, lo especificariamos de la siguiente forma.
dónde cada campo es el nombre del campo en la tabla interna.
Por ejemplo.
Tenemos la estructura siguiente, formada por tres campos:
Ahora queremos aplicar lo explicado antes, pero para que tenga en cuenta sólo el campo MATKL a la hora de eliminar duplicados.
Se eliminarian todos los registros duplicados excepto uno, el primero de la ordenación, con el mismo campo MATKL, aunque los dos campos siguientes sean diferentes.
Gracias a Samuel Artiles.
Supongamos que nos pasan una tabla con muchísimos registros, de los cuales pueden haber duplicados. Necesitamos tener un solo registro de cada tipo, por lo que nos interesa eliminar de la tabla los duplicados. Para ello, podemos hacer lo siguiente:
- ordenamos la tabla -> SORT tabla_interna.
- eliminamos los duplicados -> DELETE ADJACENT DUPLICATES FROM tabla_interna.
Este delete eliminaría los duplicados de los registros, pero sólo aquellos que coincidan en todos los campos. Si cada registro se compone de varios campos, tienen que coincidir en todos para ser eliminados.
Si lo que nos interesa es eliminar registros que coincidan sólo en uno, dos, ... n campos, lo especificariamos de la siguiente forma.
- ordenamos la tabla -> SORT tabla_interna.
- eliminamos los duplicados -> DELETE ADJACENT DUPLICATES FROM tabla_interna COMPARING campo1 campo2 ... campoX.
dónde cada campo es el nombre del campo en la tabla interna.
Por ejemplo.
Tenemos la estructura siguiente, formada por tres campos:
Ahora queremos aplicar lo explicado antes, pero para que tenga en cuenta sólo el campo MATKL a la hora de eliminar duplicados.
- SORT gt_fich_gr_articulos.
- DELETE ADJACENT DUPLICATES FROM gt_fich_gr_articulos COMPARING MATKL.
Se eliminarian todos los registros duplicados excepto uno, el primero de la ordenación, con el mismo campo MATKL, aunque los dos campos siguientes sean diferentes.
Gracias a Samuel Artiles.
Etiquetas:
ABAP
Estructura para CALL TRANSACTIONS
Con la estructura CTU_PARAMS podemos definir algunos parámetros del CALL TRANSACTION como modo de ejecución (Sólo errores, Visible, Invisible,...), modo de actualización, tamaño estándar de dynpro,...
Para su uso, por ejemplo, podemos definir un parámetro de tipo CTU_PARAMS-XXXXXX en la pantalla de selección y ello nos dará la posibilidad de seleccionar los diferentes aspectos en la ejecución del CALL TRANSACTION.
Ejemplo:
Para su uso, por ejemplo, podemos definir un parámetro de tipo CTU_PARAMS-XXXXXX en la pantalla de selección y ello nos dará la posibilidad de seleccionar los diferentes aspectos en la ejecución del CALL TRANSACTION.
Ejemplo:
Etiquetas:
ABAP
Cambiar el Infoset a un Query
Muchos (sobre todo funcionales) se habrá tropezado alguna vez cuando intenta copiar un query, porque no pueden cambiar el infoset. Pues bien, si no lo sabían, aquí está el truco.
1. Transacción SQ01 (SAP Query). Copiar el QUERY1 en QUERY2. El QUERY2 tendrá asignado el INFOSET1 y no se puede cambiar.
2. Transacción SQ02 (Infosets). Copiar el INFOSET1 en INFOSET2. Hacer las modificaciones que quieran en el INFOSET2.
3. Download el QUERY2 a fichero. Para ello ir a Infosets, Entorno->Transportes (Camioncito).
4. Editar el fichero de texto y cambiar INFOSET1 por INFOSET2.
5. Upload del QUERY2.
Y Listo. El QUERY2 será remplazado por el del fichero, que tiene el nuevo infoset.
Gracias a Jorge Martel por esta información.
1. Transacción SQ01 (SAP Query). Copiar el QUERY1 en QUERY2. El QUERY2 tendrá asignado el INFOSET1 y no se puede cambiar.
2. Transacción SQ02 (Infosets). Copiar el INFOSET1 en INFOSET2. Hacer las modificaciones que quieran en el INFOSET2.
3. Download el QUERY2 a fichero. Para ello ir a Infosets, Entorno->Transportes (Camioncito).
4. Editar el fichero de texto y cambiar INFOSET1 por INFOSET2.
5. Upload del QUERY2.
Y Listo. El QUERY2 será remplazado por el del fichero, que tiene el nuevo infoset.
Gracias a Jorge Martel por esta información.
Comprobación del NIF
para españa p.e.: COUNTRY = 'ES' y TAX_CODE_1 = nif a comprobar
en las excepciones devuelve si el NIF es válido o no.
martes, mayo 20, 2008
Reutilizar un tipo importado de una RFC
En muchas ocasiones habremos deseado aprovechar los tipos importados de las RFCs, evitando así diseñar los tipos necesarios para el mapeo con éstas, sobre todo si constan de muchos campos. Pues bien, existe una manera de hacerlo un poco casera pero eficaz. Para ello deberemos localizar en primer lugar la RFC/iDoc donde se encuentre el tipo a utilizar.
Una vez localizada, exportaremos el esquema XSD del tipo de mensaje deseado. En este caso exportaremos el correspondiente a la petición (request). Para ello iremos al menú Tools -> Export XSD -> Request... . Ésto nos generará el fichero .xsd en la ubicación que le hayamos indicado. A continuación, editaremos dicho fichero para poder importarlo desde el tipo que vayamos a crear. Supongamos que el tipo de datos que vamos a crear se llamará DT_DUMMY y que pertenece al dominio "http://dummy.es".

En primer lugar deberemos reemplazar el nombre del dominio con el que fue exportado el esquema. En este caso el dominio es "urn:sap-com:document:sap:rfc:functions", debiendo remplazarlo por "http://dummy.es". En sugundo lugar, faltará reemplazar el nombre del tipo del elemento "item" de "*_E_INTE_CAN_ALMACEN" a "DT_DUMMY". Guardamos los cambios.
Con ésto ya podremos crear el nuevo tipo de datos basado en el de la RFC. El nombre del tipo de datos y del dominio debe coincidir con lo que hemos puesto en el fichero. Para importar el esquema modificado deberemos seleccionar la etiqueta "XSD" y pulsar el icono de importar esquema.

En el momento de importarlo nos aparecerá un mensaje de aviso informando que se ignorará el elemento global que se define en el esquema, pero no debemos de darle mayor importancia ya que hace referencia al nombre de la RFC del que proviene. Con ello tendremos definido el nuevo tipo con los mismos campos y características que el tipo de la RFC, solo faltará aplicar las reglas de cardinalidad en función de las especificaciones.
Una vez localizada, exportaremos el esquema XSD del tipo de mensaje deseado. En este caso exportaremos el correspondiente a la petición (request). Para ello iremos al menú Tools -> Export XSD -> Request... . Ésto nos generará el fichero .xsd en la ubicación que le hayamos indicado. A continuación, editaremos dicho fichero para poder importarlo desde el tipo que vayamos a crear. Supongamos que el tipo de datos que vamos a crear se llamará DT_DUMMY y que pertenece al dominio "http://dummy.es".
En primer lugar deberemos reemplazar el nombre del dominio con el que fue exportado el esquema. En este caso el dominio es "urn:sap-com:document:sap:rfc:functions", debiendo remplazarlo por "http://dummy.es". En sugundo lugar, faltará reemplazar el nombre del tipo del elemento "item" de "*_E_INTE_CAN_ALMACEN" a "DT_DUMMY". Guardamos los cambios.
Con ésto ya podremos crear el nuevo tipo de datos basado en el de la RFC. El nombre del tipo de datos y del dominio debe coincidir con lo que hemos puesto en el fichero. Para importar el esquema modificado deberemos seleccionar la etiqueta "XSD" y pulsar el icono de importar esquema.
En el momento de importarlo nos aparecerá un mensaje de aviso informando que se ignorará el elemento global que se define en el esquema, pero no debemos de darle mayor importancia ya que hace referencia al nombre de la RFC del que proviene. Con ello tendremos definido el nuevo tipo con los mismos campos y características que el tipo de la RFC, solo faltará aplicar las reglas de cardinalidad en función de las especificaciones.
Etiquetas:
XI
lunes, mayo 19, 2008
Acerca las USER EXITS
Las user exits (Function module exits) son salidas desarrolladas por SAP. La salida se implementa como una llamada a un módulo de función. El código para el módulo de función lo escribe el desarrollador. No escribes el código directamente en el módulo de función sino en el include que está en dicho módulo.
La nomenclatura estándar de los módulos de función de las user exits es:
La llamada a un módulo de función de user exit se realiza de la siguiente manera:
Ejemplo:
El programa de la transacción VA01 es SAPMV45A.
Si se busca CALL CUSTOMER-FUNCTION en el programa SAPMV45A se encontrará ( entre otras user exits):
La exit llama al módulo de función EXIT_SAPMV45A_003
Para encontrar las user exits que se necesitan se puede hacer uso del programa que se detalla en esta entrada del blog: User Exits de una transacción.
Enlaces de interés:
La nomenclatura estándar de los módulos de función de las user exits es:
- EXIT_
La llamada a un módulo de función de user exit se realiza de la siguiente manera:
- CALL CUSTOMER-FUNCTION
Ejemplo:
El programa de la transacción VA01 es SAPMV45A.
Si se busca CALL CUSTOMER-FUNCTION en el programa SAPMV45A se encontrará ( entre otras user exits):
La exit llama al módulo de función EXIT_SAPMV45A_003
Para encontrar las user exits que se necesitan se puede hacer uso del programa que se detalla en esta entrada del blog: User Exits de una transacción.
Enlaces de interés:
Etiquetas:
ABAP,
USER EXITS
Suscribirse a:
Entradas (Atom)