viernes, 12 de junio de 2009

ALV Con Colores

ALV CON COLORES

Los listados ALV se pueden mostrar con diferentes colores tanto en filas como en columnas.

FILAS: En la tabla interna que se le pasa a la funcion del ALV habrá que añadir un campo de 4 caracteres llamado color (o como se quiera). Luego tan solo habrá que completar en ese campo y para esa fila el color que se desee. Para que la función interprete que le estamos pasando un color en el campo info_fieldname del layout habrá que poner el nombre del campo que guarda el color.

ls_layout-info_fieldname = 'COLOR'.

COLUMNAS: Para poner colores en las columnas habrá que poner en el catálogo que se le pasa a la función ALV que esa columna la pinte de un determinado color. Para ello existe el campo"emphasize" en el catálogo donde se le introduce el color.

gt_catalog-col_pos = col_pos.
gt_catalog-ref_tabname = 'MBEW'.
gt_catalog-tabname = 'GT_DATOS'.
gt_catalog-fieldname = 'MATNR'.
gt_catalog-emphasize = 'C401'.
APPEND gt_catalog. CLEAR gt_catalog.
ADD 1 TO col_pos.

CODIFICACION DE COLORES: El color del ALV sigue el siguiente formato CXYZ donde...

C-> indica que es un color
X-> indica el numero de color, que debe ser del 1 al 9
Y-> indica la intensidad: ('0'=off / '1'=on).
X-> indica si el color es inverso ('0'=off / '1'=on).

viernes, 5 de junio de 2009

Conceptos y Ejemplos de programación en HR

Desde siempre hemos visto que toda la información en SAP se guarda en tablas de diccionario. HR no es una excepción, pero además aparecen nuevos contenedores de información que son: Bases de datos lógicas de HR, Infotipos y Tablas de Base de datos.

En HR tenemos dos bases de datos lógicas que son PNP y PAP. La primera se refiere a los datos de los empleados y la segunda a los datos a los candidatos. El uso de Base de datos lógica facilita el acceso a los infotipos.


En los Infotipos se guarda la información referente al personal de la empresa: Datos de personales, Datos bancarios, Datos de nómina, Formación , Salud, Derecho de vacaciones, etc… en el sistema hay aproximadamente unos trescientos infotipos distintos, aunque muchos de ellos son específicos de cada país (como por ejemplo el infotipo 88 que guarda la información de la maternidad en Gran Bretaña).


Las Tablas de base de datos se dividen en áreas o clusters, estas áreas o cluster guardan información referente a las a los resultados de nóminas, Impuestos, Seguridad Social, etc… El acceso a estas tablas es el más complicado de todos, debido a que no se accede como en una tabla cluster normal y corriente, como la INDX, sino que se accede a través de macroinstrucciones.


Para acceder a los infotipos existen sentencias específicas para el acceso a infotipo y macroinstrucciones que es una combinación de estas últimas.


Las Sentencias específicas para el acceso a infotipos son aquellas que usaremos para declarar el infotipo en el programa (el equivalente a la sentencia Tables) y el acceso a dicho(s) infotipo(s), su equivalente sería el Select.


Las Macroinstrucciones es una posibilidad más de modularizar programas. Las macroinstrucciones contienen sentencias ABAP/4 que permiten el ahorro de trabajo.



Bases de datos lógica
Como se ha mencionado antes SAP tiene dos base de datos lógica: PNP que se refiere a los datos de empleado y la PAP que se refiere a los datos de candidatos. La base de datos que más se usa es la PNP y será dicha tabla que usaremos como ejemplo.


Cuando ejecutamos un report que accede a la base de datos lógica, esta carga los datos de personal de cada empleado en memoria para su tratamiento.


En memoria se carga el historial completo del empleado. Estos datos se pierden cuando se carga un nuevo empleado.


Cada vez que se usa la base de datos lógica se realizan dos verificaciones una de personal y otra de datos.


La primera se verifica que el usuario tiene acceso al empleado siguiendo los criterios de asignación organizacional. Si el usuario no tiene acceso al empleado, este no se evalúa.


La segunda verifica que el usuario tiene acceso a los infotipos especificados en el report.


Un ejemplo sencillo sería:


En los atributos del programa:


El código fuente:


REPORT zprueba1.
* PERNR es una estructura que es llenada por la base de datos lógica PNP
* con los datos del empleado
TABLES: pernr." --Datos de personal
* Declaración de los infotipos


INFOTYPES: 0001.

START-OF-SELECTION.

GET pernr. " Usa base de datos lógica PNP

PROVIDE * FROM p0001 BETWEEN pn-begda AND pn-endda.

WRITE:/ 'P0001:’, p0001.
ENDPROVIDE.



Los campos de la selección de datos están definidos en la estructura QPPNP , mientras que los campos de selección de personal están definidos en el programa include DBPNPSEL (Tablas internas que se completan mediante APPEND).


Cuando se usa la base de datos lógica PNP hay que declarar en el programa la estructura PERNR , en esta estructura se guardarán los números de personal seleccionados mediante la pantalla de selección.


En la estructura PERNR solo hay que el leer el campo PERNR, que contiene el número de empleado, el resto de campos se encuentran allí por motivos internos.


Si se usa la base de lógica PAP habrá que declarar la tabla APPLICANT, para obtener el numero de candidato.


Cuando se realiza el GET re rellenan la tablas internas (el nombre de la tabla interna es Pnnnn , nnnn es el número del infotipo) de los infotipos (declarados en la sentencia INFOTYPES) con los registros, desde los datos inferior hasta los datos superiores, del numero de personal leído en el GET .

INFOTIPOS

Los infotipos se utilizan en HR y representan grupos de datos relacionados con un tema en particular. Los datos que se almacenan en un infotipo dependerán del número de personal de un empleado o del número de un candidato, es decir, cada empleado o candidato siempre se le asigna un registro de infotipo.

Cada infotipo está compuesto por un número de cuatro dígitos nnnn . El rango de número de 9000 a 9999 esta reservado para los infotipos del cliente.

Mediante la transacción PM01 – Diálogos en la gestión de personal se pueden crear y tratar infotipos.

En un infotipo no podemos añadir ni borrar información, solo podemos modificarla.

Declaración

Antes de procesar un infotipo hay que declararlo. Para declararlo hay que usar la sentencia INFOTYPES.

El rango de infotipos es el siguiente:

* Entre el 0000 y 0999 tenemos los datos maestros del infotipo.
* Entre el 1000 y el 1999 tenemos los datos de planificación.
* Entre el 2000 y el 2999 tenemos los datos de tiempo.
* Entre el 3000 y 8999 no tenemos nada.
* Y entre el 9000 y 9999 tenemos los infotipos de cliente.


La sintaxis sería:

INFOTYPES: nnnn [NAME c] [OCCURS n] [MODE N] [VALID FROM comp1 TO comp2]

Donde nnnn es el número del infotipo que vamos a declarar.

Cuando se declara un infotipo en memoria se crea una tabla interna con la siguiente estructura:

DATA BEGIN OF Pnnnn OCCURS 10.

INCLUDE STRUCTURE Pnnnn.

DATA END OF Pnnnn VALID BETWEEN BEGDA AND ENDDA.

La cláusula VALID BETWEEN BEGDA AND ENDDA indica que período se va a coger registros.

Los parámetros opcionales son:

* NAME C Nos crea una tabla interna, con la misma estructura que el infotipo declarado, con el nombre indicado en C. C tiene un longitud máxima de 20 caracteres.
* OCCURS n Nos crea una tabla interna poniendo el valor n en la cláusula OCCURS.
* MODE n Esta cláusula solo esta disponible para las bases de datos lógica PNP y PCH, y su efecto es que no llena el infotipo cuando se ejecuta la sentencia GET PERNR.
* VALID FROM comp1 TO comp2 Cuando se ejecuta la sentencia GET PERNR el infotipo se llenará con los registros cuyo período este comprendido entre comp1 y comp2.

Procesamiento del infotipo

Existen dos maneras de procesar un infotipo:

* Procesamiento de un registro especifico del infotipo, el más reciente/más antiguo.
* Procesamiento de todo el infotipo.



Procesar de un registro específico del infotipo

En muchos casos no necesitaremos leer todos los registros del infotipo, sino que necesitaremos leer el último o primer registro. Para ello utilizaremos las siguientes macroinstrucciones:

Nos devuelve el último registro.
àRP-PROVIDE-FROM-LAST Pnnn SPACE PN-BEGDA PN-ENNDA

Nos devuelve el primer registro.
àRP-PROVIDE-FROM-FIRST Pnnn SPACE PN-BEGDA PN-ENNDA

Donde nnnn es el numero de infotipo, en la variable PN-BEGDA o PNPENDDA tenemos la fecha inicial del período introducido por pantalla, y en PN-ENDDA o PNPENDDA tenemos la fecha final del período introducido por pantalla.

Un ejemplo sería:

REPORT zprueba1.

* PERNR es una estructura que es llenada por la base de datos lógica PNP

* con los datos del empleado

TABLES: pernr." --> Datos de personal

* Declaración de los infotipos

INFOTYPES: 0001.

START-OF-SELECTION.

GET pernr. " --> Usa base de datos lógica PNP

rp_provide_from_last p0001 space pn-begda pn-endda.

* Si hemos encontrado datos entonces se muestra el registro.

IF pnp-sw-found = ’1’.

WRITE:/ ’P0001:’, p0001.

* En caso contrario leemos el siguiente numero de personal

ELSE.

REJECT.

ENDIF.

Las macroinstrucciones se definen en la tabla TRMAC.



Procesamiento de todo el infotipo

Ya hemos comentado que cuando se realiza un GET PERNR las tablas internas de los infotipos son llenadas con el historial completo (del más antiguo al más reciente) del empleado leído. Por lo tanto podemos tener que en una tabla interna existan más de un registro o períodos o intervalos de validez.

El procesamiento de registros del infotipo es dependiente del tiempo, es decir, depende del período de selección de datos introducido en la imagen de selección. Pueden procesarse al mismo tiempo los datos de varios infotipos y pueden prepararse para un período de tiempo parcial específico.

Las tablas internas del infotipo se procesan con la sentencia PROVIDE. La sintaxis es:

PROVIDE * FROM Pnnnn BETWEEN PN-BEGDA AND PN-ENDDA.

……..

ENDPROVIDE.

Donde nnnn sería el numero del infotipo. La relación entre el infotipo y el período de selección de datos de la imagen de selección se establece mediante las variables PN-BEGDA (Inicio) y PN-ENDDA (Fin).

Actualización de un infotipo

Como hemos se ha visto antes a los infotipos no se les puede insertar ni borrar, pero si que podemos es modificar sus datos. Para ello esta la macroinstrucción RP-UPDATE. Cuya sintaxis es:

RP-UPDATE datos_antiguos datos_nuevos.

Un ejemplo sería:

REPORT ZPRUEBA .
TABLES: PERNR.
* Definimos una tabla interna llamada OLD/NEW con la misma estructura
* que 0001.
INFOTYPES: 0001 NAME OLD,
0001 NAME NEW.

START-OF-SELECTION.


GET PERNR.
* Cuando se efectura el GET las tablas internas OLD y NEW están llenas
* con el resultado de la búsqueda
PROVIDE * FROM OLD BETWEEN PNPBEGDA AND PNPENDDA.
WRITE:/, OLD-PERNR, 'OLD-PERSK':, OLD-PERSK.
* Ponemos el nuevo valor a la tabla NEW
NEW-PERSK = '22'.
WRITE:/ 'NEW-PERSK':, NEW-PERSK.
* Modificamos la tabla interna, no insertamos porque ya esta llena
MODIFY NEW INDEX SY-TABIX.
ENDPROVIDE.
* Llamamos a la macroinstrucción RP-UPDATE pasando la tablas interna
* con los viejos y nuevos datos.
RP-UPDATE OLD NEW.

viernes, 29 de mayo de 2009

User Exit para ME21N, ME22N

Les adjunto 2 user exit, que se gatillan, al momento de grabar y dar enter en los pedidos de compra.

personalmente me ha servido de mucha utilidad :

EXIT_SAPMM06E_006, Include ZXM06U36

EXIT_SAPMM06E_017, include ZXM06U42

jueves, 28 de mayo de 2009

Ejemplo de Select Options Dinamico


Con el siguiente código podremos crear pantallas de entrada de datos dinámicas. Donde según el radio button que se elija, aparecerán distintos filtros de selección.



TABLES: KNA1, MARA.

************************************************************************
*** SELECTION-SCREEN / PARAMETERS / SELECT-OPTIONS ***
************************************************************************
SELECTION-SCREEN BEGIN OF BLOCK B1 WITH FRAME TITLE TEXT-A01.
PARAMETERS:
R_CLIE RADIOBUTTON GROUP GRUP USER-COMMAND R DEFAULT ‘X’,
R_MATE RADIOBUTTON GROUP GRUP.
SELECTION-SCREEN END OF BLOCK B1.

*Datos Clientes
SELECTION-SCREEN BEGIN OF BLOCK B2 WITH FRAME TITLE TEXT-B02.
SELECT-OPTIONS: SO_CLIE FOR KNA1-KUNNR MODIF ID CLI,
SO_NAME FOR KNA1-NAME1 MODIF ID CLI,
SO_LAND FOR KNA1-LAND1 MODIF ID CLI.
SELECTION-SCREEN END OF BLOCK B2.

*Datos Materiales
SELECTION-SCREEN BEGIN OF BLOCK B3 WITH FRAME TITLE TEXT-B03.
SELECT-OPTIONS: SO_MATE FOR MARA-MATNR NO INTERVALS NO-EXTENSION MODIF ID MAT.
SELECTION-SCREEN END OF BLOCK B3.

*———————————————————————–*
*AT SELECTION-SCREEN.
*———————————————————————–*

AT SELECTION-SCREEN OUTPUT.

LOOP AT SCREEN.

IF SCREEN-GROUP1 = ‘MAT’.
CASE R_MATE.
WHEN ‘X’.
SCREEN-ACTIVE = 1.
WHEN OTHERS.
SCREEN-ACTIVE = 0.
ENDCASE.
ELSEIF SCREEN-GROUP1 = ‘CLI’.
CASE R_MATE.
WHEN ‘X’.
SCREEN-ACTIVE = 0.
WHEN OTHERS.
SCREEN-ACTIVE = 1.
ENDCASE.
ENDIF.

MODIFY SCREEN.

ENDLOOP.

miércoles, 20 de mayo de 2009

Crear un alv con columnas dinamicas

Ejemplo de creación de un ALV con columnas dinámicas generado mediante una tabla interna de columnas dinámicas.

REPORT ZPRUEBA_ALV_DINAMICO.
 
TYPE-POOLS: slis.
 FIELD-SYMBOLS: <t_dyntable> TYPE STANDARD TABLE, " Dynamic internal table name
  <fs_dyntable>, " Field symbol to create work area
  <fs_fldval> type any. " Field symbol to assign values
 
PARAMETERS: p_cols(5) TYPE c, " Input number of columns
  p_rows(5) TYPE c.
DATA: t_newtable TYPE REF TO data,
  t_newline TYPE REF TO data,
  fs_fldcat TYPE slis_t_fieldcat_alv,
  t_fldcat TYPE lvc_t_fcat,
  wa_it_fldcat TYPE lvc_s_fcat,
  wa_colno(2) TYPE n,
  wa_flname(5) TYPE c.


* Create fields .
  DO p_cols TIMES.
  CLEAR wa_it_fldcat.
  move sy-index to wa_colno.
  concatenate 'COL'
  wa_colno
  into wa_flname.
  wa_it_fldcat-fieldname = wa_flname.
  wa_it_fldcat-datatype = 'CHAR'.
  wa_it_fldcat-intlen = 10.
  APPEND wa_it_fldcat TO t_fldcat.
  ENDDO.

* Create dynamic internal table and assign to FS


  CALL METHOD cl_alv_table_create=>create_dynamic_table
  EXPORTING
  it_fieldcatalog = t_fldcat
  IMPORTING
  ep_table = t_newtable.
  ASSIGN t_newtable->* TO <t_dyntable>.
* Create dynamic work area and assign to FS
  CREATE DATA t_newline LIKE LINE OF <t_dyntable>.
  ASSIGN t_newline->* TO <fs_dyntable>.


************************
** Populate internal table

************************


  DATA: fieldname(20) TYPE c.
  DATA: fieldvalue(10) TYPE c.
  DATA: index(3) TYPE c.
  DATA: index2(3) TYPE c.
  DO p_rows TIMES.
  index2 = sy-index.
  DO p_cols TIMES.
  index = sy-index.
  MOVE sy-index TO wa_colno.
  CONCATENATE 'COL'
  wa_colno
  INTO wa_flname.
* Set up fieldvalue

  CONCATENATE 'VALUE ' index '-' index2 INTO
  fieldvalue.
  CONDENSE fieldvalue NO-GAPS.
  ASSIGN COMPONENT wa_flname
  OF STRUCTURE <fs_dyntable> TO <fs_fldval>.
  <fs_fldval> = fieldvalue.
  ENDDO.


* Append to the dynamic internal table
  APPEND <fs_dyntable> TO <t_dyntable>.
  ENDDo.


 

************************
** Display internal table
************************


 
DATA: wa_cat LIKE LINE OF fs_fldcat.
  DO p_cols TIMES.
  CLEAR wa_cat.
  MOVE sy-index TO wa_colno.
  CONCATENATE 'COL'
  wa_colno
  INTO wa_flname.
  wa_cat-fieldname = wa_flname.
  wa_cat-seltext_s = wa_flname.
  wa_cat-outputlen = '10'.
  APPEND wa_cat TO fs_fldcat.
  ENDDO.

* Call ABAP List Viewer (ALV)

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
  EXPORTING
  it_fieldcat = fs_fldcat
  TABLES
  t_outtab = <t_dyntable>.





martes, 19 de mayo de 2009

Manejo de Errores con Try – Catch

ABAP puede controlar errores para evitar dumps con TRY-CATCH (muy usando en JAVA)

Ejemplo :
*Al Insertar registros en la table ZPEDIDOS si hay algún tipo de error de SQL  manejo *la excepción con un mensaje de advertencia. 
  TRY.
      INSERT INTO ZPEDIDOS VALUES WA_ZPEDIDOS  
      CATCH CX_SY_DYNAMIC_OSQL_ERROR.
      MESSAGE ‘Error al actualizar la tabla ZPEDIDOS’ TYPE ‘I’.
  ENDTRY.


lunes, 18 de mayo de 2009

Leer datos de memoria de un dynpro

Este ejemplo lee los datos de memoria de la grilla del dynpro de posiciones del pedido de compra (ME22N), funciona muy bien en user exit.

es adaptable a cualquier dynpro tanto estandard como Z.

DATA char(50) VALUE '(SAPLMEPO)POT[]'.
DATA itab LIKE bekpo OCCURS 0 WITH HEADER LINE.
FIELD-SYMBOLS <f1> TYPE ANY.

ASSIGN (char) TO <f1>.
itab[] = <f1> .
LOOP AT itab.
itab-loekz = 'S'.
MODIFY ITAB.
ENDLOOP.
<f1> = itab[].