jueves, 20 de noviembre de 2008

Como encontrar una BADI

Como encontrar la BADI que necesitamos

Existen varios métodos para encontrar la BADI que necesitamos pero nosotros vamos a explicar un método basado en la transacción ST05 (Performance Analysis).

Esta técnica de análisis se basa en el echo de que todas las BADIS’s están registradas en tablas de SAP. Por lo que en cada llamada a una Badi el sistema pasa por estas tablas. Las tablas de las BADIS son las siguientes SXS_INTER, SXC_EXIT, SXC_CLASS y SXC_ATTR. A estas tablas Sap siempre accede mediante las vistas V_EXT_IMP y V_EXT_ACT. Por lo que estas vistas (T: SE11) serán la base de nuestro análisis.

EJEMPLO:

Supongamos que quiero saber que BADIS son llamadas en la transacción “Maintain Business Partners” código BT

PASOS:

1.- Primero chequeamos que ningún otro usuario (T:SM04) o jobs en fondo (T: SM50) están usando el mismo usuario que tú.

2.- Nos vamos a la transacción ST05 (Performance Analysis) y marcamos el flag "Buffer trace", después pulsamos el botón “Activate Trace “, para activar el Trace.

3.- Inmediatamente después ya que el sistema está ya “Grabando” nos vamos a la transacción BT que queremos analizar y pulsamos el boton "Organization" completando los campos con los siguientes datos de prueba:


Al finalizar pulsamos el boton salvar.

4.- Volvemos a la ventana donde teníamos abierta la ST05 y pulsamos el botón "Deactivate Trace" para finalizar el trace y pulsamos sobre el botón "Display Trace", entonces el popup "Set Restrictions for Displaying Trace" aparecerá.

5.- Ahora vamos a filtrar el Trace con los objetos: V_EXT_IMP y V_EXT_ACT. Que son nuestras vistas.


Pulsamos el botón "Copy (FCool" , Fill Operations: OPEN y pulsamos el botón "Enter"

ANALISIS DE LOS RESULTADOS

Obtendremos un listado parecido a este que interpretaremos de la siguiente manera:




Todas las “interface class names” de las vista V_EXT_IMP comienzan con IF_EX_. Este es el prefijo estándar de Sap para las “ BAdI class interfaces “. El nombre de la BAdI está después de este IF_EX_.
Es decir el nombre de la BADi para IF_EX_ADDR_LANGU_TO_VERS es ADDR_LANGU_TO_VERS.

En la transacción SE18 puedes ver la definición de la BADI.


Aconsejamos durante la realización del Trace no ejecutar ninguna otra transacción o comando que no sean los propios de análisis si queremos obtener unos resultados lo más limpios posibles. Bien pues ya podéis realizar una función que propiamente es de analista .

No obstante podemos ver una lista de las BADI’s disponibles haciendo lo siguiente:
- Vamos a la Transacción SE18
- Pulsamos F4 para desplegar el matchcode
- Hacemos click en el icono “Sistema de información”
- Aumentamos el campo “Cant. Máxima aciertos” a 999999
Hacemos click en OK.

Se nos listará de esta forma las BADIS disponibles.

viernes, 27 de junio de 2008

Ventana vertical en SAPScript


En esta entrada explicaremos como crear una ventana vertical en un formulario SapScript. En la imagen aparece resaltada en rojo.
Lo que se debe hacer es lo siguiente:

1. Crear la ventana, con una anchura que solo permita escribir una letra por línea y con la variable con el texto que queremos imprimir.
2. En el programa de control (el que lanza el formulario), inicializaremos la variable anterior con el texto girado de forma que la primera letra sea la última. Por ejemplo, si queremos poner "Barcelona, 06 de mayo de 2008", en nuestra variable tendremos que tener el texto: "8002 ed oyam ed 60 ,anolecraB".
3. Con el software FontCreator (existe una versión de prueba de 30 días) creamos el tipo de letra que queremos utilizar. Para ello, yo he cogido el tipo de letra Arial, porque me interesaba esta tipografia, y la he renombrado a "Rotated". Luego rotamos todas las letras 90º. Este trabajo es un poco laborioso, y si queremos que quede bien tenemos que fijarnos donde alineamos las letras.
4. Instalamos la nueva fuente a SAP mediante la transacción SE73.
5. Creamos un tipo de fuente en el formulario con nuestra fuente, y lo aplicamos a la variable de la ventana vertical, y gualà, ya lo tenemos (mas o menos).
6. Modificamos el interlineado de la ventana vertical hasta que salga a nuestro gusto.

Un problema que encontré era que los espacios salian al lado de la letra precedente, y por lo tanto, el texto vertical estaba todo junto (sin espacios: Barcelona,06demayode2008), para solucionarlo debemos modificar una letra que jamás utilicemos de forma que sea un solo punto de 1x1 px, de forma que la impresora no lo imprima, pero que ocupe un espacio (yo lo he hecho con "_", de esta forma en lugar de escribir "Barcelona, 06 de mayo de 2008", escribimos "Barcelona,_06_de_mayo_de_2008". Debido al tamaño del punto, este no se imprime y el efecto resultante es como si hubieramos puesto un espacio).

Report con ALV

En esta entrada se explica como realizar un ALV. Primero necesitaremos una tabla con los campos que deseamos mostrar en el ALV. A esta tabla la hemos llamado gt_data. La tabla gt_data necesita que el primer campo se llame 'box' y sea de tipo boolean. A continuación esta el código necesario para crear el ALV. Una vez hayamos rellenado la tabla gt_data con los datos a mostrar, llamaremos a la función 'mostrar_alv' y listo. También será necesario crear un status llamado 'STATUS_ALV' con los botones típicos del ALV para ordenar, modificar el layout, hacer sumas, etc.




*&---------------------------------------------------------------------*
*& Include REPORT_TOP
*&---------------------------------------------------------------------*

TYPE-POOLS: slis.


CONSTANTS:
gc_formname_top_of_page TYPE slis_formname VALUE 'TOP_OF_PAGE',
evento_status TYPE slis_formname VALUE 'SET_STATUS',
evento_command TYPE slis_formname VALUE 'USER_COMMAND',
C_NO TYPE C VALUE '',
C_OK TYPE C VALUE 'X'.


DATA: gt_fieldcat TYPE slis_t_fieldcat_alv,
gs_layout TYPE slis_layout_alv,
gs_print TYPE slis_print_alv,
gt_sort TYPE slis_t_sortinfo_alv,
gt_sp_group TYPE slis_t_sp_group_alv,
gt_events TYPE slis_t_event,
g_repid LIKE sy-repid,
gt_list_top_of_page TYPE slis_t_listheader,
p_f2code LIKE sy-ucomm VALUE '&ETA',
g_boxname type c length 3 value 'BOX'.


* Definimos la tabla con los datos de salida, el primer campo debe ser 'box' de tipo 'boolean'
TYPES: BEGIN OF t_data,
box TYPE BOOLEAN,
. . .
end of t_data.




DATA: gt_data TYPE t_data OCCURS 0.





*&---------------------------------------------------------------------*
*& Include REPORT_ALV
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form construir_catalogo_eventos_alv
*&---------------------------------------------------------------------*
FORM construir_catalogo_eventos_alv
USING e03_lt_events TYPE slis_t_event.


DATA: ls_event TYPE slis_alv_event.


CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = e03_lt_events.


READ TABLE e03_lt_events WITH KEY name = slis_ev_top_of_page
INTO ls_event.
IF sy-subrc = 0.
MOVE gc_formname_top_of_page TO ls_event-form.
APPEND ls_event TO e03_lt_events.
ENDIF.


ENDFORM. " construir_catalogo_eventos_alv
*&---------------------------------------------------------------------*
*& Form construir_orden_alv
*&---------------------------------------------------------------------*
FORM construir_orden_alv USING e06_lt_sort TYPE slis_t_sortinfo_alv.


DATA: ls_sort TYPE slis_sortinfo_alv.


ls_sort-fieldname = 'PERNR'.
ls_sort-tabname = 'GT_DATA'.
ls_sort-spos = 1.
ls_sort-up = 'X'.
ls_sort-group = 'UL'.
* ls_sort-subtot = 'X'.
APPEND ls_sort TO e06_lt_sort.


ENDFORM. " construir_orden_alv
*&---------------------------------------------------------------------*
*& Form construir_cabecera_alv
*&---------------------------------------------------------------------*
FORM construir_cabecera_alv USING e04_lt_top_of_page TYPE slis_t_listheader.


DATA: ls_line TYPE slis_listheader,
texto(50) TYPE c,
separador(3) TYPE c.


CLEAR ls_line.
ls_line-typ = 'H'.
ls_line-info = text-001.
APPEND ls_line TO e04_lt_top_of_page.


CLEAR ls_line.
ls_line-typ = 'S'.
ls_line-info = text-002.
APPEND ls_line TO e04_lt_top_of_page.


ENDFORM. " construir_cabecera_alv
*&---------------------------------------------------------------------*
*& Form definir_layout_alv
*&---------------------------------------------------------------------*
FORM definir_layout_alv USING e05_ls_layout TYPE slis_layout_alv.


e05_ls_layout-f2code = p_f2code.
e05_ls_layout-zebra = c_ok.
e05_ls_layout-cell_merge = c_no.
e05_ls_layout-colwidth_optimize = c_ok.
e05_ls_layout-box_fieldname = g_boxname.
e05_ls_layout-no_input = c_no.
e05_ls_layout-no_vline = c_no.
e05_ls_layout-no_colhead = c_no.
CLEAR e05_ls_layout-lights_fieldname.


e05_ls_layout-totals_before_items = c_no.
e05_ls_layout-group_change_edit = c_no.
e05_ls_layout-lights_condense = c_no.
e05_ls_layout-totals_text = 'Totales '.
e05_ls_layout-subtotals_text = c_no.
e05_ls_layout-totals_only = c_no.
e05_ls_layout-key_hotspot = c_no.
e05_ls_layout-detail_popup = c_no.


ENDFORM. " definir_layout_alv
*---------------------------------------------------------------------*
* FORM top_of_page *
*---------------------------------------------------------------------*
FORM top_of_page.


CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
i_logo = 'LOGO_COLOR'
it_list_commentary = gt_list_top_of_page.


ENDFORM. "top_of_page
*---------------------------------------------------------------------*
* FORM set_status *
*---------------------------------------------------------------------*
FORM set_status USING extab TYPE slis_t_extab.


* Si quisieramos excluir funciones del menu principal...
* DATA: fcode LIKE rsmpe-func.
* fcode = '&RNT_PREV'.
* APPEND fcode TO extab.


* SET PF-STATUS 'STATUS_ALV' EXCLUDING extab.




SET PF-STATUS 'STATUS_ALV'.


ENDFORM. "set_status
*---------------------------------------------------------------------*
* FORM user_command *
*---------------------------------------------------------------------*
FORM user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.


CASE r_ucomm.
WHEN 'LOG'.
rs_selfield-refresh = 'X'.
CALL FUNCTION 'MESSAGES_SHOW'
EXPORTING
object = text-012
show_linno = space.
CLEAR r_ucomm.
ENDCASE.


ENDFORM. "user_command
*&---------------------------------------------------------------------*
*& Form construir_catalogo_campos_alv
*&---------------------------------------------------------------------*
FORM construir_catalogo_campos_alv USING e01_lt_fieldcat TYPE slis_t_fieldcat_alv.


DATA: ls_fieldcat TYPE slis_fieldcat_alv.


CONSTANTS: c_tabname LIKE ls_fieldcat-tabname VALUE 'GT_DATA'.


CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'NOMBRE_CAMPO'.
ls_fieldcat-tabname = c_tabname.
ls_fieldcat-seltext_l = text-0017.
APPEND ls_fieldcat TO e01_lt_fieldcat.


CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'NOMBRE_CAMPO'.
ls_fieldcat-tabname = c_tabname.
ls_fieldcat-seltext_l = text-003.
APPEND ls_fieldcat TO e01_lt_fieldcat.


. . .

ENDFORM. " construir_catalogo_campos_alv
*&---------------------------------------------------------------------*
*& Form mostrar_alv
*&---------------------------------------------------------------------*
FORM mostrar_alv.




PERFORM construir_catalogo_eventos_alv USING gt_events[].
PERFORM construir_catalogo_campos_alv USING gt_fieldcat[].
PERFORM construir_cabecera_alv USING gt_list_top_of_page[].
PERFORM definir_layout_alv USING gs_layout.
PERFORM construir_orden_alv USING gt_sort[].


CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program =sy-repid
i_callback_user_command = evento_command
i_callback_pf_status_set = evento_status
i_callback_top_of_page = gc_formname_top_of_page
is_layout = gs_layout
it_fieldcat = gt_fieldcat[]
it_special_groups = gt_sp_group[]
it_sort = gt_sort[]
i_save = 'A'
it_events = gt_events[]
TABLES
t_outtab = gt_data.


ENDFORM. " MOSTRAR_ALV

miércoles, 28 de mayo de 2008

Barra de progreso en un report

A veces es muy útil utilizar una barra de progreso para saber cuando le falta al programa para que finalice. Esto es muy útil para programas que requieren bastante tiempo para ejecutarse debido a que realizan una tarea repetidamente.

Para incluir dicha barra de progreso debemos escribir el siguiente código en nuestro programa:

DESCRIBE TABLE it_data LINES ld_lines.

  LOOP AT it_data.
    PERFORM progress_bar
   USING 'Procesando...'(001)
            sy-tabix
            ld_lines.
    ...
  ENDLOOP.

El código de la rutina 'progress_bar' es el siguiente:

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
INTO w_text SEPARATED BY space.

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