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[].


Debloquear Editor (SE38)

Cuando necesitamos modificar un programa que tiene el bloqueo de editor activado? Por lo general, le pedimos a quien lo haya activado, que lo libere. El problema es que por lo general (casi siempre) esa persona ya no está en el proyecto o en el lugar donde estamos. 

En ese caso, existe un truco para poder quitar el bloqueo. Desde la SE16, ingresamos a la tabla PROGDIR. En el campo NAME ponemos el nombre del programa que queremos desbloquear. Al traer los registros que cumplen con nuestra selección (F8) aparecerá un registro con el nombre de nuestro programa. Lo seleccionamos y presionamos el lapiz para modificar el registro. (El famoso "palo hache"...) Borramos la X que hay en el campo EDTX (que indica que está activado el bloqueol de editor) y grabamos.

Listo! Ahora podemos modificar el programa normalmente.

Barra de Progreso (ejemplo clasico)

La barra de Progreso es muy util cuando se quiere informar al usuario que un proceso esta tardando , pero que pronto llegara a su fin... (para que no pierda la paciencia...jejej).

internamente sirve tambien para evitar dumps por time out.

Aqui va un ejemplo :

*&**********************************************************************

*& DESCRIPTION: Demonstrate Progress indicator *
*&**********************************************************************

REPORT zprogind.

TYPES: BEGIN OF t_mara,
  matnr LIKE mara-matnr,
  END OF t_mara.
DATA: it_mara TYPE STANDARD TABLE OF t_mara INITIAL SIZE 0,
  wa_mara TYPE t_mara.
DATA: mara_lines TYPE i,
  gd_percent TYPE i.



START-OF-SELECTION.

  SELECT matnr
  INTO TABLE it_mara
  FROM mara.

  CHECK sy-subrc EQ 0.
  mara_lines = sy-dbcnt.
  clear: gd_percent.

  LOOP AT it_mara INTO wa_mara.
  PERFORM progress_bar USING 'Retrieving data...'(001)
  sy-tabix
  mara_lines.
* WAIT UP TO 2 SECONDS.
  ENDLOOP.

  WRITE: /20 'Report is "Complete" OK'.


*&---------------------------------------------------------------------*
*& Form PROGRESS_BAR
*&---------------------------------------------------------------------*

FORM progress_bar USING p_value
  p_tabix
  p_nlines.

  DATA: w_text(40),
  w_percentage TYPE p,
  w_percent_char(3).

  w_percentage = ( p_tabix / p_nlines ) * 100.
  w_percent_char = w_percentage.
  SHIFT w_percent_char LEFT DELETING LEADING ' '.
  CONCATENATE p_value w_percent_char '% Complete'(002) INTO w_text.

* This check needs to be in otherwise when looping around big tables
* SAP will re-display indicator too many times causing report to run

* very slow. (No need to re-display same percentage anyway)

  if w_percentage gt gd_percent or p_tabix eq 1.

  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
  EXPORTING
  percentage = w_percentage
  text = w_text.
  gd_percent = w_percentage.
  endif.
endform. 

Seleccion de datos a una tabla interna

Para completar todos los datos (o parte de ellos) a una tabla interna es bueno tener a mano este codigo :

select [campos o asterisco] into corresponding
  fields of table [tabla interna] from [tabla sap]
  where [opciones where].