• No results found

El Arte de Programar SAP NetWeaver

N/A
N/A
Protected

Academic year: 2021

Share "El Arte de Programar SAP NetWeaver"

Copied!
551
0
0

Loading.... (view fulltext now)

Full text

(1)

Para mi esposa Milly y mi hija Tammy Luz.

(2)

Sobre el Autor…

Alvaro Tejada Galindo se inició en el mundo de la programación a los 20 años. Sus primeros lenguajes fueron C++ y Visual Basic 6.0 lo cuales aprendió de manera autodidacta gracias a libros, foros, tutoriales y códigos fuente.

A lo largo de los años, fue agregando nuevos lenguajes a su colección, tales como Java, QBasic, Pascal, Delphi, HTML y JavaScript.

Fue cuando tenía 24 años, que conoció el mundo del SAP, puesto que entró a hacer sus prácticas en TSNet Global, en donde trabajó por espacio de 2 años, con grandes proyectos en empresas como Telefónica del Perú, Carsa, Minsur, Alicorp y Funsur.

Luego de dejar TSNet Global (Consultora Peruana), se dio un descanso para continuar estudiando y dedicarse al aprendizaje de PHP. Luego de esto, trabajó durante 2 años en la Consultora ActualiSap (Consultora Chilena), en donde además de dos exitosos proyectos de implementación en Suez Enegy Perú y el Aeropuerto Jorge Chávez, dictó un curso interno de IDoc’s en Santiago de Chile. Tuvo un breve paso por Servisoft (Consultora Peruana) en el proyecto de E. Wong. Con Stefanini IT Solutions trabajó para Alicorp, Exsa, Votorantim Metais y el Banco de Crédito del Perú.

(3)

Su experiencia en SAP y ABAP es de 5 años a la fecha, en los cuales siempre ha buscado obtener lo mejor del sistema.

Adicionalmente, es uno de los Bloggers o Columnistas del SAP Developer Network o SDN (http://sdn.sap.com) en donde escribe artículos sobre ABAP, HR, Integración de PHP con SAP e Integración de Ruby con SAP.

Además, es Moderador en los foros del SDN y Mentor de SAP para América Latina y el resto del mundo.

Pueden leer sus artículos en la siguiente dirección:

http://tinyurl.com/jnlfd http://atejada.blogspot.com

(4)

Indice

Conociendo el entorno SAP NetWeaver 7

Introducción 7

Ingresando al sistema 8

Conociendo las transacciones más importantes 12

El Menú de SAP NetWeaver 21

Diccionario de Datos 23

Introducción 23

Elementos del Diccionario de Datos 23

Creando una tabla 26

Creando un dominio 37

Creando un elemento de datos 38

Creando una vista de actualización 50

Creando una ayuda de búsqueda 60

Creando una estructura 65

Creando una Vista 66

Programación en ABAP 70

Introducción 70

Estructura de un programa ABAP 71

Declaración de variables y tablas internas 78

Selección de datos 83

Lectura de datos en tablas internas 86

Operadores de comparación 89

Operaciones en tablas internas 98

Copiar tablas internas 104

Ordenar tablas internas 108

Estructuras de Control 110

Trabajando con Cadenas de Texto 111

Variables de Sistema 119 Modularización de programas 121 Depuración de programas 129 Programas de ejemplo 138 SapScript 159 Introducción 159 Creando un formulario 159

(5)

Crear ventana en página 163 Crear párrafo por defecto 166 Creando un programa de impresión 168

Diseñando el formulario 175 Ejecutando el formulario 182 Debugger en SAPScript 185 SmartForms 187 Introducción 187 Creando un estilo 187 Creando un formulario 191

Creando un programa de impresión 196

Ejecutando el formulario 200

Crear una tabla 202

Screen Painter y Menu Painter 210

Introducción 210

Screen Painter 210

Controles del Screen Painter 213 Ejemplo de Screen Painter 215

Menu Painter 228

Agregando componentes 235

Programación avanzada en Dynpros 240

MatchCodes dinámicos 240

Eliminar registros en un Table Control 246 Escritura/Lectura en un Table Control 249 Trabajando con subScreens 259 Utilizando listas desplegables 272 Leyendo datos de un Dynpro 278

Módulos de Función y BAPIS 280

Introducción Módulos de Función 280 Creando nuestra primera función 280 Llamando funciones desde un programa 288

(6)

Introducción 328 ¿Qué es la Orientación a Objetos? 328 Conceptos básicos de POO 329 Como programar en ABAP Objects 335 Componentes Orientados a Objetos 351

Crear un ALV Grid OO 351

Agregar validaciones y eventos 365

Crear un ALV Tree OO 379

Agregar validaciones y eventos 399 Crear un ALV Object Model 409 Agregar validaciones y eventos 416 Cargar Imágenes en Dynpros 421

Leer PDF’s 430

Comprimir (zip) archivos 438

Crear un Control de Texto 451

WebDynpro 458

Introducción 458

Creando nuestro primer WebDynpro 458

BSP 489

Introducción 489

Creando nuestro primer BSP 489

ABAP y XML 501 Scripting in a Box 518 SAPLink 521 Integración PHP-NetWeaver 525 Introducción 525 Instalando el SAPRFC 526

Comunicándonos con NetWeaver 527

Integración Ruby-NetWeaver 539

Introducción 539

Instalando el SAP:Rfc 540

Comunicándonos con NetWeaver 540 Donde conseguir el SAP NetWeaver Sneak Preview 546 Bibliografía y agradecimientos 547

(7)

Conociendo el entorno SAP NetWeaver

Introducción

NetWeaver es la evolución del SAP R/3 que es un ERP (Enterprise

Resource Planning – Planificador de Recursos Empresariales).

¿Porque llamamos a NetWeaver una evolución del R/3? Pues porque

NetWeaver incorpora todos los aspectos de la programación orientada

a objetos, así como una fuerte integración web.

Al decir que se incorporan todos los aspectos de la programación orientada a objetos, nos referimos a que el ABAP (Advanced Business Application Programming) ha evolucionado también, proveyendo herramientas de desarrollo que aumentan la productividad.

A lo largo de este libro, vamos a trabajar con SAP NetWeaver 7.0

Trial Version al que llamaremos NSP (NetWeaver Sneak Preview),

que no es más que una versión reducida del NetWeaver que nos permite tomar ventaja de todos los componentes de desarrollo del sistema.

Para poder tener un mejor aprendizaje de los conceptos que se explican en el libro, vamos a crear dos tablas de base de datos muy

(8)

Ingresando al Sistema

Para poder ingresar a NSP, deberemos contar con un usuario y password, proporcionados por el administrador del sistema.

En nuestro caso, tenemos 2 usuarios que comparten un mismo password.

• SAP* Æ Super Usuario. Con este usuario podemos crear nuevos usuarios en NSP.

• BCUSER Æ Usuario Desarrollador. Con este usuario podemos programar en NSP.

• DDIC Æ Usuario de Diccionario de Datos. Con este usuario, podemos acceder a los datos almacenados dentro del NSP. En esta pantalla podemos ver el SAP Logon, que es donde se almacenan las entradas a los diferentes servidores de NSP.

En su caso, ustedes solamente van a tener uno, así que los marcan (NSP Local) y presionamos Acceder al Sistema.

(9)
(10)

En esta ventana es donde ingresaremos nuestro usuario y password. En la caja de texto de Language (Idioma), solamente podremos ingresar

EN Æ Inglés o DE Æ Alemán. El inglés es el idioma por defecto.

Luego de haber ingresado al sistema, veremos la pantalla principal del

NSP.

Esta es la pantalla de inicio, en donde podremos acceder a las transacciones que nos ofrece NSP. Las transacciones son códigos generalmente de 4 dígitos que sirven como accesos directos a los programas que se ejecutan internamente en el NSP.

Para acceder, tenemos dos opciones, buscarlas en el menú del lado izquierdo.

(11)
(12)

Conociendo las transacciones más importantes

1.- SE38 (Editor ABAP)

Este es el entorno de programación del NSP.

Aquí podemos crear nuestro programas o includes (Programas no ejecutables que se incluyen dentro de programas ejecutables).

(13)

2.- SE11 (Diccionario ABAP)

En esta transacción podremos crear, visualizar o modificar Tablas, Vistas, Dominios, Estructuras y Ayudas para Búsqueda.

(14)

3.- SE16 (Browser de Datos)

(15)

4.- SE71 (Form Painter)

(16)

Podemos definir páginas, ventanas, tipos de párrafo, márgenes, tabuladores, insertar imágenes.

Por lo general se utilizan para generar Cartas de Pago a Bancos, Facturas, Cheques, Certificados.

5.- SmartForms (Form Painter Avanzado)

Nos permite crear formularios de Impresión. El SmartForms es la nueva versión del SapScript. Se puede utilizar cualquiera de los dos, aunque depende de cada desarrollador.

(17)

6.- SE51 (Screen Painter)

(18)
(19)

8.- SE37 (Function Builder)

Nos permite crear funciones para utilizar en nuestros programas, así como modificar o visualizar funciones ya creadas.

(20)
(21)

El menú de SAP NetWeaver

En todas las transacciones, contamos con una barra de menú, que nos permite interactuar con las aplicaciones de NetWeaver. Veamos cuales son:

Æ Equivale a hacer clic en la tecla Enter.

Æ Aquí es donde se escribe la transacción a la cual queremos acceder. Si escribimos /n antes de la transacción, accederemos a ella en la misma ventana. Si escribimos /o antes de la transacción, accederemos a ella en una nueva ventana. Ej: /nSE38 ó

/oSE16.

Æ Grabar.

Æ Retroceder una pantalla.

Æ Salir del programa o transacción. Æ Cancelar el programa o transacción.

(22)

Æ Se habilitan en Tablas y sirven para avanzar o retroceder registros.

Æ Abre una nueva ventana o sesión del NetWeaver. Æ Crea un acceso directo en el escritorio.

Æ Ayuda.

(23)

Diccionario de Datos

Introducción

El Diccionario de Datos en NetWeaver, es el repositorio en el cual se almacenan todas las tablas, elementos de datos, dominios, estructuras, ayudas de búsqueda.

Vamos a dar un breve repaso de todos los conceptos que intervienen en el diccionario de datos, así como la manera de crear cada uno de sus diferentes componentes.

Cabe destacar, que en NetWeaver, todo es manejado por tablas, es decir, todos los programas, funciones, includes y elementos del diccionario son almacenados en tablas. Por lo tanto, NetWeaver cuenta con 63,348 tablas standard...Y eso que hablamos de la versión

Sneak Preview, la versión real del NetWeaver debe tener por lo

menos el doble o triple de tablas.

Elementos del Diccionario de Datos

1.- Tablas

Las tablas se dividen en 3 tipos básicos:

(24)

• Tablas Reunidas (Pooled Tables):

Posee una relación de muchos a uno con una tabla de la Base de Datos. Es decir, por una tabla que existe físicamente en la base de datos, existen muchas tablas en el Diccionario de Datos. Muchas tablas Pool, se encuentran almacenadas físicamente en la Base de Datos en tablas llamadas Pool Tables. Este tipo de tablas, son definidas por SAP.

• Tablas Racimo (Cluster Tables):

Una tabla racimo, es similar a una Pool Table. Poseen una relación de muchos a uno con una tabla de la Base de Datos. Muchas tablas racimo son almacenadas físicamente en la Base de Datos en tablas llamadas Table Cluster. Este tipo de tablas son definidas por SAP y su uso se limita a tablas que son accedidas constantemente, como las tablas del sistema.

2.- Componentes de una tabla

Las tablas están compuestas por campos, y cada campo debe de estar asignado a un Elemento de Datos o a un Tipo Predefinido. Los Elementos de Datos, contienen los nombres del campo, así como también almacenan los valores de la ayuda en línea.

Una definición de Elementos de Datos, requiere a su vez de un Dominio. Los Dominios, contienen las características técnicas de un campo, tales como su longitud y su tipo de dato.

(25)

Tipos de Datos para Dominios

Tanto los Elementos de Datos como los Dominios, son reutilizables. Lo que significa que pueden estar definidos en más de una tabla, sin que esto genere algún tipo de conflicto.

(26)

En esta transacción podremos visualizar, modificar, eliminar o crear los siguientes elementos:

• Tablas Transparentes • Vistas

• Estructuras • Dominios

• Elementos de Datos • Ayudas para búsqueda

1.- Creando una tabla

Para propósitos del libro, vamos a crear 2 tablas, llamadas

(27)

tablas, vamos a trabajar todos los ejemplos del libro, así que es muy importante que las creen para poder seguir los ejemplos con mayor facilidad.

Como se habrán dado cuenta, ambas tablas comienzan con el prefijo “Z”, puesto que es la única restricción que nos da NetWeaver al momento de crear cualquier elemento o componente.

Para crear nuestra primera tabla, hacemos lo siguiente: • Escribimos el nombre de la tabla que queremos crear.

(28)

Clase de Entrega

Casi en un 99% de las veces, se utiliza la clase de entrega A, así que es la que vamos a utilizar nosotros. En todo caso, la única que podríamos utilizar además de esta, son los tipo C y L.

También debemos escoger el tipo de Mantenimiento que se le va a dar a la tabla. En nuestro caso, escogeremos la opción

Display/Maintenance Allowed para poder generar una Vista de

Actualización más adelante.

Cuando grabemos, nos encontraremos con una ventana muy común en NetWeaver. Esta ventana, nos pide asociar nuestra tabla a un

Package (Paquete), que nos es más que una tabla donde se

(29)

utilizamos el paquete $TMP que es local y por lo tanto no transportable (Es decir, no puede salir del ambiente DEV de desarrollo), o podemos crear nuestro propio Package en donde almacenaremos todos los componentes que creemos en el libro. Obviamente, vamos a crear nuestro propio Package, así que debemos hacer lo siguiente:

• Abrimos una nueva ventana o sesión con /oSE80 (Object Navigator). Y escogemos la opción Package de la lista.

• Con un clic derecho, abrimos un menú emergente y escogemos Create Æ Package.

(30)

• Llenamos los campos y presionamos el botón Save.

• NetWeaver nos solicita que ingresemos una Orden de Transporte para almacenar nuestro nuevo Package, presionamos el botón Create Request.

(31)

• Ingresamos una descripción y grabamos.

• Una vez creada y asignada la Orden de Transporte, presionamos el botón Continue o presionamos Enter.

(32)

Atributos del Package ZARTE_PROGRAMAR • Regresamos a la sesión donde teníamos la tabla y hacemos

(33)

• Podemos ingresar el nombre del Package, o solicitar que se muestren todos los disponibles, presionando el botón Start

Search o presionando la tecla Enter.

• En nuestro caso, lo mejor es escribir Z* para que nos muestre solamente los paquetes creados por nosotros o por el sistema (Definidos para los usuarios).

(34)

• Presionamos el botón Save. Y nos va a aparecer la ventana solicitando una Orden de Transporte. Como creamos una orden al momento de crear el Package, entonces la misma orden aparecerá por defecto. Presionamos el botón Continue o la tecla Enter.

Ahora, podemos continuar con la creación de nuestra tabla.

Debemos ir a la pestaña Fields (Campos), para poder agregar los campos necesarios para nuestra tabla.

(35)

El primer campo que vamos a utilizar es el MANDT, que identifica al ambiente en el cual estamos trabajando (Y que es un campo llave). El segundo campo, se llamará Id, y será el encargado de identificar a cada uno de los registros (También es un campo llave).

Como se darán cuenta, en el gráfico no he llenado el campo

Data Element (Elemento de Datos), para el campo Id. Esto es

(36)

• Queremos que el tipo de dato sea CHAR y tenga una longitud de 3, además, agregamos una pequeña descripción del campo.

• El siguiente campo también necesita un tipo predefinido, así que lo llamamos Nombre y lo definimos como un CHAR de longitud 15.

• El siguiente campo se llamará Entorno. Este estará relacionado con una tabla que llamaremos

ZENTORNOS_PROG, así que abrimos otro modo para

poder crearla, antes de continuar con la tabla

ZLENGUAJES_PROG.

• Al igual que en la tabla ZLENGUAJES_PROG, los 2 primeros campos serán Mandt y Id.

(37)

• El tercer campo, se llamará Nombre, y no tendrá asociado un Tipo Predefinido, sino que contará con un Elemento de Datos y un Dominio. Para esto, abrimos una nueva ventana en la SE11 y nos posicionamos en Domain (Dominio).

2.- Creando un Dominio

A este Dominio, lo llamaremos ZD_ENT_NAME. Llenamos los campos como se muestra en la imagen.

(38)

Lo grabamos y lo activamos utilizando el botón Activate (Activar) o presionando Crtl + F3.

3.- Creando un Elemento de Datos

• Una vez creado el Dominio, pasamos a crear nuestro Data

Element (Elemento de Datos). En la misma transacción, nos

posicionamos en Data Type (Tipo de Dato).

Lo llamaremos ZE_ENT_NAME. Se dará cuenta, de que al momento de presionar el botón Create, aparece una ventana preguntándonos por el Tipo de Dato que queremos crear. Lo dejamos como Data Element y presionamos Enter. Llenamos los datos como se muestra en la figura, utilizando el Dominio que creamos.

(39)

Ahora, debemos pasar a la pestaña Field Label (Etiqueta de Campo), que no es más que la descripción del Elemento de Datos. La llenamos como se muestra en la figura. Grabamos y activamos.

• Regresamos a la ventana donde estábamos creando la tabla

ZENTORNO_PROG.

• Como estábamos ingresando Tipos Predefinidos, debemos presionar el botón Data Element . E ingresar el nombre de nuestro Elemento de Datos.

(40)

llenar el Enhacement Category (Categoría de Ampliación) Æ Extras Æ Enhacement Category.

El campo Data Class (Clase de Datos) especifica el área física en la cual se va a crear la tabla. Para nosotros, el valor por defecto siempre será APPL0.

El campo Size Category (Categoría de Tamaño), determina la cantidad de espacio que se reservará inicialmente para la tabla, en nuestro caso, nuestra tabla no contendrá mucho datos, así que 0 es la opción a tomar.

(41)

Esto sirve para definir si la tabla puede ser modificada con campos adicionales. En nuestro caso, le decimos que no, puesto que son tablas que hemos creado como ejemplo para el libro.

Grabamos y activamos.

• Regresamos a nuestra tabla ZLENGUAJES_PROG y presionamos el botón Data Element, para poder ingresar nuestro Elemento de Datos para el campo Entorno.

• Nos posicionamos sobre el campo Entorno y presionamos el botón Foreign Keys (Llaves Foráneas) . Esto nos mostrará una ventana, que veremos a continuación.

(42)

En el campo Check Table (Tabla de Verificación), escribimos el nombre de nuestra tabla ZENTORNOS_PROG. Y presionamos Enter.

El sistema nos propone crear una asignación entre las tablas, presionamos Yes (Sí) o presionamos Enter.

(43)

Recibimos este mensaje, porque la llave completa de la tabla

ZENTORNOS_PROG no existe en la tabla ZLENGUAJES_PROG.

(44)

vamos a crear nuevamente un Dominio (ZD_CONEX_SAP) y un Elemento de Datos (ZE_CONEX_SAP).

Como ven, es simplemente un CHAR de 1. Ahora, pasamos a la pestaña Value Range (Rango de Valores). Y llenamos solamente dos valores.

(45)

• Grabamos, activamos y creamos nuestro Elemento de Datos.

Llenamos la pestaña Field Label (Etiqueta de Campo), grabamos y activamos.

(46)

Ahora que tenemos nuestras dos tablas listas, es hora de agregar algunos datos. Nos vamos a la transacción SE16 (Browser de Datos). Colocamos el nombre de nuestra tabla de entornos, y presionamos el botón Create Entries (Crear Entradas) o presionamos F5.

Ingresamos algunos cuantos valores. Y grabamos con el botón Save (Guardar) o presionamos Crtl. + S.

(47)

Una vez que hemos terminado de insertar registros, retrocedemos presionando el botón Back (Atrás) o presionando el botón F3. Para poder ver los registro que hemos creado, podemos presionar el botón Table Contents (Contenido de Tabla) o presionar Enter.

En esta ventana, podemos hacer un filtro ya sea por Id o por Entorno. En nuestro caso, queremos ver todos los valores, así que dejamos esos campos en blanco. Presionamos el botón Execute

(48)

Tenemos 3 registros grabados en la base de datos. Ahora, es el turno de la tabla ZLENGUAJES_PROG.

Seguimos el mismo procedimiento.

Cuando se posicionen en el campo Entorno, se darán cuenta de algo interesante. Aparece un pequeño botón al final del campo, lo cual nos indica que existen valores de los cuales podemos escoger. Para esto debemos hacer clic en ese botón o presionar F4.

(49)

Esos son los registros que ingresamos en la tabla

ZENTORNOS_PROG y que ahora podemos insertar en nuestra

tabla ZLENGUAJES_PROG. Lo mismo sucede con el campo

CONEX_SAP.

(50)

Ingresamos algunos datos y estamos listos.

Seguramente, les parecerá que ingresar los datos así, es un poco tedioso...No se preocupen, que ahora vamos a crear una vista de actualización.

3.- Creando una Vista de Actualización

Para crear nuestra vista de actualización, debemos regresar a la transacción SE11 y modificar la tabla ZLENGUAJES_PROG. En el menú, vamos a Utilities (Utilidades) Æ Table Maintenance

Generator (Generador de Mantenimiento de Tabla).

(51)

Presionamos el botón Find Scr. Number(s) (Buscar Número(s) de Pantalla) o presionamos Shift + F7.

En esta ventana, siempre escogemos la primera opción Propose

(52)

Finalmente presionamos el botón Create (Crear) o presionamos

F6. Grabamos y activamos. Ahora, debemos ir a la transacción SM30.

Y presionar el botón Maintain.

Se nos muestra una pantalla más amigable para el ingreso de datos, pero como se darán cuenta, los dos primeros campos aparecen como

(53)

“+”. Esto es porque al ser Tipos Predefinidos, no poseen un texto descriptivo. Esto lo podemos solucionar fácilmente regresando a la transacción SE11 y al Generador de Mantenimiento de Tabla.

Debemos hacer clic tanto en el Overview Screen (Ventana de Vista general) como en el Single Screen (Ventana sencilla).

(54)

Seguramente esta pantalla los asusta un poco, pero no se preocupen, que por el momento no vamos a hacer nada con esto, puesto que es código generado automáticamente por el NetWeaver.

Debemos hacer clic en el botón Layout (Disposición) . La pantalla del Screen Painter es la que nos interesa, sobre todos las cabeceras que tienen un “+”.

(55)

Debemos hacer un clic en el botón Display > Change (Mostrar <-> Cambiar) o presionar F1.

Ahora, nos colocamos sobre la primer columna y en la ventana que dice Text (Texto), escribimos lo siguiente

Y en la segunda columna:

Grabamos, activamos y retrocedemos dos veces hasta regresar a la ventana del Generador de Mantenimiento de Tabla.

(56)

Y repetimos la operación, modificando los símbolos “+”. Grabamos, activamos y regresamos nuevamente.

Una vez hecho esto, nos vamos a la transacción SM30 y veremos que los símbolos “+” han sido reemplazados por los textos correctos.

Ahora, para hacer las cosas más interesantes y poder trabajar mejor los ejemplos del libro, regresamos a la transacción SE11 para crear una nueva y última tabla con las siguientes características.

(57)

La tabla se llamará ZPROGRAMAS y contendrá algunos programas que hemos hecho utilizando los lenguajes de programación que hemos creado.

En otra ventana, creamos un dominio para el código del lenguaje de programación, llamado ZD_ID_LENGUAJE.

(58)

Regresamos a la tabla ZPROGRAMAS y tendremos la siguiente estructura:

Para que esto funcione correctamente y podamos hacer una asociación entre las tablas ZPROGRAMAS y

(59)

ZLENGUAJES_PROG incluyendo el Elemento de Datos que

creamos:

Luego de haber grabado y activado, regresamos a ZPROGRAMAS y nos posicionamos en el campo Id y presionamos el botón Foreign

(60)

Grabamos, actualizamos las Características Técnicas y la Categoría de Amplicación y activamos la tabla.

Como solamente hemos asignado el campo Id a nuestra tabla, al momento de querer elegir un lenguaje de programación, solamente vamos a ver el código, lo cual no nos va a ayudar de mucho, así que hora de crear una ayuda de búsqueda.

4.- Creando una Ayuda de Búsqueda

Para esto, en una nueva ventana, vamos a la transacción SE11. Y escogemos la opción Seach Help (Ayuda de búsqueda).

(61)

Como pueden ver, el campo Nombre tiene asignamos un elemento de datos, así que nuevamente, creamos un Dominio y un Elemento de Datos como se muestra a continuación.

(62)

Grabamos y activamos nuestra ayuda de búsqueda y la probamos con presionando el botón Test (Prueba) o presionando F8.

(63)

En esta ventana, podemos filtrar por Id o por Nombre del lenguaje, en este caso, presionamos Enter porque queremos ver todos los registros disponibles.

Nuestra ayuda de búsqueda está terminada, así que regresamos a la tabla ZPROGRAMAS a la pestaña Entry Help/Check (Entrada de Ayuda/Verificación).

(64)

Asignamos la ayuda de búsqueda que creamos.

Grabamos y activamos.

(65)

Como podemos ver, al hacer F4 en el campo Id, podremos ver tanto el código como el nombre del Lenguaje.

Finalmente, nuestra tabla contendrá los siguientes registros.

Con esto terminamos y podemos crear una estructura, que no es otra caso que una tabla que solamente contiene una cabecera, es decir, no puede almacenar registros. Esto nos va a ser útil al momento de desarrollar nuestros programas, puesto que vamos a poder contar con la estructura sin utilizar memoria adicional de la base de datos.

5.- Creando una Estructura

En la transacción SE11, en el campo Data type, creamos nuestra estructura llamada ZSLENGUAJES_PROG.

(66)

Cuando presionamos Create (Crear) , se nos muestra una ventana en donde debemos elegir Structure (Estructura).

Utilizamos los mismos componentes que en la tabla

ZLENGUAJES_PROG, aunque quitamos el campo MANDT.

Grabamos y activamos. Nos va a pedir, el Enhacement Category (Categoría de ampliación), lo agregamos para poder activar.

6.- Creando una Vista

Dentro de la transacción SE11, creamos nuestra vista en el campo

(67)

En la ventana que aparece, elegimos Database view (Vista de Base de Datos). Los demás tipos no los vamos a ver en este libro, puesto que el Database view es el más utilizado.

Primero, debemos de llenar los campos que vamos a utilizar para relacionar las tablas que vamos a utilizar en la vista, en este caso,

(68)

En la pestaña View Flds (Campos de la Vista). Definimos los campos que queremos que se muestren en la vista.

Grabamos y activamos. Los mensajes de advertencia, podemos obviarlos.

Una vez que la Vista está activa, podemos comprobar los valores presionando el botón Contents (Contenidos) o presionando Ctrl.

+ Shift + F10.

Se darán cuenta de que el sistema no envía a la transacción SE16.

(69)

Con esto, terminamos el capítulo dedicado a Diccionario de Datos. Ahora, ya pueden crear sus propias tablas, elementos de datos, dominios o vistas.

(70)

Programación en ABAP

Introducción

ABAP (Advances Business Application Programming), es el

lenguaje de programación propietario de SAP AG, con el cual se desarrollan aplicaciones que son integradas al NetWeaver. Cabe de destacar que muchos de los componentes de NetWeaver han sido desarrollados utilizado ABAP, lo cual nos permite hacer modificaciones que otro tipo de sistemas serían imposibles.

El ABAP, viene a ser una especie de nieto del COBOL (Common Object Business Oriented Language), que era muy utilizado para el desarrollo de aplicaciones empresariales.

En cuanto a la sintaxis de lenguajes, podemos tomarlo como un híbrido entre COBOL, PASCAL y SQL Server.

Hasta la versión 45B, el ABAP, era un lenguaje procedural, aunque con el tiempo se el agregaron funcionalidades para convertirlo en un lenguaje orientado a objetos, por lo cual al momento de programar, se pueden mezclar ambas tecnologías sin mayores problemas.

El NetWeaver actualmente está en la versión 7.0.0, lo cual significa que nos permite trabajar con ABAP Objects de manera muy completa, aunque como es de suponerse, en versiones posteriores de

NetWeaver, se adicionarán algunos componentes extras.

En el presente capítulo, vamos a revisar los principales componentes del ABAP, así como la estructura de los programas que se crean con el.

(71)

Estructura de un programa en ABAP

Para crear un programa en ABAP, debemos ingresar a la transacción

SE38, y especificar el nombre del programa que queremos crear.

Recodemos que debemos utilizar la letra Z antes del nombre del programa. Esto es porque SAP, reserva el nombre Z para los programas que son creados por los clientes y no por los mismos trabajadores de SAP.

(72)

En Type (Tipo) siempre escogemos Executable program (Programa ejecutable) y en Status (Estado), elegimos SAP

Standard Production Program (Programa Standard SAP para

Productivo).

Al presionar el botón Save , nos va a pedir el paquete al cual queremos asignar el desarrollo, elegimos

ZARTE_PROGRAMAR. Y cuando nos pida la orden de

transporte, elegimos la creamos puesto que se nos muestra por defecto (Siempre y cuando no hayamos creado otras ordenes).

El sistema, nos envía al Editor ABAP, que es donde vamos a poder crear nuestros programas. Debemos tener claro, que existen ciertos comentarios, que debemos colocar en todos nuestros programas, para poder definir algunos bloques importantes.

(73)

En el espacio de comentario, debemos incluir por ejemplo, quien está creando el programa y cuando.

La primera y única línea que nos muestra el editor es REPORT y el nombre de nuestro programa. Esto indica que se trata de un programa ejecutable.

(74)

*&---* *& Report ZDUMMY_PRIMER_PROGRAMA * *&---* *& Creado por: Alvaro "Blag" Tejada Galindo. * *& Fecha creación: 14 de Noviembre del 2007 * *&---* REPORT ZDUMMY_PRIMER_PROGRAMA.

*=====================================================* * SELECTION-SCREEN * *=====================================================*

SELECTION-SCREEN BEGIN OF BLOCK PRUEBA

WITH FRAME TITLE TEXT-T01.

PARAMETERS:

TEXTO(30) TYPE C.

SELECTION-SCREEN END OF BLOCK PRUEBA.

*=====================================================* * START-OF-SELECTION * *=====================================================*

START-OF-SELECTION.

WRITE: TEXTO.

El SELECTION-SCREEN BEGIN OF BLOCK, nos permite definir un espacio en donde van a ir los parámetros de entrada de nuestro programa. PRUEBA, es el nombre que le estamos asignando al bloque de parámetros.

WITH FRAME TITLE, significa que el área de los parámetros

de selección va a estar rodeados por un marco y TITLE, significa que va a contar con un título definido por nosotros, en este caso

(75)

TEXT-T01. TEXT-T01, lo podemos separar en dos partes TEXT,

que nos indica que es un texto del sistema y T01, es el nombre de dicho texto. Para poder modificarlo, simplemente deberemos hacer doble clic en el texto. Si no lo hemos creado, nos aparecerá la siguiente ventana:

Simplemente, ingresamos el texto, grabamos y activamos. Dentro del bloque que hemos definido para los parámetros, podemos utilizar

(76)

El parámetro que hemos utilizado en este programa, es un CHAR de

30 caracteres.

TEXTO(30) TYPE C.

Si activamos y ejecutamos el reporte (Presionando la tecla F8), veremos el parámetro de entrada que definimos.

Ahora, si queremos cambiar el texto que muestra nuestro parámetro, deberemos de ingresar al siguiente menú.

(77)

Aquí, deberemos de ingresar el texto que queremos que tenga nuestro parámetro, lo grabamos, lo activamos y listo.

(78)

El START-OF-SELECTION, nos indica que va a comenzar la ejecución de nuestro programa, es aquí donde colocamos toda la lógica.

WRITE: TEXTO, significa que vamos a escribir en la pantalla, el

valor que hemos ingresado en el parámetro de entrada TEXTO.

Ese fue nuestro primer y más simple programa en ABAP.

Declaración de Variables y Tablas Internas

Para poder declarar variables, utilizamos la sentencia DATA, que lo único que hace es separar un espacio en memoria.

(79)

Aquí estamos diciendo que vamos a crear una variable llamada

TEXTO, y que va a ser de tipo C (Caracter). Además, podemos

especificar su tamaño.

DATA: TEXTO(30) TYPE C.

Entre los tipos de datos que nos ofrece el ABAP, tenemos:

C Character 1 Space N Numeric String 1 ’00…0’ D Date (YYYYMMDD) 8 ‘000000000’ T Time (HHMMSS) 6 ‘000000’ X Byte (Hexadecimal) 1 X’00’ I Integer 4 0 P Packed Integer 8 0 F Floating point number 8 ‘0.0’ STRING String Variable Empty string

(80)

DATA: V_CARRID TYPE SPFLI-CARRID.

En este caso, estamos declarando una variable que va a ser exactamente igual que el campo CARRID de la tabla SPFLI.

Por lo tanto, V_CARRID es un CHAR de 3 caracteres.

Ahora veamos las tablas internas, que son uno de los elementos más valiosos del ABAP.

Las tablas internas, son tablas temporales que existen solamente en el ámbito del programa que las creó y permiten almacenar información para luego poder manipularla sin tener que acceder múltiples veces a la base de datos.

En versiones anteriores, podíamos utilizar la siguiente sintaxis:

DATA: BEGIN OF TABLA OCCURS 0,

END OF TABLA.

Con la introducción de NetWeaver, esto no es posible, así que de ahora en adelante, vamos a utilizar y aprender solamente las nuevas sintaxis que se nos ofrecen gracias a la creación del ABAP Objects.

TYPES: BEGIN OF TY_TABLA,

END OF TY_TABLA.

DATA: T_TABLA TYPE STANDARD TABLE OF TY_TABLA.

(81)

Primero, debemos crear un TYPE, es decir, un tipo de tabla interna y luego, utilizando el DATA, creamos una tabla interna que haga referencia a nuestro tipo de tabla.

Para los que ya conocen ABAP, se darán cuenta de que no hemos creado la tabla con una cabecera. Es decir, no utilizamos ni

OCCURS 0, ni tampoco WITH HEADER LINE. Esto es porque,

en ABAP Objects, está prohibido utilizar cabeceras o workareas. Para los que no conocen ABAP, en versiones anteriores, podiamos crear tablas internas con líneas de cabecera, lo cual facilitaba la lectura de datos, pero que al mismo tiempo ocasionaba problemas de performance. Es por eso, que SAP decició eliminar la cabeceras completamente.

Además de crear tablas internas, de la manera que hemos visto, podemos también incluir estructuras completas de Base de Datos. Esto podemos hacerlo de dos maneras, dependiendo de si queremos o no incluir campos adicionales.

DATA: T_SPFLI TYPE STANDARD TABLE OF SPFLI.

(82)

Claro, si queremos crear una tabla interna que tenga datos propios, lo hacemos de la siguiente forma.

TYPES: BEGIN OF TY_TEST, NOMBRE(30) TYPE C, EDAD TYPE I,

END OF TY_TEST.

DATA: TEST TYPE STANDARD TABLE OF TY_TEST.

Seguramente se habrán dado cuenta y sobre todo se preguntarán, porque tenemos que utilizar el TYPE STANDARD TABLE, muy simple, porque tenemos disponibles más tipos de tablas.

TYPES: BEGIN OF TY_TEST, ID(3) TYPE C,

NOMBRE TYPE STRING, EDAD TYPE I,

END OF TY_TEST.

DATA: TEST TYPE STANDARD TABLE OF TY_TEST.

DATA: TEST_H TYPE HASHED TABLE OF TY_TEST

WITH UNIQUE KEY ID.

DATA: TEST_S TYPE SORTED TABLE OF TY_TEST

WITH UNIQUE KEY ID

(83)

TEST Æ Tablas Standard. Puede ser accedida mediante un índice o

mediante campos.

TEST_H Æ Tabla de tipo hashed. De rápido acceso, pero no puede

ser accedida mediante un índice.

TEST_S Æ Sorted table. De rápido acceso, siempre está ordenada,

no puede ser accedida mediante un índice.

En realidad, el uso de tablas Hashed o Sorted, depende del nivel de nivel de datos o de la complejidad del programa, en lo personal, solo he utilizado este tipo de tablas algunas cuantas veces en toda mi carrera.

Selección de Datos

Al igual que en SQL, podemos utilizar la clásica sentencia

SELECT, para poder seleccionar datos. Aunque en el caso de ABAP, tenemos mayor flexibilidad para poder almacenar los datos,

ya sea en Variable o en Tablas internas. En Variables:

(84)

Declaramos una variable llamada NOMBRE del tipo del campo

NOM_PROG de la tabla ZPROGRAMAS. Hacemos un SELECT SINGLE para obtener un registro cuyo campo ID_PROG sea igual

a 001.

En Tablas internas:

TYPES: BEGIN OF TY_PROGRAMAS,

NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS.

SELECT NOM_PROG

INTO TABLE T_PROGRAMAS

FROM ZPROGRAMAS.

En esta caso, creamos un TYPE, luego una tabla interna y finalmente leemos todas las instancias del campo NOM_PROG dentro de nuestra tabla interna.

Claro, también podemos utilizar INNER JOINS para hacer nuestras consultas.

TYPES: BEGIN OF TY_PROGRAMAS,

NOMBRE TYPE ZLENGUAJES_PROG-NOMBRE, ENTORNO TYPE ZLENGUAJES_PROG-ENTORNO, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG,

(85)

DATA: T_PROGRAMAS TYPE STANDARD TABLE OF TY_PROGRAMAS.

SELECT NOMBRE ENTORNO NOM_PROG

INTO TABLE T_PROGRAMAS

FROM ( ZLENGUAJES_PROG INNER JOIN ZPROGRAMAS

ON ZLENGUAJES_PROG~ID = ZPROGRAMAS~ID ).

Ahora, supongamos que tenemos un campo más en nuestra tabla interna, pero no queremos seleccionarlo, entonces, el SELECT va a estar incompleto y los registros pueden guardarse donde no les corresponde. Esto lo podemos solucionar utilizando un INTO

CORRESPONDING FIELDS, que lo que hace es almacenar los

registros en los campos correspondientes, aunque claro, esto afecta el performance de nuestros programas, así que lo mejor es evitarlos.

TYPES: BEGIN OF TY_PROGRAMAS,

NOMBRE TYPE ZLENGUAJES_PROG-NOMBRE, ENTORNO TYPE ZLENGUAJES_PROG-ENTORNO, CONEX_SAP TYPE ZLENGUAJES_PROG-CONEX_SAP, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG,

END OF TY_PROGRAMAS.

(86)

Lectura de datos de Tablas Internas

Una vez que tenemos datos en nuestras tablas internas, debemos de leerlas para poder hacer algo con ellas. Para eso, contamos con dos opciones.

Aunque, antes de eso, debemos conocer un elemento muy importante, sin el cual no podríamos hacer mucho en ABAP.

Estamos hablando de los Field-Symbols. Para los que han programado alguna vez en C++, los Fields-Symbols, son muy parecidos a los punteros, es decir, almacenas la dirección en memoria de una variable. Por lo general, los utilizamos para crear cabeceras de tablas internas.

FIELD-SYMBOLS: <FS_TABLA> LIKE LINE OF T_TABLA.

Con esto, creamos una referencia a la tabla T_TABLA, la cual contiene únicamente una línea de cabecera, con lo cual ganamos mucho performance al hacer lecturas de tablas internas.

• LOOP AT

TYPES: BEGIN OF TY_PROGRAMAS,

NOMBRE TYPE ZLENGUAJES_PROG-NOMBRE, ENTORNO TYPE ZLENGUAJES_PROG-ENTORNO, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

(87)

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

OF T_PROGRAMAS.

SELECT NOMBRE ENTORNO NOM_PROG

INTO TABLE T_PROGRAMAS

FROM ( ZLENGUAJES_PROG INNER JOIN ZPROGRAMAS

ON ZLENGUAJES_PROG~ID = ZPROGRAMAS~ID ).

LOOP AT T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>. WRITE:/ <FS_PROGRAMAS>-NOM_PROG.

ENDLOOP.

Al hacer un LOOP AT, lo que hacemos es leer cada uno de los registros almacenados en nuestra tabla interna, y al asignar cada uno de estos registros a nuestro Field-Symbol, lo que estamos haciendo es pasar simplemente la cabecera de ese registro, por lo cual la lectura de la tablas es mucho más veloz. Finalmente, utilizando un WRITE imprimimos el contenido del campo NOM_PROG. El símbolo / nos sirve para dejar un espacio hacia abajo luego de haber impreso el valor

(88)

• READ TABLE

TYPES: BEGIN OF TY_PROGRAMAS,

NOMBRE TYPE ZLENGUAJES_PROG-NOMBRE, ENTORNO TYPE ZLENGUAJES_PROG-ENTORNO, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

OF T_PROGRAMAS.

SELECT NOMBRE ENTORNO NOM_PROG

INTO TABLE T_PROGRAMAS

FROM ( ZLENGUAJES_PROG INNER JOIN ZPROGRAMAS

ON ZLENGUAJES_PROG~ID = ZPROGRAMAS~ID ).

READ TABLE T_PROGRAMAS INDEX 1

ASSIGNING <FS_PROGRAMAS>.

WRITE:/ <FS_PROGRAMAS>-NOM_PROG.

READ TABLE T_PROGRAMAS

WITH KEY NOMBRE = 'PHP'

ASSIGNING <FS_PROGRAMAS>.

WRITE:/ <FS_PROGRAMAS>-NOM_PROG.

En este caso, al utilizar un READ TABLE, leemos un solo registro de nuestra tabla, como podemos ver, podemos utilizar

(89)

un Indice o también un Campo para leer el contenido y asignarlo a nuestro Field-Symbol.

Operadores de Comparación

Un proceso muy común, es el comparar valores entre variables o tablas internas, para esto, contamos con los siguientes comandos.

=, EQ Igual a <>, NE Distinto a >, GT Mayor que <, LT Menor que >=, GE Mayor igual <=, LE Menor igual

Ambos tipos de comandos son equivalentes, por lo tanto es lo mismo decir:

IF NOMBRE EQ ‘PHP’. WRITE:/ ‘Viva PHP!’. ENDIF.

(90)

ENDIF.

Para poder afianzar los conocimientos adquiridos hasta el momento, vamos a crear una pequeña aplicación.

REPORT ZDUMMY_PRIMER_PROGRAMA

NO STANDARD PAGE HEADING.

*=====================================================* * DECLARACION DE TABLES * *=====================================================* TABLES: ZPROGRAMAS. *=====================================================* * DECLARACION DE TYPES * *=====================================================* TYPES: BEGIN OF TY_PROGRAMAS,

NOMBRE TYPE ZLENGUAJES_PROG-NOMBRE, ENTORNO TYPE ZLENGUAJES_PROG-ENTORNO, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

*=====================================================* * DECLARACION DE VARIABLES * *=====================================================* DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS.

*=====================================================* * FIELD-SYMBOLS * *=====================================================* FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

(91)

OF T_PROGRAMAS.

*=====================================================* * SELECTION-SCREEN * *=====================================================*

SELECTION-SCREEN BEGIN OF BLOCK PRG

WITH FRAME TITLE TEXT-T01.

SELECT-OPTIONS:

S_ID FOR ZPROGRAMAS-ID. SELECTION-SCREEN END OF BLOCK PRG.

*=====================================================* * START-OF-SELECTION * *=====================================================*

START-OF-SELECTION.

SELECT NOMBRE ENTORNO NOM_PROG

INTO TABLE T_PROGRAMAS

FROM ( ZLENGUAJES_PROG INNER JOIN ZPROGRAMAS

ON ZLENGUAJES_PROG~ID = ZPROGRAMAS~ID )

WHERE ZPROGRAMAS~ID IN S_ID.

WRITE:/1 'Lenguaje',17 'Entorno',33 'Programa'.

WRITE:/ SY-ULINE(45).

(92)

Analicemos un poco el programa antes de ejecutarlo y ver el resultado.

REPORT ZDUMMY_PRIMER_PROGRAMA

NO STANDARD PAGE HEADING.

REPORT indica que estamos creando y ejecutando un programa. ZDUMMY_PRIMER_PROGRAMA es el nombre de nuestro

programa.

NO STANDARD PAGE HEADING, indica que no queremos que

el título del programa se muestre en el output del reporte.

TABLES: ZPROGRAMAS.

TABLES indica que vamos a utilizar una tabla para hacer referencia

a un campo en el SELECTION-SCREEN.

TYPES: BEGIN OF TY_PROGRAMAS,

NOMBRE TYPE ZLENGUAJES_PROG-NOMBRE, ENTORNO TYPE ZLENGUAJES_PROG-ENTORNO, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

TYPES indica que vamos a crear un tipo de tabla definido por

nosotros.

DATA: T_PROGRAMAS TYPE STANDARD TABLE OF TY_PROGRAMAS.

(93)

DATA indica que vamos a crear una variable o una tabla interna. T_PROGRAMAS es el nombre de nuestra tabla interna.

TYPE STANDARD TABLE indica que la tabla es de tipo STANDARD.

OF indica a que tipo de dato va a hacer referencia nuestra tabla

interna.

TY_PROGRAMAS es el nombre del tipo de tabla que creamos y al

cual va a hacer referencia nuestra tabla interna.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE OF T_PROGRAMAS.

FIELD-SYMBOLS crea un field-symbol.

<FS_PROGRAMAS> es el nombre de nuestro field-symbol.

LIKE LINE OF indica que va a representar una línea de cabecera

de una tabla interna.

T_PROGRAMAS es la tabla interna de la cual el field-symbol va a

representar la cabecera.

SELECTION-SCREEN BEGIN OF BLOCK PRG

WITH FRAME TITLE TEXT-T01.

(94)

WITH FRAME indica que nuestro bloque de parámetro debe tener

un marco (más que nada un tema de visualización).

TITLE TEXT indica que el bloque de parámetros debe tener un

título.

T01 contiene el título.

SELECT-OPTIONS indica que es un parámetros con rango de

valores.

S_ID es el nombre del SELECT-OPTION.

FOR indica que hace referencia a un campo de Base de Datos. ZPROGRAMAS-ID es el nombre de la Base de Datos y el campo

respectivamente.

SELECTION-SCREEN END OF indica el fin del bloque de

parámetros.

START-OF-SELECTION.

START-OF-SELECTION indica el inicio de nuestro programa.

SELECT NOMBRE ENTORNO NOM_PROG

INTO TABLE T_PROGRAMAS

FROM ( ZLENGUAJES_PROG INNER JOIN ZPROGRAMAS

ON ZLENGUAJES_PROG~ID = ZPROGRAMAS~ID )

WHERE ZPROGRAMAS~ID IN S_ID.

SELECT indica que queremos seleccionar datos.

NOMBRE ENTORNO NOM_PROG son los campos que

(95)

INTO TABLE indica en que tabla interna queremos guardar los

datos.

T_PROGRAMAS es la tabla donde vamos a guardar los datos.

FROM indica de donde queremos obtener los datos.

ZLENGUAJES_PROG INNER JOIN ZPROGRAMAS indica

que queremos realizar un INNER JOIN entre estas dos tablas

ON indica el parámetro de igualdad de campos del INNER JOIN. ZLENGUAJES~ID = ZPROGRAMAS~ID indica que el campo ID de ambas tablas va a utilizarse como campo de igualdad.

WHERE indica el parámetro de restricción del SELECT.

ZPROGRAMAS~ID es el campo por el cual queremos hacer el

filtro.

IN indica que el campo del filtro debe de estar dentro de los valores

del SELECT-OPTION.

S_ID es el SELECT-OPTION contra el cual vamos a validar el

campo ZPROGRAMAS~ID.

WRITE:/1 'Lenguaje',17 'Entorno',33 'Programa'.

WRITE:/ SY-ULINE(45).

(96)

SY-ULINE(45) es una variable del sistema que nos permite dibujar

una línea. El 45 entre paréntesis indica la longitud de la línea.

LOOP AT T_PROGRAMAS

ASSIGNING <FS_PROGRAMAS>.

WRITE:/ <FS_PROGRAMAS>-NOMBRE,<FS_PROGRAMAS>-ENTORNO, <FS_PROGRAMAS>-NOM_PROG.

ENDLOOP.

LOOP AT indica que vamos a recorrer todos los registros de una

tabla interna.

T_PROGRAMAS es la tabla interna de la cual vamos a leer los

registros.

ASSIGNING <FS_PROGRAMAS> indica que vamos a asignar el

registro leído a un Field-Symbol.

<FS_PROGRAMAS> es el nombre del Field-Symbol.

<FS_PROGRAMA>-NOMBRE es el nombre del campo que

queremos escribir en la pantalla.

ENDLOOP indica el fín del LOOP.

Ahora que ya hemos revisado todo el programa línea por línea, podemos ejecutarlo.

(97)

Si queremos que nuestro programa se vea un poco más colorido, podemos agregar un par de líneas.

(98)

FORMAT COLOR indica que queremos pintar el fondo de un

color.

5 representa al color verde.

FORMAT COLOR OFF indica que ya no queremos seguir

pintando el fondo de un color. El reporte quedaría así:

Operaciones en tablas internas

Cuando se trabaja con tablas internas, muchas veces se necesita agregar, modificar o eliminar registros (Ya sea porque no nos sirven o porque están duplicados). Veamos como manejar esto:

• Agregando registros

TYPES: BEGIN OF TY_PROGRAMAS,

(99)

NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

OF T_PROGRAMAS.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'.

READ TABLE T_PROGRAMAS INDEX 1

ASSIGNING <FS_PROGRAMAS>.

WRITE:/ <FS_PROGRAMAS>-ID_PROG.

WRITE:/ <FS_PROGRAMAS>-NOM_PROG.

Como vemos, creamos una tabla interna. Pero como esta no tiene cabecera, entonces debemos asignarle una utilizando

APPEND INITIAL LINE TO y asignándola a <FS_PROGRAMAS>.

(100)

• Modificando registros

TYPES: BEGIN OF TY_PROGRAMAS,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

OF T_PROGRAMAS.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'.

READ TABLE T_PROGRAMAS INDEX 1

ASSIGNING <FS_PROGRAMAS>.

WRITE:/ <FS_PROGRAMAS>-ID_PROG.

WRITE:/ <FS_PROGRAMAS>-NOM_PROG.

READ TABLE T_PROGRAMAS INDEX 1

ASSIGNING <FS_PROGRAMAS>.

SKIP 1.

WRITE:/ 'Modificamos el registro'.

(101)

<FS_PROGRAMAS>-NOM_PROG = 'Web Browser'.

READ TABLE T_PROGRAMAS INDEX 1

ASSIGNING <FS_PROGRAMAS>.

WRITE:/ <FS_PROGRAMAS>-ID_PROG.

WRITE:/ <FS_PROGRAMAS>-NOM_PROG.

Tomando el ejemplo anterior, leemos el primer registro y lo asignamos a <FS_PROGRAMAS>. Simplemente escribimos el nuevo valor para que se modifique automáticamente. Podrán ver que además, estamos utilizando la sentencia SKIP, esta sentencia nos permite realizar saltos de línea. En esta caso solamente 1.

• Eliminado registros

TYPES: BEGIN OF TY_PROGRAMAS,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

(102)

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '007'.

<FS_PROGRAMAS>-NOM_PROG = 'Web Browser'.

DELETE T_PROGRAMAS INDEX 1.

DELETE T_PROGRAMAS WHERE ID_PROG EQ '006'.

Asignamos dos registros a nuestra tabla interna, y como podemos ver, podemos eliminarlos utilizando ya sea un índice o uno de los campos como parámetro de búsqueda. Ahora, supongamos que tenemos registros repetidos y queremos eliminarlos sin preocuparnos por el índice (Puesto que eliminado por campo, eliminaríamos todos los registros).

TYPES: BEGIN OF TY_PROGRAMAS,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

(103)

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE OF T_PROGRAMAS.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'.

DELETE ADJACENT DUPLICATES FROM T_PROGRAMAS.

Como podemos ver, tenemos dos veces el mismo registro, por lo tanto utilizamos DELETE ADJACENT

DUPLICATES para dejar solamente uno de los dos

registros.

Claro, quizás se podría dar el caso de que solamente el campo ID_PROG esté repetido, más no el campo

(104)

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE OF T_PROGRAMAS.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'Web Browser'.

DELETE ADJACENT DUPLICATES FROM T_PROGRAMAS

COMPARING ID_PROG.

Simplemente debemos agregar un COMPARING, con lo cual solamente se toma en cuenta el campo ID_PROG para hacer la validación de registros repetidos.

Copiar tablas internas

Algunas veces, necesitamos copiar el contenido de una tabla interna a otra. En este caso, dos opciones, las tablas tienen la misma estructura o tienen una estructura distinta.

(105)

• Copiar tablas con la misma estructura

TYPES: BEGIN OF TY_PROGRAMAS,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS,

T_PROGRAMAS_AUX TYPE STANDARD TABLE

OF TY_PROGRAMAS.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE OF T_PROGRAMAS.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'. T_PROGRAMAS_AUX[] = T_PROGRAMAS[].

(106)

• Copiar tablas con diferente estructura

TYPES: BEGIN OF TY_PROGRAMAS,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

TYPES: BEGIN OF TY_PROGRAMAS_AUX, ID TYPE ZPROGRAMAS-ID,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS_AUX.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS,

T_PROGRAMAS_AUX TYPE STANDARD TABLE

OF TY_PROGRAMAS_AUX.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

OF T_PROGRAMAS,

<FS_PROGRAMAS_AUX> LIKE LINE

OF T_PROGRAMAS_AUX.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'.

LOOP AT T_PROGRAMAS

ASSIGNING <FS_PROGRAMAS>.

(107)

ASSIGNING <FS_PROGRAMAS_AUX>. MOVE <FS_PROGRAMAS>-ID_PROG TO <FS_PROGRAMAS_AUX>-ID_PROG. MOVE <FS_PROGRAMAS>-NOM_PROG TO <FS_PROGRAMAS_AUX>-NOM_PROG. ENDLOOP.

Creamos un tipo de tabla llamado TY_PROGRAMAS_AUX al cual le agregamos el campo ID, con lo cual hacemos que ambas tablas internas sean distintas, por lo cual no podemos seguir utilizando el []. En vez de eso, debemos hacer un

LOOP y asignar los valores de la tabla T_PROGRAMAS a

la tabla T_PROGRAMAS_AUX. Eso está bien para algunos campos, pero si tenemos por decir 20 campos...Entonces debemos utilizar una forma alternativa.

TYPES: BEGIN OF TY_PROGRAMAS,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

TYPES: BEGIN OF TY_PROGRAMAS_AUX, ID TYPE ZPROGRAMAS-ID,

(108)

OF TY_PROGRAMAS_AUX.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

OF T_PROGRAMAS,

<FS_PROGRAMAS_AUX> LIKE LINE

OF T_PROGRAMAS_AUX.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'.

LOOP AT T_PROGRAMAS

ASSIGNING <FS_PROGRAMAS>.

APPEND INITIAL LINE TO T_PROGRAMAS_AUX ASSIGNING <FS_PROGRAMAS_AUX>.

MOVE-CORRESPONDING <FS_PROGRAMAS> TO

<FS_PROGRAMAS_AUX>.

ENDLOOP.

Cuando utilizamos el MOVE-CORRESPONDING, lo que hacemos es que el ABAP se encargue de mover todos los campos de la tabla T_PROGRAMAS a la tabla

T_PROGRAMAS_AUX.

Ordenar tablas internas

Esto es bastante simple, ya se solamente tenemos una forma de hacerlo.

(109)

TYPES: BEGIN OF TY_PROGRAMAS,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG, END OF TY_PROGRAMAS.

DATA: T_PROGRAMAS TYPE STANDARD TABLE

OF TY_PROGRAMAS.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

OF T_PROGRAMAS.

APPEND INITIAL LINE TO

T_PROGRAMAS ASSIGNING <FS_PROGRAMAS>.

<FS_PROGRAMAS>-ID_PROG = '006'.

<FS_PROGRAMAS>-NOM_PROG = 'MP3 Player'. <FS_PROGRAMAS>-ID_PROG = '005'.

<FS_PROGRAMAS>-NOM_PROG = 'Web Browser'.

SORT T_PROGRAMAS BY ID_PROG ASCENDING.

SORT T_PROGRAMAS BY ID_PROG DESCENDING.

(110)

Estructuras de Control

Como vimos, podemos utilizar un LOOP para recorrer todos los registros de una tabla interna. ¿Pero que pasa si lo que necesitamos es recorrer los posibles valores de una variable?

Para estos casos contamos con WHILE-ENDWHILE.

DATA: VAR TYPE I.

WHILE VAR LT 10. WRITE:/ VAR. VAR = VAR + 1.

ENDWHILE.

Esto significa que mientras la variable VAR sea menor o igual a 10, imprimimos el valor. Aumentamos el valor de VAR de uno en uno, por cada vuelta del WHILE.

También tenemos presente el DO-ENDO.

DATA: VAR TYPE I.

DO. IF VAR LT 10. WRITE:/ VAR. VAR = VAR + 1. ELSE. EXIT. ENDIF. ENDDO.

(111)

El DO-ENDDO es un bucle repetitivo que avanza mientras no le digamos que tiene que salir. Utilizando un IF preguntamos si el valor de la variable es menor o igual a 10. En el caso afirmativo imprimimos y aumentamos en uno. Cuando VAR es mayor a 10, salimos del DO-ENDDO utilizando un EXIT.

Aunque, también podríamos haberlo escrito así:

DATA: VAR TYPE I.

DO 10 TIMES. WRITE:/ VAR. VAR = VAR + 1.

ENDDO.

En esta caso, le decimos al DO-ENDO que solo realice el bucle 10 veces. Imprimimos el valor de la variable VAR y la aumentamos en uno.

Adicionalmente tenemos los comandos CONTINUE y EXIT, que sirven para continuar en la siguiente iteración de la estructura de la estructura de control o para salir de la estructura de control completamente.

(112)

ejemplo PERL), de todos modos nos brinda alguna poderosas herramientas como estas:

• TRANSLATE

Convierte una cadena de texto a Mayúsculas o Minúsculas.

DATA: VAR TYPE STRING.

VAR = 'El Arte de Programar'.

TRANSLATE VAR TO UPPER CASE.

WRITE:/ VAR.

TRANSLATE VAR TO LOWER CASE.

WRITE:/ VAR.

Con TO UPPER CASE convertimos a Mayúsculas y con

TO LOWER CASE convertimos a Minúsculas.

• CONCATENATE

Concatena dos o más cadenas de texto. Es decir, une cadenas en una cadena más grande.

DATA: VAR TYPE STRING, VAR_AUX TYPE STRING, VAR_TEXT TYPE STRING.

(113)

VAR = 'El Arte de Programar'. VAR_AUX = 'SAP NETWEAVER'.

CONCATENATE VAR VAR_AUX

INTO VAR_TEXT.

WRITE:/ VAR_TEXT.

Con el CONCATENATE decimos que los valores de las variables VAR y VAR_AUX se guarden en la variable

VAR_TEXT.

Aunque claro, si ejecutamos el programa nos daremos cuenta de que no hay ningún espacio entre las dos palabras, esto lo arreglamos fácilmente.

DATA: VAR TYPE STRING, VAR_AUX TYPE STRING, VAR_TEXT TYPE STRING.

VAR = 'El Arte de Programar'. VAR_AUX = 'SAP NETWEAVER'.

CONCATENATE VAR VAR_AUX

(114)

estamos diciendo que separe el texto con un espacio en blanco.

• SPLIT

Divide una cadena en subcadenas, dependiendo de un carácter aguja.

DATA: VAR TYPE STRING, VAR_AUX TYPE STRING, VAR_TEXT TYPE STRING.

VAR_TEXT = 'SAP NETWEAVER'.

SPLIT VAR_TEXT AT SPACE

INTO VAR VAR_TEXT.

WRITE:/ VAR.

WRITE:/ VAR_TEXT.

Utilizamos el SPLIT para dividir la cadena utilizando como aguja un espacio y pasamos los valores a las variables VAR y

VAR_TEXT.

TYPES: BEGIN OF TY_CADENAS, VAR(30) TYPE C, END OF TY_CADENAS.

DATA: T_CADENAS TYPE STANDARD TABLE

(115)

DATA: VAR_TEXT TYPE STRING.

VAR_TEXT = 'SAP NETWEAVER'.

SPLIT VAR_TEXT AT SPACE

INTO TABLE T_CADENAS.

Creamos un tipo de tabla con un campo llamado VAR de tipo

C y longitud 30.

Creamos una tabla interna con referencia a nuestro tipo de tabla. Declaramos una variable de tipo STRING y utilizando el SPLIT mandamos las subcadenas a la tabla interna.

• SHIFT

Utilizado con la sentencia DELETING, permite eliminar los espacios o caracteres al inicio o al final de una cadena de texto.

DATA: VAR_TEXT TYPE STRING.

VAR_TEXT = ' SAP NETWEAVER '.

References

Related documents

• Data reconciliation was a manual process, making it very difficult to link the various documents (PO changes, acknowledgements, ship notices, invoices, etc.) related to each

La máquina indicará que está lista para la descalcificación cuando el botón POWER (Encendido), el botón de 1 taza, el indicador CLEAN/DESCALE (Limpiar/Descalcificar) y el indicador

Moreover, as the federal government did prior to and during the 2007 Rio Pan American Games, it will again deploy massive forces during the 2016 Games –

Strengths were noted in the areas of staff management, student administration, quality assurance, academic management, course design and care of students.. The inspection report

The aim of this project is to determine the prevalence of the R563Q mutation of the -subunit of the epithelial sodium channel ( -ENaC) gene in a cohort of primigravid women with

Pulse de nuevo el botón de encendido/apagado para apagar el aparato y cierre la tapa del depósito de agua.. Seque el aparato con un

The Network Address Translation 46 (NAT 46) feature solves IPv4 to IPv6 connectivity by providing a mechanism for connectivity of IPv4 hosts to IPv6 internet when dual stack and

The Iowa State University Digital Repository provides access to Integrated Crop The Iowa State University Digital Repository provides access to Integrated Crop Management News