El Arte de Programar - SAP Netweaverv1_JC

548 

Loading.... (view fulltext now)

Loading....

Loading....

Loading....

Loading....

Texto completo

(1)

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

(2)

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

Introducción BAPIS 290

ALV (ABAP List Viewer) 292

Introducción 292

Creando un ALV 292

Agregando una cabecera al reporte 301

Eventos ALV 308

Pintemos con colores 313

(3)

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

(4)

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 sencillas y las mismas serán utilizadas para todos los ejemplos.

(5)

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.

(6)
(7)

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.

(8)
(9)

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).

(10)

2.- SE11 (Diccionario ABAP)

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

(11)

3.- SE16 (Browser de Datos)

(12)

4.- SE71 (Form Painter)

(13)

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.

(14)

6.- SE51 (Screen Painter)

(15)
(16)

8.- SE37 (Function Builder)

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

(17)
(18)

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. Imprimir.

Buscar. Buscar más.

(19)

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.

(20)

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:

Tablas Transparentes (Transparent Tables):

Posee una relación de uno a uno con una tabla de la Base de Datos. Es decir, cada tabla transparente definida en el Diccionario de Datos, existe físicamente en la base de datos. Es el tipo más común de tabla y es el más utilizado por los

(21)

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.

(22)

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.

Creación de Objetos del Diccionario

Para acceder al Diccionario de Datos, deberemos ingresar a la transacción SE11.

(23)

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

(24)

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.

Presionamos el botón Create.

En este momento, se nos presenta una ventana, en la cual, deberemos ingresar una descripción para la tabla, además de una clase de entrega y definir si la tabla puede ser mantenida desde la transacción SE16 o por algún programa externo.

(25)

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

(26)

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.

(27)

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.

(28)

Ingresamos una descripción y grabamos.

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

(29)

Atributos del Package ZARTE_PROGRAMAR

Regresamos a la sesión donde teníamos la tabla y hacemos un clic en el botón del parámetro Package.

(30)

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).

Escogemos nuestro Package con un doble clic para que quede asignado a nuestra tabla.

(31)

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.

(32)

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

porque vamos a utilizar un Predefined Type (Tipo Predefinido).

Hacemos clic en el botón Predefined Type. Y como podemos ver, la interfaz de la pantalla cambia un poco.

(33)

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.

(34)

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.

(35)

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.

(36)

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.

Grabamos y ahora debemos llenar los datos de Technical

Settings (Caraterísticas Técnicas) Goto Technical Settings o presionar Crtl + Shift + F9. Y luego debemos

(37)

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.

(38)

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.

(39)

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.

(40)

Recibimos este mensaje, porque la llave completa de la tabla

ZENTORNOS_PROG no existe en la tabla ZLENGUAJES_PROG.

Dejamos la ventana, como se muestra en la figura.

El ultimo campo, se llama CONEX_SAP y determina si el lenguaje posee algún tipo de conexión con SAP. Para esto,

(41)

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.

(42)

Grabamos, activamos y creamos nuestro Elemento de Datos.

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

De vuelta en la tabla ZLENGUAJES_PROG, agregamos el campo CONEX_SAP con su respectivo elemento de datos.

(43)

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.

(44)

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 (Ejecutar) o presionamos F8.

(45)

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.

(46)

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.

Cabe destacar que los valores que están en la tabla

ZENTORNOS_PROG, son los únicos valores válidos, es decir, si

ingresamos cualquier otro valor, el sistema nos mostrará un mensaje de error.

(47)

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).

(48)

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

(49)

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

(50)

“+”. 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).

(51)

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 “+”.

(52)

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.

(53)

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.

(54)

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.

(55)

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 ZLENGUAJES_PROG, debemos modificar la tabla

(56)

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

(57)

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).

(58)

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.

(59)

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

(60)

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).

Nos posicionamos en el campo Id, y presionamos el botón Search

(61)

Asignamos la ayuda de búsqueda que creamos.

Grabamos y activamos.

(62)

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.

(63)

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

(64)

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,

(65)

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.

(66)

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

(67)

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.

(68)

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.

Cuando presionamos el botón Create (Crear), el sistema nos mostrará la siguiente ventana, en donde debemos escoger el Type (Tipo de programa) y el Status (Estado) asociado.

(69)

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.

(70)

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.

Para empezar, vamos a hacer un programa muy simple, que simplemente solicite al usuario un texto y lo imprima en pantalla, luego de esto, veremos la sintaxis de ABAP y podremos hacer programas más complejos.

(71)

*&---* *& 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

(72)

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 2 tipos de parámetros:

• PARAMETERS Son parámetros simples que aceptan solamente un valor.

(73)

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ú.

(74)

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

(75)

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.

(76)

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

XSTRING Byte Sequence Variable Empty X String

Adicionalmente, podemos utilizar campos de tablas para poder hacer la declaración de variables.

(77)

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.

(78)

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.

TYPES: BEGIN OF TY_SPFLI.

INCLUDE STRUCTURE SPFLI. TYPES: TEST TYPE STRING.

TYPES: END OF TY_SPFLI.

DATA: T_SPFLI TYPE STANDARD TABLE OF TY_SPFLI.

(79)

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

(80)

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:

DATA: NOMBRE TYPE ZPROGRAMAS-NOM_PROG.

SELECT SINGLE NOM_PROG

INTO NOMBRE

(81)

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,

(82)

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.

DATA: T_PROGRAMAS TYPE STANDARD TABLE OF TY_PROGRAMAS.

SELECT NOMBRE ENTORNO NOM_PROG

INTO CORRESPONDING FIELDS OF TABLE T_PROGRAMAS

(83)

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,

(84)

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 (Equivales a hacer un ENTER).

(85)

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

(86)

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. Que decir: IF NOMBRE == ‘PHP’.

(87)

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 * *=====================================================*

(88)

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).

LOOP AT T_PROGRAMAS

ASSIGNING <FS_PROGRAMAS>.

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

(89)

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.

(90)

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.

SELECT-OPTIONS:

S_ID FOR ZPROGRAMAS-ID.

SELECTION-SCREEN END OF BLOCK PRG.

SELECTION-SCREEN BEGIN OF BLOCK indica el inicio de

(91)

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

(92)

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).

WRITE indica que queremos escribir algo en la pantalla.

/ indica que luego de escribir en la pantalla queremos hacer un salto

de líneas.

1, 17 y 33, indican las posiciones X en las cuales queremos escribir. ‘Lenguaje’, ‘Entorno’ y ‘Programa’ son los texto que queremos

(93)

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.

(94)

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

FORMAT COLOR 5.

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

FORMAT COLOR OFF.

(95)

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

(96)

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>.

Luego, agregamos los valores a la tabla y al momento de leerla con el índice 1, podemos imprimir los nuevos valores.

(97)

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'.

(98)

<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

OF TY_PROGRAMAS.

FIELD-SYMBOLS: <FS_PROGRAMAS> LIKE LINE

OF T_PROGRAMAS.

(99)

<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

(100)

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 NOM_PROG. Entonces debemos hacer algo más.

TYPES: BEGIN OF TY_PROGRAMAS,

ID_PROG TYPE ZPROGRAMAS-ID_PROG, NOM_PROG TYPE ZPROGRAMAS-NOM_PROG,

(101)

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

(102)

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[].

En este caso, tenemos las dos tablas internas

T_PROGRAMAS y T_PROGRAMAS_AUX, ambas

haciendo referencia a TY_PROGRAMAS, por lo tanto, poseen exactamente la misma estructura. Por ello, podemos utilizar el [] para copiar los datos de una tabla a otra.

(103)

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

(104)

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,

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

DATA: T_PROGRAMAS TYPE STANDARD TABLE

(105)

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

Figure

Actualización...

Referencias

Actualización...

Related subjects :