jueves, 24 de julio de 2008

selection screen,(primer intento)

Esta parte de ABAP, trata de los eventos generados por el usuario.

Programando Event-Driven.
En ABAP ya vimos que los eventos se definen por bloques en el programa comenzando por determinadas palabras claves de eventis, estos bloques son ejecutados al invocar ciertos eventos.

Como ya vimos, si un bloque de programa no está asignado a ningúna clave de evento, se le asigna por defecto al evento de clave: start-of-selection.

Es buena practica escribir los bloques en el orden lógico secuencial en que se producen, y también usar los eventos mas importantes de selection-screen.

  • El evento initialization
  • El evento at selection-screen
  • El evento at user-command
El Evento initialization

Este evento se lanza antes de la pantalla de usuario, por lo que es especialmente valido para inicializar variables....

El evento at selection-screen

El evento at selection-screen se procesa despues de que el usuario haga input en la pantalla de seleción activa. Por ejemplo pulsando un botón, u otras entradas de la pantalla de selección.
Puede ser usado para validar las entradas o tambien para modificar la propia pantalla de seleccion.

ABAP. Tablas internas.

TABLAS INTERNAS.
Una tabla interna es una tabla temporal en la memoria del servidor de aplicaciones. Es creada y mantenida por un programa durante la ejecución, y es descartada cuando el programa termina. Como una tabla de bases de datos, una tabla interna consiste de varios registros con la misma estructura, poro sus datos desaparecen cuando el programa termina. Se usa como almacen temporal para manipular datos, o como un buffer temporal privado.

Una tabla interna se compone de un cuerpo y una cabecera opcional..
El cuerpo es el que almacena los registros de la tabla interna. Normalmente cuando se habla de tabla interna, se refiere al cuerpo de la tabla interna.
La cabecera de la tabla interna es un unico registro que se utiliza para añadir y recoger datos del cuerpo de la tabla interna.

Como crear una basica tabla interna:
Creando con data un field string, podemos crear una tabla interna con la sintaxis:
con header:
begin of it1 occurs n.
data it1 like fs1 occurs n with header line. 

sin header:
data it1 like fs1 occurs n.

Pienso que no necesita explicación.
El numero de registros simplemente es orientativo, pese a que es posible que haya algún problema cuando nos pasamos este número, por ejemplo que no haga el rolling completo. (consultar versiones)
Es importante el número de registros (puede ser incluso cero) para la 'perfomance'.

La mayor confusión con respecto a las tablas internas está en que el cuerpo y la cabecera se llaman igual, pero esto no es problema porque la propia codificación nos dice si estamos usando el cuerpo o la cabecera, por ejemplo los asignamientos de campos de las tablas internas siempre se refieren al header.

Añadir datos a una tabla interna con la sentencia append.

append it.
Añade los datos introducidos en la cabecera it (usar it como si fuera un field string) al final de la tabla it.

append wa to it
Añade los datos de wa (un field string conla misma estructura que it).

append initial line to it
Añade un registro en 'blanco' a la tabla interna.


sy-tabix es una variable del sistema que nos dice que numero de registro es el que acabamos de añadir.

Leyendo datos de una tabla interna

Sentencia loop at

loop at it [into wa] [from m] [to n] [where exp].
---
endloop.
donde:
  • it es una tabla interna
  • wa es el nombre del work area (si se omite, por defecto es el header).
  • m y n son enteros literales,constantes o variables representando numeros de registros.
  • exp es una expresión lógica restrigiendo el numero de registros.
  • --- Son lineas de codigo que se ejecutan una vez por registro de la tabla interna.
Mas explicaciones:
  • wa tiene que tener la misma estructura que la tabla interna.
  • wa puede ser la cabecera de la tabla interna.
  • Si no se expecifica work area se usa por defecto la cabecera..
  • Si from no se especifica es el primer registro
  • Si to no se especifica es el ultimo registro.
  • En la expresion logica, los componentes os subcampos de la it no tienen que escribirse it-componente, sino componente. Incluso da error si se hace asi.
  • En exp, cualquie uso de los componentes de la tabla tiene que estar a la izquierda del operador relación.
sy-tabix nos muestra en cualquier momento el numero de registro por el que vamos.
Si hay bucles anidados, nos da el del bucle en el que estamos.
Despues del bucle, es cero si se han leido registro y no-cero si no se ha leido ninguno (comprobar).

En la condición, hay que intentar que no se hagan transformaciones que no llegen a hacer el program amuy pesado.


Sentencias del control de bucle.
Sentencias que alteran el bucle de proceso de tablas internas
Statement
Effect
exitTermina el bucle y sigue en la linea siguiente a endloop
ContinueEl programa va inmediatamente a la sentencia endloop y continuea el siguiente registro. Si no hay mas, linea siguiente a endloop.
Check exp Si if es true, el proceso continua y si no, lo mismo que continue.


Sentencia read table :
Se usa para leer un solo registro de una tabla interna.
read table it [into wa] [index i | with key keyexp [binary search] ] [comparing cmpexp] [transporting texp].


  • it es una tabla interna
  • wa es un work area
  • i es un número de registro.
  • keyexp una condición para buscar el registro
  • cmpexp es una expresion de comparación de test sobre el registro encontrado.
  • texp es una expresion que representa los campos que se transportan al work area despues que el registro ha sido encontrado.
  • Si comparing y transporting son especificados primero se realiza el comparing.


read table con la opcion index
En una tabla interna el indice de registros es el numero de registro de cada registro.En la sentencia read table , index i , especifica el registro numero i.
Ejemplo:
read table it index 7
lee el registro 7 en cabecera.
Si es correcto: sy-subrc=0 y sy-tabix=i

Ejemplo:
REPORT .
data: begin of mitabla occurs 10,
cliente(4),
nombre(20),
importe type i,
end of mitabla.

mitabla-cliente = '0001'. mitabla-nombre = 'pepito perez'. mitabla-importe = 1000.
append mitabla.
mitabla-cliente = '0002'. mitabla-nombre = 'antonio leches'. mitabla-importe = 2000.
append mitabla.
mitabla-cliente = '0003'. mitabla-nombre = 'ramiro oveja'. mitabla-importe = 3000.
append mitabla.
mitabla-cliente = '0004'. mitabla-nombre = 'jesus boina'. mitabla-importe = 4000.
append mitabla.
mitabla-cliente = '0005'. mitabla-nombre = 'remigio gutierrez'. mitabla-importe = 5000.
append mitabla.
mitabla-cliente = '0006'. mitabla-nombre = 'wenceslao roto'. mitabla-importe = 6000.
append mitabla.

read table mitabla index 3.
write: /,
/ 'sy-subrc =', sy-subrc,
/ 'sy-tabix =', sy-tabix,
/ mitabla-cliente,
/ mitabla-nombre.
Resultado:
sy-subrc=0
sy-tabix=3
0003
ramiro obeja

Si ejecutamos con
read table mitabla index 9.
cRead table con la opcion key

Si se especifica la opción key keyexp, el sistema busca un registro que cumpla la expresión clave y lo coloca en el header. Caso de encontrarse varios registros que cumplan la keyexp, solo el primero encontrado se retorna (por orden de registro). Es de suponer que la busqueda que hace es secuencial.

Expresiones de la opcion key y sus efectos.
Key Expression
Effect
c1 = v1 c2 = v2 ...Localiza el primer registro de la tabla interna cuyo componente c1 tiene el valor v1(literal, constante o vaariable) y así sucesivamente.
(f1) = v1 (f2) = v2 ...f1 contiene el nombre del componente cuyo contenido se va a comparar. (el contenido de f1 es en mayusculas).
= wawa es un work area identico en estructura a la tabla interna. Se localiza el primer registro que es igual a wa, comparando incluso blancos.. Tiene que coincidir el registro entero.
Wawa es un work area idéntico en estructura a la tabla interna pero solo los primeros n campos.
Busca el primer registro que cumple todos los n campos. Tienen que cumplir los n campos perfectamente


valores de SY-SUBRC and SY-TABIX despues de key exp
Result
sy-subrc
sy-tabix
Lectura correcta. Se encontro un registro
0
index of matching row
No se encontro un registro pero hay uno con una clave mayor que la leida
4
index of row with next higher key
No se encontro un registro ni igual ni mayor, (esto a mi no me funciona)
8
number of rows in it + 1
-----------------------
Ejemplo anterior usando key expr:

read table mitabla with key cliente = '0004'.
Resultado:
sy-subrc=0
sy-tabix=4
0004
jesus boina
---------------------
Otro ejemplo:
read table mitabla with key cliente = '0009'.
Resultado:
sy-subrc=4
sy-tabix=0
0006
wenceslao roto
------------------------------
read table mitabla with key importe = 1000."con datos numericos
sy-subrc=0
sy-tabix=1
0001
pepito perez

---------------------------------
data clave(7) value 'CLIENTE'. read table mitabla with key (clave) = '0001'. " indirecto

sy-subrc=0
sy-tabix=1
0001
pepito perez

------------------------------------





read table con la opcion binary search

Cuando usamos la opcion key addition, podemos usar la opcion binary search, que causa que el registro se localice usando una busqueda bianaria en lugar de una busqueda lineal.
Claro que antes necesita ser indexada en ascendente orden por los componentes especificados en la key exp. (ver la opcion on sorting).

???? esto hay que mirarlo mas, no se muy bien como funciona cuando los valores van con espacios....

CAUTION
Only blanks in a default key field will match all values. This means that you cannot clear types d, t, n, and x and obtain a match-clearing will set them to zeros, not blanks. You must force blanks into these fields for them to match. You can do this using a field string (see the following example), using a subfield, or using a field symbol (see the previous section on field symbols for more information).
Sin opciones como funciona?.

read table mitable.
Es como si la clave fuera todo

Usando la opcion comparing.


La opcion comparing es seguida por campos de la tabla, la busqueda y el resultado es el mismo, pero según el resultado de comparar el work area y el registro encontrado, el valor de sy-subrc cambia.
Table 11.4 Forms for the Comparison Expression in the Read Table Statement
Cmpexp
Description
f1 f2 ...Si los valores de f1, f2 son iguales en registroencontrado y work area , sy-subrc is set to 0. Si hay alguno diferente, sy-subrc es 2.
all fieldsTodos los campos son comparados.
no fieldsNo se compara nada, valor por defecto

El workarea es la cabecera o el into workarea. Hemos de tener en cuenta pues, el contenido inicial del workarea.
La utilidad de esta opción es evitarse unos if despues del read table.


La opción transporting :

La opcion transporte, es para indicar los campos del registro encontrado que pasarán al workarea.

Table 11.5 Forms for the Transporting Expression in the READ TABLE Statement
Cmpexp
Description
f1 f2 ...After a row is found, the value of f1 in the found row overlays the value of f1 in the work area. Then the value of f2 overlays the value of f2 in the work area, and so on. Only the components named after transporting are moved. All other components remain unchanged.
All fieldsAll fields are transported. This is the default, and has the same effect as leaving off the transporting addition.
no fieldsNo fields are transported. None of the fields in the work area are changed.

Es util para controlar el contenido del workarea si encuentra un registro.


ORDENANDO EL CONTENIDO DE UNA TABLA INTERNA

Para ordenar el contenido de una tabla interna, hay que usar la sentencia sort.

Los registros son ordenados por una o mas colunas en orden ascendente o descendente.

La secuencia de ordenación puede ser modificada.

Syntax de la sentencia SORT


sort it [descending] [as text] [by f1 [ascending|descending] [as text]
f2 ...].

:

  • it el nombre de una tabla interna.
  • f1 y f2 son campos de la tabla interna
  • La tabla se ordena con los campos indicados con la opción de ascending/descending y/o como texto..

mas propiedades:

  • ascending es por defecto.
  • Si descending aparece antes de los campos, se aplica a todos los campos por defecto.
  • Por defecto se ordena por la clave por defecto , que son los campos char de la tagbla en orden ascendiente.
El orden de registros con la misma clave es impredecible.


La opción text, se reffiere a las palabras acentuadas y ñ's. Por defecto en un entorno ASCII se ordena por codigo ascii del caracter.

EL text environment(entorno de texto) es un conjunto de caracteristicas asociadas con el lenguaje al hacer el usuario logon. Se caracteriza por el conjunto de caracteres utilizados y su secuencia. Se puede puede cambiar usando la sentencia set locale. La variable dels sistema sy-langu guarda el contenido de lenguaje especificado

En todo caso lo siguiente se aplica a la opcion text en la sentencia sort.
  • Solo se aplica a campos tipo c.
  • Puede especificarse para todos o campo por campo.


xxxx
xxxx

ABAP. Instruciones de control

IF

La comparación de variables constantes y literales es:


Comparaciones comunes y formas alternativas

Comparison
Alternate
Forms
True When
v1 = v2 EQv1 equals v2
v1 <> v2 NE, ><v1 does not equal v2
v1 > v2 GTv1 is greater than v2
v1 < v2 LTv1 is less than v2
v1 >= v2 GE, =>v1 is greater than or equal to v2
v1 <= v2 LE, =<v1 is less than or equal to v2
v1 between v2 and v3
v1 lies between v2 and v3 (inclusive)
not v1 between v2 and v3
v1 lies outside of the range v2 to v3 (inclusive)



Durante las comparaciones entre variables, puede haber conversiones.
Para eso se usa el ANALISIS DE PROGRAMA.
Conversion de Literales
Description
Data Type
Numbers one to nine digits long
i
Numbers 10 or more digits long
p
All others
c

Conversiones de variables en la comparación.
  • If one field is type f, the other is converted to type f.
  • If one field is type p, the other is converted to type p.
  • If one field is type i, the other is converted to type i.
  • If one field is type d, the other is converted to type d. Types c and n, however, are not converted. They are compared directly.
  • If one field is type t, the other is converted to type t. Types c and n, however, are not converted. They are compared directly.
  • If one field is type n, both are converted to type p (at this point, the other field can only be type c or x).
  • At this point, one field will be type c and the other will be type x. x is converted to type c.

Conversions follow the same rules as those performed by the move statement. Type conversions are fully detailed in the ABAP/4 keyword documentation under the heading "Relational Operators for All Data Types."


COMPARACIÓN DE STRINGS DE CARACTERES
Table 10.3 Special Operators for Character Strings


Operator


Means


True When

Case
Sensitive?
Trailing
Blanks
Ignored?
v1 CO v2 Contains Onlyv1 is composed solely of characters in v2
Yes
No
v1 CN v2 not v1 CO v2 v1 contains characters that are not in v2
Yes
No
v1 CA v2 Contains Anyv1 contains at least one character in v2
Yes
No
v1 NA v2 not v1 CA v2 v1 does not contain any character in v2
Yes
No
v1 CS v2 Contains Stringv1 contains the character string v2
No
Yes
v1 NS v2 not v1 CS v2 v1 does not contain the character string v2
No
Yes
v1 CP v2 Contains Patternv1 contains the pattern in v2
No
Yes
v1 NP v2 not v1 CP v2 v1 does not contain the pattern in v2
No
Yes

These operators can be used in any comparison expression. The CS, NS, CP, and NP operators ignore trailing blanks and are not case sensitive.

Esto es válido para variables, literales y strings.

Contains Pattern: Se pueden usar las siguientes pattern:

Table 10.4 CP and NP Operators
Character
Used to
*
Match any sequence of characters.
+
Match any single character.
#
Interpret the next character literally.


sy-fdpos. Es una variable del sistema que se puede usar para comparaciones.



Sentencia Case.

La sintaxis de la sentencia case es la siguiente:

case v1.
when v2 [ or vn ... ].
---
when v3 [ or vn ... ].
---
[ when others.
--- ]
endcase.






xxxxx

ABAP. Asignar,convertir y calcular.

Sentencias de asignación.Clear
Clear es la sentencia que se utiliza en principio para 'borrar' el contenido de una variable, o dicho de otra forma, llevarla a sus valores por defecto, sin embargo tiene algunos añadidos para iniciar la variable a conveniencia del programador.
  • Si v1 es una variable tipo c sin adicciones, es rellenada con blancos. Si v1 es e cualquier otro tipo , es rellenada con ceros. Si v1 es un field string, sus componentes siguen la misma norma.
  • Si usamos "with v2" , el primer byte de v2 es usado para rellenar todo v1.
  • Si usamos "whit 'A'" todo v1 se rellenará del literal 'A'. (¿Y si v1 es numérico?).
  • Si usamos "with NULL", se rellena todo v1 con nulos. (????).


Sentencias de asignación.Move.
Move es el operador de asignación de contenido a cualquier variable, es equivalente al igual.
Al destino se le asigna todo o parte del origen.
Tenemos las siguentes sintaxis:

move v1 to v2.
v2 = v1.
v2 = v1 = vm = vn . . ..

¡Cuidado con los espacios que son obligatorios!


Subcampos y asignación de subcampos.

move v1[+N(L)] to v2[+N(L)].
v2[+N(L)] = v1[+N(L)].

Si v1 es un char de 10:
v1(3) referencia a las tres primeras posiciones de v1, es equivalente a v1+0(3),
si v1='123456789' entonces v1+2(3) es '345' .
Los subcampos solamente son válidos con tipos char.



Asignaciones simples numericas-char.

Las conversiones con variables simples se hacen automáticamente.
Ejemplo:

REPORT .
data: caracter(5) type c,
entero type i.
caracter = 126.
caracter = '126'.
entero = 128.
caracter = entero.
entero = '128'.
entero = 129.

write: / caracter,entero.



Problemática con las conversiones de tipos numéricos.

Los sistemas operativos suelen requerir que los campos numéricos se ajusten a ciertas reglas. Por ejemplo, la dirección de un entero de cuatro bytes requieren que sea un número par. Este tipo de normas se llama Alineamento de datos numéricos.
Este alineamiento, puede dar lugar a errores en las asignaciones de field strings que se supone que copia byte a byte.

De todas formas con la entrada del unicode, esto se complica mas.




La sentencia move-corresponding
Con la sentencia move-corresponding, podemos copiar field string en otro field string solamente copiando los nombres que coincidan, el resto no se copia.

Es una solucción simple para los movimientos de datos numéricos de distintos tipos.

sintaxis: move-correspondig sf1 to sf2. " sf1 y sf2 son field string.



Calculos en ABAP.Operator.
La sentencia para realizar operaciones en ABAP, es la sentencia operator.
Operadores en ABAP
Operator
Operation
+
Addition
-
Subtraction
*
Multiplication
/
Division
**
Exponentiation
DIV
Integer division
MOD
Remainder of integer division


compute v3 = v1 op v2 [op vn ...].
v3 = v2 op v2 [op vn ...].


Calculos en ABAP.add, substract,multiply,divide.
Son calculos simples directos.

add v1 to v2
substract v1 to v2
multiply v1 to v2
divide v1 to v2


Calculos en ABAP field string.add-correspondig,
substract-corresponding,
multiply-correspondig,
divide-correspondig.


Se pueden hacer operaciones con field strings cuando coinciden los tipos de datos de los componentes.
Si los tipos de datos son distintos tenemos la posibilidad de operar solo con subcampos con los mismos nombres.




Calculos con date.






Asignación dinámica. Punteros.
Un puntero se representa con entre tags <puntero&lgt;

La sintasix simple es:
field-symbols <nombrepuntero>.


Y podemos asignarlo de esta forma
assign variable to <nombrepuntero>. 


A partir de entonces el <nombrepuntero> se puede usar de la misma forma que la variable
data var(3).
field-symbols <pun>.
assign var to <pun>.
<pun> = 'XYZ'. " es equivalente a var = 'XYZ'.

xxxxxxx

El diccionario de datos. Dominios y tipos de datos

Explorando Componentes de Tablas

Campos

Una Tabla en SAP está íntimamente ligada con una tabla de la base de datos, sobre todo en las tablas trans parentes que son las que estamos tratando.

Las tablas de la base de datos están formadas por campos. Las tablas de SAP tambien están formadas por campos.

Los campos en la base de datos, están formados basicamente por un nombre, un tipo de datos(char,fecha,numero.....) y unos datos especificativos (longitud, decimales). En SAP, estos datos están agrupados en unas entidades llamadas Elementos de Datos,

Los Elementos de Datos de SAP, contienen una parte semántica (descripciones y ayudas), y una parte técnica que es lo que está mas cerca de la tabla de base de datos, es decir el tipo del campo de la tabla de la base de datos su longitud, decimales....... Esta parte técnica se agrupa en unas entidades llamadas Dominios.

Cuando hablamos del tipo de un campo de una tabla de SAP, puede ser:
  • El Elemento de Datos al que pertenece.
  • El Dominio al que pertenece. (Parte del elemento de Datos)
  • El Tipo de campo elemental(base de datos). (Parte del dominio);

Los Elementos de Datos y Dominios pueden crear/editar/borrar desde el diccionario SAP, pero el tipo de campo de la base de datos, se puede solo consultar.


Tipos de campos basicos.

Estos tipos especifican la representación usada internamente por la basse de datos para almacenar los valores de los campos. Son por lo tanto fuertemente dependientes de la base de datos. Algunos tipos tienen deteminados una validación de formato y una salida formateada del campo. Por ejemplo los datos de fecha y hora.

Hay campos que necesitan datos adicionales como su longitud y/o número de decimales.

Tipos de Datos mas comunes
Type
Description
CHARCharacter strings (maximum 255 characters)
DECDecimal values (maximum length 31)
DATSDate field
TIMSTime field
INT1, INT2, INT4 Integer values
NUMCCharacter field that can contain only numerics

Existen también tipos de campo que son exclusivos de SAP R/3 y se encarga SAP convertirlos a datos reales de base de datos, como por ejemplo el tipo CLNT del que ya hemos hablado (mandante).


Dominios.

Veamos lo que se necesita para crear un dominio.
  • Nombre del dominio.
10 Caracteres máximo.
Tienen que empezar por y o por z, el resto esta reservado por SAP.

  • Descripción corta.
El campo descripción corta, contendrá una descripción del dominio. El usuario final nunca lo ve, sino que sólo se muestra a los desarrolladores. Cuando buscamos un dominio para un cambo, veremos esta descripción. Puede ser muy util escribirla correctamente.
  • tipo de campo.
Se trata del tipo de campo explicado anteriormente. Está intimamente ligado a la base de datos utilizada.Según el tipo de campo, nos pueden aparecer campos adicionales para implementar correspondientes al tipo de dato elegido. Como por ejemplo la longitud y los decimales.

  • Opciones de Formato. Longitud y decimales.

En algunos casos se necesita la longitud del campo y el numero de decimales.

En los campos tipo DEC, el punto decimal, no se guarda en la base de datos. Sólo la parte numérica se almacena, no la coma decimal. Al recuperar el dato, la posición de la coma decimal se determina por el valor que se pone puso en el campo decimales.

  • Opciones de Salida. Longitud, minusculas,signo.
Las opciones de salida, nos permiten un pequeño control sobre la visualización de los datos que contienen estos campos.

Con estos datos, ya sería suficiente para crear un dominio.

Elemento de Datos.

Elemento de datos.

Veamos lo que se necesita para crear un Elemento de datos.
descripcion breve
el dominio al que pertenece.
Las etiquetas?
Falta terminar

abap.estructuras,field string

Field strings

Un Field string, es un conjunto de varios datos, se corresponde a una estructura del Diccionario de SAP, por lo que también se puede corresponder con los datos de una tabla.

Hay dos formas de definir Field strings en SAP.


Field strings con la declaración data.


Sintaxis básica:
data begin of fs1.

data f1[(l)] [type t] [decimals d] [value 'xxx'].
data f2[(l)] [type t] [decimals d] [value 'xxx'].
...
data end of fs1.
Ejemplo:
data begin of totals_1.
data region(7) value 'unknown'.
data debits(15) type p.
data count type i.
data end of totals_1.
En un formato compuesto típico:
data: begin of fs1,

f1[(l)] [type t] [decimals d] [value 'xxx'],
data f2[(l)] [type t] [decimals d] [value 'xxx'],
...
data end of fs1.
Ejemplo:
data begin of totals_1.
data region(7) value 'unknown'.
data debits(15) type p.
data count type i.
data end of totals_1.

Un componente de un string field tambien puede ser un 'like'
Ejemplo:
data begin of fs1.
data region(7) value 'unknown'.
data debits(15) type p.
data count type i.
data end of fs1.
data begin of fs2.
data region(7) value 'unknown'.
data debits(15) type p.
data cosa like fs1.
data count type i.
data end of fs1.
Y se puede incluir un field string en otro fied string, pero cuidado que no puede ser en la forma compuesta porque la sentencia include no es parte de data.

Ejemplo:
data: begin of totals_1,
region(7) value 'unknown',
debits(15) type p,
count type i,
end of totals_1,
totals_2 like totals_1.
data: begin of totals_3,
xregion(7) value 'unknown',
xdebits(15) type p,
xcosas like totals_1.
include structure totals_1.
data: xcount type i,
end of totals_3.


A los componentes de un field string accedemos con la tipica barra "-"
por ejemplo en este ultimo ejemplo, podriamos escribir:

totals_3-xcosas-region = '123'.
write totals_3-xcosas-region.

Usos especiales del field string.
puede usarse el like para definir otro field string igualito.
pueden hacerse asignaciones globales si el field string es todo char.
Ejemplo:
data : begin of localidad,
ciudad(2),
pueblo(3),
end of localiddad.
localidad='12345'.
write: localidad-ciudad,localidad-pueblo.



Field strings con la declaración tables.

Con tables, podemos definir un field string con el mismo nombre y forma que una tabla o estructura del diccionario.
Sintaxis básica:
tables fs1.
fs1 tiene que ser un elemento del diccionario.


Una tabla es siempre global (visivilidad que aun no se muy bien como funciona)
Una tabla es la forma de interacturar con un select de una tabla de la base de datos.



Tipos definidos por el usuario.

Podemos definir tipos y luego usarlos de esta forma:
types t1[(l)] [type t] [decimals d].

or

types t1 like v1.





Tipos definidos por el usuario estructurados.

Podemos definir tipos de estructura y luego usarlos de esta forma:
 1 report ztx0813.
2 types: begin of address,
3 street(25),
4 city(20),
5 region(7),
6 country(15),
7 postal_code(9),
8 end of address.
9
10 data: customer_addr type address,
11 vendor_addr type address,
12 employee_addr type address,
13 shipto_addr type address.



Grupos de tipos(Type Groups). Sentencia type-pools.

Podemos definir varios tipos en el diccionario SAP agrupandolos con un nombre (llamados type Groups) y acceder a ellos
mediante la sentencia type-pools.
A los tipos accederemos de esta forma : grupo_tipo.

 type-pools ztx1.
data: begin of american_sums,
petty_cash type ztx1_dollars,
pay_outs type ztx1_dollars,
lump_sums type ztx1_dollars,
end of american_sums.

Existe un grupo de tipos en el diccionario que se llama ztx1, en los cuales está definido el tipo dollars, por lo que el tipo es en el programa ABAP ztx1_dollars.




xxxxxx

ABAP modularización.

Unidad Modularización es como un shell en que podemos escribir código.

Permite segregar un grupo de lineas de código del resto, y lo ejecutamos en un momento determinado. Las lineas de codigos dentro de una modularización actua como un mini-programa que puede llamarse desde otro programa.



ABAP/4 Ofrece tres tipo de unidades de modulariación.

  • Events
  • Subroutines
  • Function modules

Usar unidades de modularización para eliminar código redundante en su programa y hacer mas facil leerlo. Por ejemplo, suponemos que tenemos una serie de sentencias que forman una direccion de correo, y necesita formar direcciones de correo en distintos lugares de su programa. En lugar de euplicar el codigo en su programa, es una buena idea escribir el código en una unidad de modularización y llamarla cuando necesite formar una direción.


Eventos

Pese a su apariencia, los programas ABAP/4 estan orientados a eventos. Una buena forma de entender ABAP/4 es entender bien los eventos.

Definiendo Eventos

Un evento es una etiqueta que identifica una seccion de codigo. La ssecion de codigo asociada con un evento, comienza con un nombre de evento y termina cuando el siguiente nombre de evento se encuentra.En el ejemplo siguiente, los nombres de eventos son : inicializacion, start-of-selection, y end-of-selection. Los nombres de eventos son palabras reservadaas. No podemos crear nuevos eventos, solamente podemos usar los que ya existen.


Ejemplo:

  report ztx1701.
initialization.
write / '1'.

start-of-selection.
write / '2'.

end-of-selection.
write / '3'.
Etiquetas repetidas
Una etiqueta de evento puede estar repetida, y entonces el codigo de las dos etiquetas pertenecen al mismo evento ejecutandose en el orden escrito.
etiqueta1.
sentencias "primero se ejecutan estas
etiqueta2.
sentencias.
etiqueta1.
sentencias" y luego estas

Driver program.

Un driver program es un programa que controla otro (driven) programa. SAP suministra driver programas con el R/3 system. Nosotros tenemos que suministar el driven (lanzado) programa. Cuando ejecutamos el programa, el driver programa es el primero que se lanza y entonces llama a los eventos de nuestro programa..
Esto pasa con todos los programas que escribimos en ABAP/4, pero es posible que no lo supieramos hasta ahora. Lea este parrafo cuidadosamente. Lo repetimos una vez mas, cuando ejecutamos nuestros programas, un driver programa comienza primero y controla nuestro programa llamando a los eventos que hay escritos en el.

EL código asociado con un evento es ejecutado por una sentencia del driver programa. Los eventos son lanzados por el driver programa en una predefinida y predecible secuencia.

El orden en que escribimos los eventos en el programa ABAP no es importante, aunque es util escribirlos mas o menos en orden.

Un bucle o condición tiene que estar siempre completamente dentro de un evento. O dicho de otra forma, Un bucle o condición no puede tener una etiqueta de evento en su ambito.




Varios eventos ABAP.

ABAP/4 Eventos

Category
Events
Driverinitialization
at selection-screen
start-of-selection
get
end-of-selection
Userat line-selection
at pfn
at user-command
Programtop-of-page
end-of-page

Los Driver eveventos son lanzados por el Driver programa. Los Eventos de usuario son desencadenados por el usuario a traves de la interfaz de usuario. Los eventos de programa son desencadenados dentro del programa.. En este capítulo se detalla el uso de la inicialización, puesta en marcha de la selección, y al final de su selección. Tenga en cuenta que algunos de estos eventos se producen entre el comienzo de la selección y al final de su selección.

EL Evento por defecto es start-of-selection

Si escribimos sentencias ejecutables sin etiqueta de evento, se adjudican por defecto a start-of-selection.


Orden de eventos lanzados por el Driver Program
  • Primero lanza el evento initialization si existe.
  • Muestra la pantalla de seleccion del programa (si existe)..
  • Lanza el evento start-of-selection event, (recordar que es el evento por defecto en el programa ABAP). Si no hay codigo para ejecutar, no hace nada.
  • Lanza el evento end-of-selection si existe.
  • Muestra la lista de salida al usuario(output list).



Consideraciones epeciales cuando se usa write en eventos

El sistema de eventos tiene dos inusuales efectos en la sentencia write.

  • Si el programa tiene una pantalla de selecion y ponemos una sentencia write en cualquier evento de antes de start-of-selection, no veremos el ouput de el. Por ejemplo si tenemos una sentencia statement en el programa, una pantalla de seleción es creada para el programa para permitir al usuario entrar parametros. Si escribimos write en inicializacion, no veremos la salida de este write.
  • Un nuevo evento siempre empieza una nueva linea en el output Por ejemplo si ponemos un write en start-of-selection, un write en end-of-selection empezará con una nuevalinea. Podemos usar la sentencia skip to linea para saltarnos este problema.

Lanzando top-of-page

¿como top-of-of page es lanzado en relacion a otros eventos?.
Si el programa no tiene una selection screen, la primera sentencia write ejecuta el top-of-page. Si el programa tiene una selection screen, es posible que top-of-page sea lanzado dos veces:

  • Por el write ejecutado antes de la selection screen.
  • Por el primer write despues de selection screen es mostrado.

Solamente si escribe alguna sentencia inusual en top-of-page deberá tener cuidado con este doble lanzamiento de eventos.

Si se ejecuta dos veces top-of-page, el write del primero sá descartado. Hay que tener cuidado

  • No se puede ver los writes antes de la seleccion. Por lo que no suele escribirse la sentencia write en estos casos.
  • Como solamente se suele escribir sentencias write en top-of-page, esta duplicación no hace daño.

Saliendo de un Evento

Se puede salir de un evento en cualquier momento con las siguientes sentencias:

  • exit
  • check
  • stop

At this time, please review the function of the check statement (presented in Chapter 10, "Common Control Statements").

Exit y check son sentencias que se usan dentro de un bucle, en tal caso, no tienen nada que ver con el evento.

Exit y check escritos fuera de un bucle, tienen que ver con eventos.

Check

Si el resultado de check es true, se sale del evento y el programa sigue su curso.

Stop

end-of-selection. se sale del evento y el programa sigue su curso.

fuera de end-of-selection. Se sale del evento y se ejecuta el evento end-of-selection.

Exit

En eventos anteriores a start-of-selection, se sale del evento y el programa sigue su curso.

En start-of-selection y eventos posteriores

----------top-of-page. se sale del evento y el programa sigue su curso.

----------------resto de eventos. Termina el report y muestra el output list.

Consejos:
No usar stop en los siguientes eventos:
initialization,
at selection-screen output,
top-of-page, Se produce short dump
end-of-page. Se puede perder salida(si usa write).
Tecnicamente,stop puede funcionar bien en top-of-page y end-of-page si nos abasstenemos de poner sentencias write en el end-of-sselection. Es más seguro de evitar por completo dentro de estos eventos.
sy-subrc
check, exit, y stop nocambian el valor de sy-subrc. Si hace falta podemos asignar nuestro propios valores.

El botón volver (back). Copia de los datos de la pantalla de selección.

Miremos mas de cerca los eventos en un report que tiene una selection screen (Recordar que la sentencia parameters genera una pantalla de selección).

Cuando el usuario ejecuta el report, el conductor(driver) lanza la inicialización y muestra la pantalla de selección. Cuando el usuario presiona el botón de ejecutar, el conductor lanza el resto de eventos y el programa termina mostrando al usuario la lista de salida. El usuario entonces presiona el boton Retorno(back), para volver, el conductor restaura el proceso comenzando al principio de la lista de eventos, comenzando por el evento inicialización y El usuario ve el la pantalla de seleción. Sin embargo hay alguna diferencia cuando ocurre la restauración.

La pantalla de seleción tiene una copia (propia) de las variables que se muestran en el. La primera vez que se ejecuta el report y el programa conductor toma el control despues de terminar la inicializacion, guarda en su copia los valores de las variables que corresponden a la pantalla de seleción y los muestra . El usuario entonces puede modificar los campos. Cuando el usuaro pulsa el boton de ejecución, el conductor guarda en su copia los valores de las variables de la pantalla de selección a parte de guardar los datos en las variables del programa.

Sin embargo la primera copia(la de despues de la inicialización) solamente ocurre la primera vez que ejecutamos el programa, por lo que al usuario se le muestra los últimos valores introducidos.

Subrutinas. form,endfor y perform.

Una subrutina es una sección de código reutilizable. Es como un mini-programa que puede ser llamado desde otro punto de su programa. Dentro de el, se pueden definir las variables, ejecutar declaraciones, calcular los resultados, y escribir salida. Para definir una subrutina, se utiliza la sentencia form para indicar el comienzo y la sentencia endform para terminarla. El nombre de una subrutina no puede exceder los 30 caracteres.

Para llamar una subrutina, usamos la sentencia perform.
Hay dos tipos de subrutinas.
  • Subrutinas internas.
  • Subrutinas externas.


Definir y llamar a una subrutina interna.

Las definiciones de subrutinas suelen normalmente escribirse al final del programa , despues de todos los eventos.

La sentencia form define el fin del evento precedente y el principio de una subrutina. Las subrutinas no pueden anidarse dentro de eventos.


Sintaxis de la sentencia form.

form s [tables t1 t2 ...]
[using u1 value(u2) ...]
[changing c1 value(c2) ...].
---
endform.

donde:

  • s es el nombre de la subrutina
  • t1, t2, u1, u2, c1, y c2 son parámetros.
  • tables permite pasar tablas internas como parámetros
  • La opción value no puede ser usada con tables.
  • La opción value, puede ser aplicada a variables via using o changing.
  • --- represents any number of lines of code.

The following points apply:


  • Los parámetros son opcionales.
  • Hay que respetar el orden.Siempre las tablas primero, luego las using y luego las changing.
  • No puede haber mas de una opcion tables , using y/o changig Each addition can only be specified once.
  • No usar comas para separar parámetros.
  • No se permiten tables de databases.
  • Una subrutina puede llamar a otra/s subrutinas.
  • Esta soportada la Recursividad. Una subrutina puede llamarse a si misma. Y una subrutina puede llamar a la subrutina que le ha llamado.
  • No se pueden anidar subrutinas (No podemos definir subrutinas dentro de otras subrutinas.)

Syntax for the perform Statement

perform  s   
[tables t1 t2 ...]
[using u1 u2 ...]
[changing c1 c2 ...].
perform  n of s1 s2 s3 ... 
[tables t1 t2 ...]
[using u1 u2 ...]
[changing c1 c2 ...].


  • s, s1, s2, s3, son nombres de subrutinas.
  • n is un numerico valor (si vale 1, se ejecutara s1, si vale 2, se ejecutara s2.......)
  • tables, using, and changing son opcionales
  • La opción value() no puede usarse con perform.

Saliendo de una subrutina.

Podemos salir de una subrutina con cualquiera de estas sentencias

  • exit
  • check
  • stop

Exit y check dentro de un bucle no tienen efecto en una subrutina.

  • check and exit Salen de la subrutina y continua con la sentencia que sigue al perform que llamó a la subrutina
  • stop sale de la surutina y va directamente al end-of-selection evento.????

check, exit, y stop no modifican el valor de sy-subrc.


Definiendo Variables locales y globales.

Variables globales.

Una variable global es una que es definida fuera de una subrutina usando la sentencia tables o data. Se puede acceder a ellas en cualquier punto del programa dentro o fuera de eventos y subrutinas. Una buena práctica es escribir la definiciones de las variables globales al principio del programa antes de cualquier linea de codigo ejecutable.

Variables locales
Una variable local es una variable que que se defina dentro de una subrutina usando las sentencias local,data o statics. Estas variables decimos que son locales a la subrutinas.
  • Local
Una variable definida con la sentencia local, es accesible por las subrutinas llamadas por la subrutina en la que están definidas las variables. Son inicializadas(se crea una copia) cada vez que se llama a la subrutina.
  • data
Las variables definidas localmente con la sentencia data, son inicializadas(se crea una copia) cada vez que se llama a la subrutina, pero al contrario de las creadas con Local, no son visibles por las subrutinas llamadas.
  • statics
Las variables definidas con statics son creadas una sola vez, por lo que su valor persiste. No son visibles por las subrutinas llamadas.
Visivilidad global versus Sentencia local.
Una variable global es visible para todo el programa pero ¡ojo! solamente a partir del punto donde se ha definido.
Una variable creada con la sentencia local en una subrutina, es visible por cualquier otra subrutina llamada por esta. ¡aunque la subrutina llamada esté escrita antes de la definición de la variable.!
Es una de las muchas razones de no escribir globales dentro de una subrutina.


Definiendo una tables Work Area con local.

Las variables definidas usando la sentencia tables son siempre globales . Pero no parece que haya motivos para escribir una sentencia tables dentro de una subrutina.

Para definir una local tabla wrok area dentro de una subrutina, usaremos local en lugar de tables.La sintaxis es la misma, y es visible por las subrutinas llamadas.


Siempre que coincidan en nombre una variable local y otra global, siempre tiene preferencia la local, por lo que las variables globales se hacen invisibles cuando hay una variable local con el mismo nombre.

Defining Data

Las variables definidas con la sentencia data en el comienzo del programa son globales. Las definiciones data en una subrutina, son locales a la subrutina. La memoria es asignada para estas variables cuando la subrutina es llamada, y liberada cuando la subrutina termina. Lo mismo que las variables definidas usando local, los valores de data locales se pierden cuando la subrutina termina.

La variables locales cradas con la sentencia statics no se pierden ni se liberan cuando se termina la subrutina. La sintaxis de static es la misma que la sentencia data. La memoria de variables estáticas es asignada la primera vez que se llama y se conserva al fin de la subrutina. Sin embargo, una variable estática es solo visible dentro de la subrutina. La siguiente vez que la subrutina es llamada, la variable vuelve a ser visible ysu valor es el mismo que la ultima vez que se retorno la subrutina.


Pasando Parámetros a subrutinas.

Los parámetros son variables,tablas,constalntes,literales... que se pasan de unas subrutinas a otras.

  • Parámetros formales
Son los que se definen en la sentencia form con una de estas opciones: tables,changing,using.
  • Parámetros actuales
Son las variables,tablas,cosntantes.... que se pasan a la subrutina en la sentencia perform.


Tipado de los parámetros formales.
En la sentencia form hemos visto, que los parametros se escriben uno detras de otros separados por espacios.
Si además ponemos el tipo, se llaman parámetros tipados.

Ejemplo de form con parámetros sin tipar.
form s1 using p1  p2  p3  p4. 
Ejemplo de form con parámetros tipados.
form s1 using p1 type c p2 type i p3 type d p4 type t.


Pasando field strings como parámetros.

Podemos pasa field strings (estructuras) como parámetros de este modo:
  • like x
  • structure x
Donde x es un field string o una estructura o tabla del diccionario.

Paso por referencia,valor,resultado.

Hay tres formas de pasar los valores a una subrutina.

  • Paso por referencia.
  • Paso por valor.
  • Paso por valor y resultado.
La sintaxis de la sentencia form determina como pasan las variables. El perform no puede cambiar la forma de paso .

forma de paso de variables a subrutinas.
Addition
Method
using v1 Por referencia
changing v1 Por referencia
using value(v1) Por valor
changing value(v1) Por valor y resultado.

Por defecto, los valores se pasan por referencia.

LOS PARÁMETROS CON LA OPCIÓN CHANGING SOLO DIFIEREN DE LA OPCIÓN USING CUANDO SE PASA POR VALOR . UN CHANGING SIEMPRE PUEDE CAMBIAR DE VALOR AUNQUE SE PASE CON LA OPCION VALUE.



xxx