jueves, 16 de enero de 2014

Ejemplo de SHARED MEMORY OBJECTS

 Voy a iniciar 2014 activando este blog con una serie de artículos sobre SAP, orientados a la parte técnica, aunque alguno será enfocado a presentar algún producto interesante de SAP o hablar de algún nicho de mercado donde SAP está trabajando activamente.

En primer lugar, hablaré de los objetos en memoria compartida (SHARED MEMORY OBJECTS).


Esta memoria va más allá de la clásica memoria SET/GET, EXPORT/IMPORT donde se pueden exportar a lo sumo tablas, pero no instancias de objetos ABAP, lo cual es una ventaja y conviene saber usarlo si en algún cliente es necesario compartir entre programas información de objetos. Esto simplifica el código porque de otro modo, hay que leer los atributos del objeto, exportarlo a memoria con las sentencias clásicas, importarlo en otro lugar y usar esa información y a veces enviarla de vuelta modificada, lo cual ya sólo escribirlo cansa, a parte de la dificultad de trabajar con IDs de memoria los cuales pueden causar problemas al perderles la pista a medida que el proyecto avanza.

De otro modo si el objeto se lleva a memoria compartida y es posible leerlo y escribir sobre él, es mucho más sencillo este tratamiento, sólo es necesario saber tratarlo y conocer las limitaciones que pueda tener esta operativa.

Otra ventaja que tienen los SHARED MEMORY OBJECTS es el tiempo de ejecución. A veces  la única forma de transmitir información de SAP de una transacción a otra es grabar los datos en la base de datos. Esto implica que es necesaria la actividad del usuario para que esta transmisión sea posible,  lo cual complica el procedimiento. Si hay un despiste, se pierde información y eso debería evitarse en lo posible.



Elaboramos un ejemplo sencillo donde dos programas necesiten compartir y actualizar un objeto en memoria.

Por ejemplo, una pantalla de selección con una variable CHAR de longitud 2, el programa mostrará lo que metamos en esa variable. Al mismo tiempo esta variable actualiza un objeto con un atributo que también sea CHAR de longitud 2.

Este objeto lo vamos a compartir a través del metodología de SHARED MEMORY OBJECTS.
A su vez hacemos otro programa que lea la memoria compartida y escriba el atributo del objeto compartido en pantalla.

Lo iremos modificando y mostrando varias veces para demostrar que efectivamente podemos crear un flujo de datos a través de los dos programas unidos a través de la memoria compartida.
En primer lugar creamos una clase que va a contener los objetos a compartir y que se denominará ROOT. Tendrá dos características a  tener en cuenta.:

1) Su interfaz será  IF_SHM_BUILD_INSTANCE.
Esto le asigna por defecto un  método constructor llamado build
2) El pincho Shared Memory-Enabled debe estar marcado.
3) Esta clase tendrá los métodos que  leerán y modificaran datos.


En el ejemplo se implementan dos métodos, con variable de entrada y salida tipo char de longitud 2, llamadas im_value y ex_value.
El método READ_DATA

method READ_DATA.
 ex_value = value.
endmethod.

 Y el método SET_DATA

METHOD set_data.

  IF im_value IS INITIAL AND value IS INITIAL.
    value = '01'.
  ELSE.
    value = im_value.
  ENDIF.

ENDMETHOD.

También implementamos el método build


method IF_SHM_BUILD_INSTANCE~BUILD.
  
data: lcl_test1 type ref to ZCL_SMO_TEST1,
        lcl_shma_test1 type ref to ZSHMA_AREA_TEST1,
        lx_exception type ref to cx_root.
  try.
      lcl_shma_test1 = ZSHMA_AREA_TEST1=>attach_for_write( ).
    catch cx_shm_error into lx_exception.
      RAISE EXCEPTION type cx_shm_build_failed
        EXPORTING
          previous = lx_exception.
  endtry.

  try.
      CREATE OBJECT lcl_test1 area handle lcl_shma_test1.
      lcl_shma_test1->set_root( lcl_test1 ).
      lcl_test1->set_data( ).
      lcl_shma_test1->detach_commit( ).
    catch cx_shm_error into lx_exception.
      RAISE EXCEPTION type cx_shm_build_failed
        EXPORTING
          previous = lx_exception.
  endtry.

  if invocation_mode = cl_shm_area=>invocation_mode_auto_build.
    CALL FUNCTION 'DB_COMMIT'.
  endif.
endmethod.


A través de la transacción SHMA creamos un área de memoria.
La clase raíz y la clase constructor será la clase root. En la pestaña “historial” se podrá ver quien creó y modificó el área.



Ya creado esto sólo nos queda escribir código en el programa que enviará datos a memoria y escribir código en el programa que leerá el objeto compartido.

En  la ayuda de SAP podemos leer lo siguiente.
Para el programa que escribe la información:

DATA: my_handle TYPE REF TO cl_my_area, 
      my_data   TYPE REF TO cl_my_data. 

TRY. 
    my_handle = cl_my_area=>attach_for_write( ). 

    CREATE OBJECT my_data AREA HANDLE my_handle. 

    my_handle->set_root( my_data ). 

    my_data->read_spfli( ). 

    my_handle->detach_commit( ). 
-   CATCH cx_shm_attach_error. 
    ... 
ENDTRY.
 Y para el programa que lee la información: 
DATA my_handle TYPE REF TO cl_my_area. 

TRY. 
    my_handle = cl_my_area=>attach_for_read( ). 

    my_handle->root->output_spfli( ). 

    my_handle->detach( ). 

  CATCH cx_shm_attach_error. 
    ... 
ENDTRY.

Teniendo en cuenta que la clase root en nuestro ejemplo se llama:

ZCL_SMO_TEST1 y la clase asociada al área compartida, ZSHMA_AREA_TEST1.

Creamos un report 1, en el cual introducimos una variable y la exportamos al atributo “value” del objeto compartido y mostramos por pantalla el valor de la variable introducida. El código es sencillo y es el siguiente.

REPORT  zsmreport1.

PARAMETERS: p_value TYPE c LENGTH 2.

* Define the area and memory object references
DATA: lcl_data TYPE REF TO zcl_smo_test1,
      lcl_area TYPE REF TO zshma_area_test1,
      lv_exception TYPE REF TO cx_root.

TRY.
    lcl_area = zshma_area_test1=>attach_for_write( ).
    CREATE OBJECT lcl_data AREA HANDLE lcl_area.
    CALL METHOD lcl_area->set_root
      EXPORTING
        root = lcl_data.

    CALL METHOD lcl_area->root->set_data(
      EXPORTING
        im_value = p_value ).

    lcl_area->detach_commit( ).

  CATCH cx_shm_attach_error.
ENDTRY.

WRITE: 'El valor de entrada es ',  p_value.

Creamos un report 2 en el cual leemos el atributo del objeto compartido y lo mostramos por pantalla. El código es el siguiente.

REPORT  zsmreport2.


DATA: gv_value TYPE c LENGTH 2.
* Define the area and memory object references
DATA: lcl_area TYPE REF TO zshma_area_test1.

TRY.
     lcl_area = zshma_area_test1=>attach_for_read( ).

     call method lcl_area->root->read_data
       IMPORTING ex_value =  gv_value.

    lcl_area->detach( ).

  CATCH cx_shm_attach_error.

ENDTRY.

WRITE: 'El valor en memoria es ',  gv_value.

Probando los programas se ve que efectivamente se comparte una variable a través del atributo de la clase ROOT.

Este es un ejemplo sencillo aunque los SHARED MEMORY OBJECTS, muestran toda su potencia cuando compartimos objetos entre programas, caso que puede darse fácilmente en un cliente real.
Una última cosa es cómo visualizar el valor del objeto compartido. Vamos a la transacción SHMA.

 Pulsamos en el icóno “Monitor”



Y pulsamos en el área que nos interese con doble click.



 Seleccionamos la instancia que queramos conocer, pulsamos el icono leer versión activa
 y se mostrará en un modo nuevo los datos a visualizar.



Pulsamos:





 Así podemos comprobar los valores que se comparten sin necesidad de debugging.



Más ayuda en :

http://help.sap.com/saphelp_nw70/helpdata/en/c5/85634e53d422409f0975aa9a551297/frameset.htm



miércoles, 27 de marzo de 2013

Generar Datos en el Modelo de Vuelo

Casi todos los que hemos tenido acceso a una formación de SAP conocemos el modelo de vuelo para el training...que es el que en los manuales de SAP propone para ejercitarse con ABAP.

Pero muchas veces nos encontramos con sistemas donde esas tablas no tienen ningún dato, y no podemos hacer nada interesante..o que muestre algún resultado.

Para ello existe el report estandard SAPBC_DATA_GENERATOR con el cual podremos generar datos con los que probar nuestros programas.




viernes, 22 de junio de 2012

Validaciones SE16N con &SAP_EDIT


Casi todo el mundo que está trabajando en SAP  tiene, tarde o temprano, que modificar datos en las tablas del diccionario, del estandard o tablas creadas a medida. Una manera de hacerlo es usar la sentencia &SAP_EDIT antes del display de datos en la SE16N. No obstante, SAP ha notado este uso por parte de consultores y usuarios y ha diseñado notas que corrigen esta funcionalidad por considerarlo un BUG en la seguridad de los datos del sistema en entornos Productivos. Entiendo el sentido de esta preocupación y la solución aportada, sin embargo, siempre puede ocurrir que hay que modificar un dato debido a que otro proceso, o bien un usuario o un programa ha generado un dato erróneo y no es posible una marcha atrás. Por ello coloco el procedimiento para saltarse las validaciones implementadas, en casos puntuales. 

1.) Activación de SAP_EDIT en la SE16N.

Breakpoint en el programa LSE16NF10, rutina EXECUTE.
Cuando llama a la función SE16N_INTERFACE hay que cambiar las variables GD-EDIT a X y la GD-SAPEDIT a X.

Con esto simulamos el &SAP_EDIT.

2.) Evitar el chequeo de verificación

Breakpoint en programa LSDFCF02, rutina FORKEY_CHECK Linea if has_forkey is initial

Cuando se grabe en la SE16N y se pare en este punto hay que dar a continuar hasta que la variable DFIES_WA-FIELDNAME tenga el nombre de los campos a chequear de la tabla que queremos modificar. Hay que limpiar la variable has_forkey para todos los campos que se chequean, si no se hace así, no se graba la modificación.

"Afortunadamente" esto no se hace fácilmente por el cual siempre un programador experimentado en debug es necesario para realizar este proceso. De todos modos, apelo a vuestra responsabilidad usando esta información.


lunes, 2 de abril de 2012

Crear Listados ALV en SAP

Adjunto documentación interesante para crear ALV GRID  en SAP. Listados dinámicos y configurables.

http://abapinho.com/wp-content/uploads/2010/05/ALV_Grid_Control_2003.pdf

http://help.sap.com/printdocu/core/print46c/en/data/pdf/BCSRVALV/BCSRVALV.pdf

No me voy a extender mucho en este post, más bien solo hacer una recomendación. Sería bueno hacer una función a la cual solo pasando los datos ya saque un ALV modelo. Ahorra mucho tiempo en los proyectos que normalmente, precisan de muchos listados.

lunes, 16 de enero de 2012

Cambiar Documentos de FI sin Batch Input

Una forma de actualizar los documentos de FI de modo automático suele ser la llamada por código a la misma transacción que utiliza el usuario para cambiar los documentos, no obstante haciendo eso también se suele estar sujeto a todas las validaciones a las que las transacciones son sometidas para evitar que los usuarios introduzcan datos en el sistema que no conviene por las razones que sean.

Por eso suele ser una buena idea hacer uso de una función estandard llamada CHANGE_DOCUMENT, con la cual, sólo cargando las tablas de forma adecuada, se pueden cambiar los valores de las tablas sin necesidad de estar sometidos a las validaciones y al consiguiente manejo de errores que siempre suele ser engorroso.


miércoles, 30 de noviembre de 2011

Programa que Regenera las sustituciones y validaciones en SAP

Frencuentemente toca añadir validaciones y sustituciones en el sistema SAP. A veces, hay que usar las user-exits que el estandard propone cómo ampliación y las cuales dan trabajo a nosotros, los programadores...

No obstante, una vez creada la nueva rutina hay que pasar un programa que regenere el Programa Estandard.

Este Report es:

RGUGBR00

En el cual hay diversas opciones.
















Es cuestión de ir probando, pero al final en los programas Standard:

GBTC2FIB para sustituciones y GBTC2FIF para validaciones, ha de haber una referencia de sustitución a nuestra nueva rutina generada por este programa.

jueves, 9 de junio de 2011

Rastreo de SET en SAP FI

Para observar en que validación - sustitución un set ha sido usado, viene excelente el manejo del siguiente Report Standard

RGUSTU01