Ir al contenido
Programación ABAP

Tipos de datos y sentencias

Tipos de datos, tablas internas y las sentencias de declaración, asignación, cálculo y manejo de textos.

Manual ABAP
3 de 14

Antes y ahora

Este capítulo se escribió para SAP R/3 y ABAP clásico. Aquí tienes qué ha cambiado; en cada apartado verás la comparación con código y, plegado, el texto original.

ConceptoEn el manualHoyEstado
Tablas internasOCCURS y WITH HEADER LINETYPE STANDARD | SORTED | HASHED TABLE OF, sin cabeceraSustituido
Referencia a un tipoLIKE campo_tablaTYPE con el elemento de datos o el campoSe escribe distinto
Declarar variablesTodas al principio, con su tipoTambién en el sitio donde se usan: DATA(lv_total) = …Se escribe distinto
AsignarMOVE a TO b, MOVE-CORRESPONDINGb = a, CORRESPONDING #( )Sustituido
CalcularCOMPUTE, ADD, MULTIPLY…Operadores: =, +=, *=…Sustituido
Unir textosCONCATENATE … SEPARATED BYPlantillas de texto |Pedido { lv_vbeln }| u operador &&Se escribe distinto
Buscar y convertir textosSEARCH, TRANSLATE … TO UPPER CASEfind( ), to_upper( ) y otras funciones de textoSustituido
Salir de un bloqueCHECK fuera de un bucle, STOPRETURN en métodosSe escribe distinto

Sigue igual: los tipos C, N, D, T, P e I, CONSTANTS y TYPES, SPLIT y CONDENSE, EXIT y CONTINUE dentro de bucles.

3.1. Tipos y objetos de datos

Se escribe distinto

Así se hace hoy

Los tipos elementales siguen siendo los mismos, y desde entonces se han añadido varios:

TipoPara quéDesde
string, xstringTexto y binario de longitud variable4.6
int8Enteros de 8 bytes7.50
decfloat16, decfloat34Decimales en coma flotante exactos7.02
utclongMarca de tiempo UTC con precisión de 100 ns7.54
abap_boolBooleano: abap_true o abap_falseTipo del grupo ABAP

Además de los tipos de la tabla existen STRING y XSTRING (longitud variable), DECFLOAT16 y DECFLOAT34, e INT8 desde la 7.50. En sistemas Unicode los campos C y N admiten hasta 262.143 caracteres.

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:TipoLong. defectoLong. Máx. (nº char)Valor inicial
    Alfanumérico (Char, string)C1de 1 a 65535SPACE
    Fecha(Date)D88'00000000'
    Coma flotante (Float)F880.0
    Entero (Integer)I440
    Numéricos (Natural)N1de 1 a 65535'0...0'
    Empaquetados (Packed)P8de 1 a 160
    Hora (Time)T66'000000'
    Hexadecimales (Hex)X1de 1 a 65535X'00'

La longitud se mide en caracteres, salvo en los tipos P y X, que se miden 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).

3.2. Tablas internas

Sustituido

Así se hace hoy

Las tablas con cabecera son obsoletas y no se admiten en clases ni en ABAP Cloud. Hoy se declara el tipo de tabla y se trabaja con un área de trabajo aparte. Elige el tipo según cómo vayas a leerla:

Antes
DATA: BEGIN OF it_pedidos OCCURS 0,
        vbeln LIKE vbak-vbeln,
        netwr LIKE vbak-netwr,
      END OF it_pedidos.

LOOP AT it_pedidos.
  WRITE it_pedidos-vbeln.
ENDLOOP.
Ahora
TYPES: BEGIN OF ty_pedido,
         vbeln TYPE vbak-vbeln,
         netwr TYPE vbak-netwr,
       END OF ty_pedido.
DATA lt_pedidos TYPE SORTED TABLE OF ty_pedido
                WITH UNIQUE KEY vbeln.

LOOP AT lt_pedidos INTO DATA(ls_pedido).
  cl_demo_output=>write( ls_pedido-vbeln ).
ENDLOOP.
Antes
READ TABLE lt_pedidos INTO ls_pedido
  WITH KEY vbeln = lv_vbeln BINARY SEARCH.
IF sy-subrc = 0.
  lv_importe = ls_pedido-netwr.
ENDIF.
Ahora
" En una tabla SORTED o HASHED la búsqueda ya es rápida
lv_importe = VALUE #( lt_pedidos[ vbeln = lv_vbeln ]-netwr
                      OPTIONAL ).
Texto original del manual: sintaxis clásica

Ejemplo moderno equivalente al de abajo: SELECT kunnr, name1 FROM kna1 INTO TABLE @DATA(lt_clientes).

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

  • Con OCCURS se indica cuántas líneas reservar en memoria al principio; no es un máximo, la tabla crece lo que haga falta. 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.:

    ABAP
    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.
      ENDLOOP.
    ENDIF.
STANDARD1clave 32clave 13clave 24clave 1Índice y claveLectura por clave:recorre la tabla (n)Pocos datos o accesopor posiciónSORTED1clave 12clave 13clave 24clave 3Índice y clave ordenadaLectura por clave:búsqueda binaria (log n)Rangos y lecturas porparte de la claveHASHED—clave K7—clave K2—clave K9—clave K4Solo clave únicaLectura por clave:tiempo constanteMuchos datos y lecturapor la clave completa
Elige el tipo de tabla según cómo vayas a leerla. Con muchas líneas y lecturas por clave, una tabla HASHED o SORTED es muchísimo más rápida que una STANDARD.

3.3. Sentencias para abandonar bloques de proceso

Se escribe distinto

Así se hace hoy

EXIT y CONTINUE siguen igual dentro de los bucles. Para salir de un método se usa RETURN; CHECK fuera de un bucle y STOP o REJECT (de los eventos y las bases de datos lógicas) quedan para el código antiguo.

Antes
FORM procesar USING pv_importe TYPE netwr.
  CHECK pv_importe > 0.
  " ...
ENDFORM.
Ahora
METHOD procesar.
  IF iv_importe <= 0.
    RETURN.
  ENDIF.
  " ...
ENDMETHOD.

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 CHECK s 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, LOOP), de forma incondicional, pasando a la siguiente vuelta. Normalmente sólo se puede usar dentro de un bucle de ese tipo.

3.4. Sentencias declarativas

Se escribe distinto

Así se hace hoy

DATA, TYPES y CONSTANTS siguen igual, pero se usa TYPE en lugar de LIKE, ya no hace falta TABLES para leer de la base de datos y las variables se pueden declarar donde se rellenan:

Antes
TABLES vbak.
DATA: lv_vbeln LIKE vbak-vbeln,
      lv_total TYPE p DECIMALS 2.

lv_vbeln = vbak-vbeln.
Ahora
DATA lv_total TYPE p LENGTH 15 DECIMALS 2.
CONSTANTS lc_iva TYPE p LENGTH 3 DECIMALS 2 VALUE '0.21'.

DATA(lv_vbeln) = ls_vbak-vbeln.   " el tipo sale de la derecha
Texto original del manual: sintaxis clásica
  • 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:

    ABAP
    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 OF nombre_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 la memoria inicial, no un máximo: la tabla siempre puede crecer. Lo habitual es poner 0 y dejar que el sistema decida) 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: TYPES 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.

  • INCLUDE nombre.
    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:

    ABAP
    * 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 ] [ TYPE tipo ] [ VALUE valor | IS INITIAL ][ DECIMALS num ].
    También para variables locales. Se usa sólo dentro de FORM s (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:

    ABAP
    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:

    ABAP
    * 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:

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

  • 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 acceden con <fs>-campo. Con LINE OF se puede dar una tabla interna. No confundir esta sentencia con FIELD-GROUPS.
    Ejemplo:

    ABAP
    * Con esto ya está declarado el campo simbólico
    FIELD-SYMBOLS <mi_simbolo>.
    
    DATA: campo1(2) TYPE C VALUE 'AA',
          campo2(2) TYPE P VALUE 34.
        ......
    ASSIGN campo1 TO <mi_simbolo>. "Aquí <mi_simbolo> es de tipo C y vale 'AA' 
        ...... 	
    ASSIGN campo2 TO <mi_simbolo>. "Ahora <mi_simbolo> 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, CLEAR, REFRESH y FREE sirven también para tablas internas (no son Native SQL, como decía la versión anterior de esta página).

  • 3.5. Sentencias de procesamiento de datos:

3.5.1. Sentencias de asignación y conversión de variables

Sustituido

Así se hace hoy

Antes
MOVE lv_a TO lv_b.
MOVE-CORRESPONDING ls_vbak TO ls_pedido.
lv_texto = lv_numero.
Ahora
lv_b = lv_a.
ls_pedido = CORRESPONDING #( ls_vbak ).
lv_texto = CONV string( lv_numero ).

CORRESPONDING también trabaja con tablas completas y permite renombrar campos con MAPPING.

Texto original del manual: sintaxis clásica
  • 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, …

3.5.2. Sentencias de cálculo

Sustituido

Así se hace hoy

Antes
COMPUTE lv_total = lv_precio * lv_cantidad.
ADD 1 TO lv_contador.
MULTIPLY lv_importe BY 2.
Ahora
lv_total = lv_precio * lv_cantidad.
lv_contador += 1.            " desde 7.54
lv_importe *= 2.

Funciones matemáticas como round( ), abs( ), ceil( ) o nmax( ) evitan llamar a módulos de función para cálculos sencillos.

Texto original del manual: sintaxis clásica
  • 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”).
  • SUBTRACT campo2 FROM campo1.
  • SUBTRACT-CORRESPONDING tabla2 FROM tabla1.
  • MULTIPLY campo1 BY campo2.
  • MULTIPLY-CORRESPONDING tabla1 BY tabla2.
  • DIVIDE campo1 BY campo2.
  • DIVIDE-CORRESPONDING tabla1 BY tabla2.
  • COMPUTE n = 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, SIN, TAN, ACOS, ASIN, ATAN, COSH, SINH, TANH, EXP (en base e), LOG (en base e), LOG10 (en base 10), SQRT.

3.5.3. Sentencias de manejo de strings

Se escribe distinto

Así se hace hoy

Las plantillas de texto y las funciones de texto sustituyen a la mayoría de estas sentencias, y además aplican formatos (fechas, ceros a la izquierda, decimales):

Antes
CONCATENATE 'Pedido' lv_vbeln 'de' lv_kunnr
  INTO lv_texto SEPARATED BY space.
TRANSLATE lv_texto TO UPPER CASE.
SEARCH lv_texto FOR 'URGENTE'.
IF sy-subrc = 0.
  ...
ENDIF.
Ahora
lv_texto = |Pedido { lv_vbeln ALPHA = OUT } de { lv_kunnr ALPHA = OUT }|.
lv_texto = to_upper( lv_texto ).
IF find( val = lv_texto sub = 'URGENTE' ) >= 0.
  ...
ENDIF.

SPLIT, CONDENSE y REPLACE siguen siendo válidos; también existen como funciones (condense( ), replace( ), segment( )).

Texto original del manual: sintaxis clásica
  • 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:

    ABAP
    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 n1 TO NUMBER 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:

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

Para seguir

  • Plantillas de texto, expresiones de tabla y constructores VALUE y CORRESPONDING: New ABAP 7.5.
  • Elegir el tipo de tabla interna adecuado: la infografía del apartado 3.2.