TIPOS DE DATOS Y OTRAS SENTENCIAS
3.1. TIPOS Y OBJETOS DE datos:
Pueden declararse tipos de datos (son descripciones que definen los objetos de datos que se declaren luego, y no ocupan memoria) y objetos de datos (entidades físicas que sí ocupan memoria: variables. Tienen un tipo asociado, y se procesan según el tipo que sea).
- Tipos de datos:Por su estructura se clasifican en elementales(predefinidos: C, D, F, I, N, P, T, X. Estos nombres son fijos; y definidos por el usuario: a partir de los anteriores. Su nombre es libre) y estructurados(predefinidos: tablas del Diccionario de Datos (se declaran con TABLES); y definidos por el usuario: field-strings y tablas internas (ambos se declaran con DATA)).
TIPOS ELEMENTALES: Tipo Long. defectoLong. Máx. (nº char) Valor inicial Alfanumérico (Char, string) C 1 de 1 a 65535 SPACEFecha(Date) D 8 8 '00000000'Coma flotante (Float) F 8 8 0.0Entero (Integer) I 4 4 0Numéricos (Natural) N 1 de 1 a 65535 '0...0'Empaquetados (Packed) P 8 de 1 a 16 0Hora (Time) T 6 6 '000000'Hexadecimales (Hex) X 1 de 1 a 65535 X'00'
La longitud se mide en caracteres, NO en bytes. Variables que no sean del mismo tipo exactamente pueden no ser totalmente compatibles, lo que puede provocar errores de conversiones numéricas. Por ej., para operaciones de división usar el tipo P (packed), al menos para el recoger el resultado.
- Objetos de datos: Se clasifican en los siguientes grupos:
- Internos:Literales (‘hardcodes’ de texto y números. No se declaran), variables (se declaran con DATA) y constantes (se declaran con CONSTANTS).
- Externos: objetos del Diccionario Datos: tablas (se declaran con TABLES), obj. matchcode.
- Del Sistema: No se declaran, como SPACE, que es un espacio o una cadena en blanco, y campos y variables del sistema (Ej,: SY-SUBRC: código de retorno de una operación; SY-UNAME: nombre de usuario; SY-REPID: código de report).
- Especiales:parámetros (variables que toman su valor en la pantalla de selección. Se declaran con PARAMETERS), y criterios de selección (Se declaran con SELECT-OPTIONS).
Las tablas internas son las creadas como locales en un programa; no pertenecen al Diccionario de Datos. Sólo son visibles localmente en el programa en el que se declaran. Se declaran con:
DATA: BEGIN OF nombre_tabla OCCURS núm_entradas, ... END OFnombre_tabla.
- Con OCCURS se especifica el número de líneas, registros o entradas máximo de la tabla. Sin este parámetro se declaran estructuras, que son cabeceras de tablas, es decir, no tienen entradas.
- Las tablas internas tienen un registro de cabecera, del mismo formato que cada entrada de la tabla, que es como un buffer que sirve para insertar o extraer entradas de ellas.
- Para insertar datos, se usa un MOVE normal para cada campo, con lo que se rellena la cabecera con los valores adecuados, y luego un APPEND nombretabla. Así se inserta dicha cabecera como una nueva entrada en la tabla). También se puede usar la sentencia COLLECT, que es similar a APPEND, salvo que si se inserta una entrada cuya clave ya existe, en lugar de crear una nueva, se suman los contenidos de los campos numéricos no clave (si no hay, es como APPEND).
- Para extraer datos, se debe recorrer la tabla (con un bucle LOOP AT nombre_tabla, por ejemplo) hasta llegar a la entrada buscada. Entonces, automáticamente ya se tendrá en el registro cabecera de la tabla dicha entrada, accesible directamente.
- Con la sentencia CLEAR se limpia o borra el registro de cabecera (pone todos los campos a su valor inicial), pero no borra ninguna entrada de la tabla. En cambio con REFRESH se borran todas las entradas de la tabla, salvo la cabecera. Con FREE se eliminan la tabla y su cabecera.
- Conviene controlar con un IF o un CHECK si la tabla está vacía o no antes de intentar imprimirla. Se puede usar la sentencia DESCRIBE TABLE tabla LINES nr_líneas. para guardar en la variable nr_líneas el número de líneas de la tabla, y así ver si es cero o no.
- Para ordenar la tabla, usar la sentencia SORT nombre_tabla BY campo [ opciones].
- Ej.:
TABLES kna1. "tabla de los datos maestros de los clientes. DATA: BEGIN OF ztabla OCCURS 100, "declara una tabla con 2 campos y 100 entradas nombre LIKE kna1-name1, cliente LIKE kna1-kunnr. DATA: END OF ztabla. REFRESH ztabla. " borra todas las entradas de la tabla, para asegurar que está vacía CLEAR ztabla. " borra el registro de cabecera de la tabla, por si era un valor basura SELECT * FROM kna1. MOVE kna1-kunnr TO ztabla-cliente. MOVE kna1-name1 TO ztabla-nombre. APPEND ztabla. " para insertar efectivamente en la tabla END-SELECT. IF sy-subrc <> 0. WRITE ‘No se ha encontrado ningún dato’. ELSE. LOOP AT ztabla. " bucle que recorre la tabla, para imprimirla entera WRITE: ztabla-nombre, ztabla-cliente. END-LOOP. ENDIF.
3.3. Sentencias para abandonar bloques de proceso:
Dichas sentencias son: STOP, EXIT, CHECK y REJECT. Son todas incondicionales salvo CHECK. La sentencia CONTINUE vale para pasar a la siguiente vuelta de un bucle.
- STOP.
Incondicional. Se debe usar sólo en el evento START-OF-SELECTION. Su efecto es cancelar todas las selecciones de las tablas de la base de datos, abandonando el evento, y activar el END-OF-SELECTION (siempre lo activa. Si no se desea esto, debe usarse EXIT en lugar de STOP).
- EXIT.
Incondicional. Abandona totalmente el bloque actual o evento (excepto eventos AT...) si no está dentro de ningún bloque, y activa la pantalla de salida. Puede usarse fuera de bucles (acaba subrutinas, acaba eventos, ...) o dentro de ellos, para finalizar estos.
- CHECK { condición | tabla_selección | SELECT-OPTIONS }.
Condicional. Si la condición es falsa, acaba el bloque de proceso o evento (si no está dentro de ningún bloque) actual; si es cierta, sigue (como si no hubiera ningún CHECK). Es decir, que si no se “pasa” el chequeo, se salta a la siguiente vuelta del bucle (funciona como un CONTINUE condicional), o abandona la subrutina, ... (funciona como un EXIT condicional). La opción SELECT-OPTIONS sólo puede usarse para CHECKs que vayan tras eventos GET. Su efecto es comprobar que la entrada leída de la tabla cumpla todos los criterios de selección asociados.
- REJECT [ tabla_bd ].
Incondicional. Tras REJECT, se procesa el siguiente evento GET para la misma tabla, abandonando la selección actual. Opcionalmente se puede indicar una tabla de la base de datos jerárquicamente superior, con lo cual, tras ejecutar REJECT se procesa el siguiente GET de la tabla especificada (la siguiente “vuelta” del GET; la “vuelta” actual se abandona).- CONTINUE.
Incondicional. Termina la vuelta de un bucle (DO, WHILE), de forma incondicional, pasando a la siguiente vuelta. Normalmente sólo se puede usar dentro de un bucle de ese tipo.
- TABLES tabla.
Así se declara el área de trabajo de la tabla del D.D. especificada, para poder usarla.
- DATA variable [ (long) ] [ TYPE tipo | LIKE campo ] [ DECIMALS núm ] [ VALUE valor ].
Versión de DATA para declarar variables. El tipo por defecto es C (alfanumérico) y la longitud por defecto es la definida así para cada tipo (para los tipo C, longitud 1: un carácter). Otros tipos de datos simples son: I (integer), P (numérico empaquetado), N (numérico no empaquetado), D (date), ... Con LIKE, se toma como tipo el mismo que tenga el campo especificado. Con VALUE se inicializa a la vez que se declara. Ejemplo de sentencias DATA encadenadas:
DATA: texto1 TYPE C VALUE 'X', texto2(4) TYPE C VALUE 'HOLA'.
DATA: BEGIN OF nombre, ... END OF nombre.
Versión de DATA para field-strings: Los campos que se declaren en el field-string (es como un registro de cadenas) van separados por comas, y en cada uno se indica su tipo. Para acceder a ellos se escribe: nombre_registro – nombre_campo, de forma análoga a las tablas. DATA: BEGIN OF nombre_tabla OCCURS núm_entradas, ... END OFnombre_tabla.
Versión de DATA para tablas internas (son las creadas como locales en un programa; no pertenecen al Diccionario de Datos. Sólo son visibles en dicho programa. Con OCCURS se indica el número máximo de entradas. Si se pone 0, el tamaño de la tabla no tiene límite sintácticamente) o estructuras (no llevan OCCURS. Son como cabeceras de tablas, es decir, “tablas” sin entradas). DATA: BEGIN OF COMMON PART nombre, ... END OF COMMON PART.
DATA para bloques de memoria comunes. Esto define una zona común de memoria que puede ser compartida por varios programas, si se declara en todos ellos (con el mismo nombre). Dentro de la "common part" se declaran las variables, tablas internas, ... que deban ser compartidas.
TYPES tipo [ longitud ] [ TYPE tipo | LIKE campo ] [ DECIMALS número ].
Para definir tipos de datos internos al programa. Para tipos estructurados (como registros o tablas. A los campos de ambos se accede con nombre–campo) puede usarse TYPES de forma encadenada: TYPES: BEGIN OF nombre, ... END OF nombre. También vale para tipos específicos de usuario. Ejemplo: TYPE cadena(30) TYPE C. Declara un string de 30 caracteres.
CONSTANTS cons [ long ] [ TYPE tipo ] VALUE valor | IS INITIAL [ DECIMALS núm ].
Sintaxis similar a la de DATA, pero para constantes simples. El parámetro VALUE es obligatorio. Con IS INITIAL, las constantes alfabéticas se inicializan a blanco, y las numéricas a cero.
CONSTANTS: BEGIN OF nombre, ... END OF nombre.
Versión de CONSTANTS para registros constantes (como tablas constantes). Se accede a las componentes de un registro constante como si fuera una tabla interna.
FIELD-GROUPS nombre.
Un field-group es una agrupación de campos (es un registro interno de strings). Con esta sentencia se declara el nombre del grupo (conjunto) de campos. Se crea un field-group, aún sin campos. Después, con la sentencia INSERT se declaran los campos de que constará el conjunto (que deben existir previamente), y con la sentencia EXTRACT se dan valores a esos campos. No se reserva espacio de memoria para dichos campos, pues sólo serán punteros a las variables correspondientes. No confundir esta sentencia con FIELD-SYMBOLS.
INCLUDEnombre.
Inserta el código fuente especificado (debe ser un programa tipo I de Include, no puede ser un programa on-line) en el lugar del programa principal donde esté esta sentencia INCLUDE. Normalmente habrá uno para las declaraciones globales (llamado include ‘TOP’) que usen varios programas, otro(s) para los procesos PBO (Process Before Output: se ejecutan antes de mostrar la pantalla de selección), otro(s) para los procesos PAI (Process After Input: se ejecutan después de que el usuario haya hecho las selecciones de dicha pantalla, y haya lanzado el programa), como en un module pool típico. Para usar en el programa estructuras ya definidas antes, se usa INCLUDE STRUCTURE para definir así tablas internas.
Ejemplo:
* Equivale a DATA tabla LIKE namestruct OCCURS n. DATA: BEGIN OF tabla OCCURS n. INCLUDE STRUCTURE namestruct. DATA: END OF tabla.
LOCAL variable.
Se usa para declarar variables locales dentro de subrutinas (FORM ... ENDFORM). Si existe una variable global de mismo nombre, se salva su valor al entrar en la subrutina, y se restaura al salir, es decir, que la variable local deja de existir fuera de la subrutina.
STATICS var [ long ] [ TYPEtipo ] [ VALUE valor | IS INITIAL ][ DECIMALS num ].
También para variables locales. Se usa sólo dentro de FORMs (subrutinas). Funciona como LOCAL, pero con la diferencia de que conserva a la salida de la subrutina el valor que se le dé dentro de ésta, en lugar de restaurar el valor previo: pero la variable sólo será visible en los procesos en los que esté definida.
STATICS: BEGIN OF nombre, ..., END OF nombre.
Se usa para declarar un field string dentro de una subrutina o módulo de función. Es similar a un DATA, pero es local al subprograma en el que se defina, y en sucesivas llamadas al mismo conserva su valor (no es destruido como ocurre con las variables locales; es estático).
RANGES tabla_selección FOR campo.
Define una tabla interna con igual estructura que la de un select-options. Permite usar IN (puede recoger un intervalo de valores). La diferencia es que en la pantalla de selección no aparece esta tabla de selección, cosa que ocurriría con un SELECT-OPTIONS (así puede dársele valor por programa, en lugar de que lo haga el usuario). Formato de esta tabla:
DATA: BEGIN OF tabla OCCURS 0, SIGN(1) TYPE C, OPTION(2) TYPE C, LOW LIKE campo, HIGH LIKE campo. DATA: END OF tabla.
TYPE-POOL nombre_tipo.
Para declarar grupos de tipos. Se acceden con la transacción SE11 (Diccionario de Datos, que es donde se guarda la estructura del TYPE-POOL). En ellos sólo pueden definirse constantes y tipos (con TYPE), y deben nombrarse empezando con el nombre del grupo de tipos seguido de ‘_’. Al ser objetos del D.D. podrán ser visibles en todos los programas SAP. Para llamarlos o acceder a ellos desde un programa se usa la sentencia (distinta) TYPE-POOLS.
Ejemplo de declaración:
* Se define el 'TIPO1' como agrupación de un P y de un I. TYPE-POOL tipo1. TYPES: tipo1_packed TYPE P, tipo1_entero TYPE I.
TYPE-POOLS nombre_tipo.
Sentencia que sirve para acceder o llamar a un TYPE-POOL almacenado ya en el D.D.
Ejemplo:
* Con esto ya es visible en el programa el 'TIPO1' antes creado. TYPE-POOLS tipo1. * Se usa 'TIPO1' como cualquier otro predefinido DATA: campo TYPE tipo1_entero. DESCRIBE FIELD var [ LENGTH long ] [ TYPE tipo ] [ COMPONENTS comps ] [ OUTPUT-LENGTH long ] [ DECIMALS decimales ] [ EDIT MASK mascara ].
Sirve para determinar los atributos del objeto dado. Si al intentar acceder a él, éste existe, SY-SUBRC valdrá cero; en otro caso, distinto de cero. No confundir esta sentencia con DESCRIBE TABLE, que es análoga pero para tablas internas en lugar de variables simples.
CREATE OBJECT objeto clase [ LANGUAGE lenguaje ].
Crea un objeto de la clase especificada. Se usa para declarar objetos OLE (por ejemplo, para asociar un fichero EXCEL a un report Abap/4).
FIELD-SYMBOLS<nombre_símbolo> [ STRUCTURE estructura DEFAULT valor ] [ TYPE [ LINE OF ] tipo ] [ LIKE [ LINE OF ] tipo ].
Con esta sentencia se pueden declarar campos simbólicos. En ejecución, con la sentencia ASSIGN, pueden asignárseles campos concretos, de forma dinámica, en lugar de los campos simbólicos. Sintaxis: ASSIGN campo1 TO<nombre_símbolo>. (los < >son obligatorios). “campo1” puede ser de cualquier tipo. Más tarde en el programa puede haber otra sentencia como: ASSIGN campo2 TO<nombre_símbolo>., con “campo2” de cualquier otro tipo (hay un polimorfismo de datos en ejecuc.). Con la opción STRUCTURE se asignarán estructuras al field-symbol. Sus campos se accederán con <fs>_campo. Con LINE OF se puede dat una tabla interna. No confundir esta sentencia con FIELD-GROUPS.
Ejemplo:
* Con esto ya está declarado el campo simbólico FIELD_SYMBOLS < mi_símbolo >. DATA: campo1(2) TYPE C VALUE 'AA', campo2(2) TYPE P VALUE 34. …… ASSIGN campo1 TO < mi_símbolo >. "Aquí mi_símbolo es de tipo C y vale 'AA' …… ASSIGN campo2 TO < mi_símbolo >. "Ahora mi_símbolo es de tipo P y vale 34 (polimorfismo) SELECTION-SCREEN, PARAMETERS, y SELECT-OPTIONS
Son sentencias declarativas de la pantalla de selección.
DESCRIBE TABLE, WRITE … TO … INDEX, CLEAR y FREE
Son sentencias Native SQL.3.5.1. Sentencias de asignación y conversión de variables:
- MOVE campo1[offset1] TO campo2[offset2] [ PERCENTAGE nr ].
- MOVEcopia el contenido del campo1 en campo2. Los offset permiten especificar sólo una parte del campo origen y/o destino, y se escriben así: +número, todo pegado al nombre del campo. En PERCENTAGE puede especificarse un %, es decir, 0 < nr < 100 (si se usa esta opción, ‘campo1’ y ‘campo2’ deben ser tipo C. El resultado es que el nr % de ‘campo1’ se mueve a ‘campo2’ justificado a la izquierda.MOVE hace conversiones de formato, si origen y destino no tienen igual tipo, lo que puede dar lugar a resultados erróneos.
- MOVE–CORRESPONDING tabla1 TO tabla2.
- Sentencia similar a MOVE, pero de un registro o cabecera de una tabla a otra igual (o no) en estructura. Si origen y destino no coinciden en todos los campos (en la estructura) sólo se mueven aquellos campos que coincidan (por nombre, no por posición. Por tanto, para evitar errores de conversión, ambos campos de mismo nombre también deberían tener el mismo tipo y tamaño).
- WRITE campo1[offset1] TO campo2[offset2].
- Similar a MOVE, salvo que el “campo2” (destino) siempre debe ser de tipo texto. Por tanto, si el origen no es de texto, será convertido. Pueden especificarse offsets a la hora de hacer estas conversiones. Con WRITE (campo1) TO … no se mueve campo1 (va entre paréntesis), sino su contenido (es una indirección).
- PACK campo TO campo.
- Convierte ese campo a su forma empaquetada, por ejemplo, números sin ceros a la izquierda. Puede escribirse el resultado sobre la misma variable, o en otra distinta.
- UNPACK campo TO campo.
- La operación inversa a PACK (es decir, convierte el campo a su forma desempaquetada). Ejemplo, rellenar con ceros a la izquierda un número, hasta completar la longitud del campo.
- CONVERT DATE e INVERT DATE
- Sentencias de conversión de fechas a formato interno de SAP (poco útil).
- CONVERT TEXT campo1 INTO SORTABLE CODE campo2.
Sentencia que transforma un campo de texto simple a un campo tal que es más rápidamente ordenable, insertando índices, claves, …
- ADD campo2 TO campo1.
Hace la operación: campo1 := campo1 + campo2. Las demás sentencias de cálculo son similares: en “campo1” se almacenará el resultado de la operación.- ADD n1 THEN n2 UNTIL ni GIVING | TO m.
Hace la operación: m := m + n1 + n2 + … + ni. Se incluye ‘m’ como sumando o no dependiendo de si se usa GIVING o TO.- ADD-CORRESPONDING tabla2 TO tabla1.
Suma los campos que se correspondan (por su nombre) de 2 registros o tablas, y deja los nuevos valores en el segundo de ellos (“tabla1”).- SUBSTRACT campo2 FROM campo1.
- SUBSTRACT-CORRESPONDING tabla2 FROM campo1.
- MULTIPLY campo1 BYcampo2.
- MULTIPLY-CORRESPONDING tabla1 BY tabla2.
- DIVIDE campo1 BY campo2.
- DIVIDE-CORRESPONDING tabla1 BY tabla2.
- COMPUTEn = expresión.
Permite realizar cualquiera de las operaciones aritméticas permitidas:
- Operaciones básicas: +, -, *, /, MOD, ** (exponenciación). Cubren las sentencias anteriores.
- Para todo dato numérico: ABS, CEIL (función techo), FLOOR (función suelo), SIGN (devuelve el “valor” del signo: -1, 0, 1), TRUNC (devuelve la parte entera), FRAC (devuelve la parte fraccionaria).
- Para coma flotante: COS, SEN, TAN, ACOS, ASEN, ATAN, COSH, SENH, TANH, EXP (en base e), LOG (en base e), LOG10 (en base 10), SQRT.
3.5.3. Sentencias de manejo de strings:
- CONCATENATE c1 … cn [ SEPARATED BY separador ] INTO campo.
Concatena los strings c1 … cn (deben ser todos de tipo C), sin conversión de tipos. Devuelve SY-SUBRC 0 si la operación se ha completado correctamente, y 4 si el campo destino es demasiado pequeño para guardar la concatenación.
- SET LOCALE LANGUAGE lenguaje [ COUNTRY país ][ MODIFIER modificador].
- CONDENSE campo [ NO-GAPS].
El “campo” debe ser tipo C (una cadena), o bien lo trata como si lo fuera (por ejemplo, no incluye en los números el carácter blanco inicial). Junta las palabras de campo dejando entre ellas sólo un blanco. Con NO-GAPS se eliminan todos los blancos.
- REPLACE string1 WITH string2 INTO campo [ LENGTH long ].
Reemplaza (sólo la primera ocurrencia) de “string1” por “string2” en el valor de “campo”.
Ejemplo:
REPLACE 'B' WITH 'hola' INTO campo.
Si "campo" era 'ABCB', el resultado será 'AholaCB' (reemplaza sólo la primera ocurrencia). Devuelve código de retorno 0 si la operación fue correcta, y 4 si hubo algún error.
- SPLIT campo AT separador INTO c1 … cn | INTO TABLE tabla.
Parte “campo” en n partes, delimitadas por el separador dado, como ‘/’ por ejemplo. Devuelve SY-SUBRC 0 si los campos c1 … cn tienen espacio suficiente, y 4 en caso contrario (los trunca).
- SHIFT campo [ BY n PLACES ] [ UP TO campo1 ] [ LEFT | RIGHT ] [ CIRCULAR ][ LEFT DELETING LEADING campo1 ] [ RIGHT DELETING TRAILING campo1 ].
Desplaza “campo” n posiciones (1 por defecto) a la izquierda o derecha, de forma circular o no (según se especifique) Rellena con blancos al desplazar.
- TRANSLATE campo [TO UPPER CASE | TO LOWER CASE ] [ USING campo1 ][FROM CODE PAGE g1 TO CODE PAGE g2 ] [ FROM NUMBER FORMAT n1TONUMBER FORMAT n2 ].
Según se especifique, pasa el campo dado a mayúsculas o a minúsculas.
- OVERLAY campo1 WITH campo2 [ ONLY campo3 ].
El contenido de ‘campo2’ sobreescribe a ‘campo1’ en todas las posiciones donde ‘campo1’ tenga blancos, reemplazándolos por los caracteres de ‘campo2’ de las posiciones respectivas (por defecto se reemplazan blancos. Se puede especificar el carácter o caracteres a reemplazar en ‘campo3’. Se sustituyen todos los caracteres que se especifiquen en este campo, y se encuentren en ‘campo1’, pero sueltos, no formando un string). Devuelve 0 si al menos un carácter ha sido sobrescrito, y 4 en otro caso.
Ejemplo:
OVERLAY 'AAAMMBBCCA' WITH 'ZXCVBNMASS' ONLY 'AB'. *Resultado --> 'ZXCMMNMCCS'
- SEARCH { campo | tabla } FOR criterio [ ABBREVIATED ][ STARTING AT inicio ][ ENDING AT final ] [ AND MARK ].
Busca en el 'campo' dado el string 'criterio'. Con ABBREVIATED se busca algo que empiece por las mismas letras que 'criterio'. Se puede delimitar la búsqueda especificando las posiciones de inicio y fin con STARTING AT y ENDING AT. Con AND MARK se señala en mayúsculas la palabra en la que se encontró el string. Devuelve 0 si encontrado (estará en la posición SY-FDPOS), y 4 en otro caso.