Archivo

Posts Tagged ‘ABAP’

Nuevo SAP GUI 7.5

Noticia: SAP liberó el nuevo GUI 7.50

El 04.05.2017 SAP liberó la versión GUI 7.50, disponible para descargar e instalar para todos los clientes.
Algunas de las características de esta nueva versión son:

– Mayor vida útil para SAP GUI, ya que está desarrollado con Visual Studio 2013
– Selección de colores por cliente / sistema con Blue Crystal Theme
– Soporte productivo para las características de SAP Screen Personas 3.0

Las nuevas características se mencionan en las siguientes notas:

2417687 – New features in SAP GUI for Windows 7.50

147519 – Maintenance strategy / deadlines for SAP GUI

Para aquellos que no tienen acceso a SAP Service Marketplace, se adjunta link: http://www.sabitlink.com/index.php/l/jc

Categorías:Otras Etiquetas: , , , ,

3 trucos ABAP para programar menos

Caso: Se enumeran algunos trucos para reducir el tiempo que se tarda programando.

Solución:

Truco 1: Armar estructuras utilizando el botón “MODELO”.

Casi siempre usamos estructuras para nuestros reportes y se pierde mucho tiempo en agregar los campos tipeándolos, veamos este trick usando el “MODELO”, también se pueden ver otras opciones ahí mismo.

Y el resultado final:

2. Copy+Paste de datos en columna

Si nos gusta crear una estructura desde el diccionario y luego completar con el texto TYPE manualmente, aquí un truco:

Seleccionamos los campos para pegarlos en nuestro programa:

He aquí el truco! Usamos ALT+drag and drop del mouse para seleccionar la info y trabajar con ella.

Por ejemplo me traigo los TYPES del punto anterior….o selecciono los tipos de datos y los elimino todos de una vez!

Para eliminar igual, con CTRL+X (cortar) o Suprimir (delete).

3. Uso del TAB para proponer texto personalizado.

Ya sabemos que el TAB nos ayuda a proponernos instrucciones, pero podemos agregar código nuestro? Si, veamos donde: el editor ABAP, en la esquina inferior derecha hay un ícono, lo presionamos.

Ahí en Modelos de códigos podemos ver los actuales y crearnos nuevos, por ejemplo:

Ahora, ya en el código:

Nos aparece el código ingresado

Categorías:ABAP/4 Etiquetas: , , , , , , ,

IW38 – Campo de cliente en estructura RIHAUFK_LIST no aparece en ALV

Caso: En la IW38, si tenemos en la estructura RIHAUFK_LIST creada una estructura append con campos de cliente y éstos no comienzan con Z, no aparecen en el ALV de resultados.

En la IW38:

Solución: Usamos la BADI BADI_EAM_SINGLELEVEL_LIST, método CHANGE_FIELD_CATALOG, borrando el valor del campo CS_FIELDCATALOG-TECH, tal como indica la nota 1509429 – Customer-defined fields are not displayed in all PM lists after upgrade

1. Por la SE18, presionamos VISUALIZAR:

2. Por la SE19 creamos una copia del QNAO_SFWS_SC_SIGLELEVEL_LIST:

3. Ingresamos a modificar el objeto recién copiado:

4. Modificamos los tildes para activar la ampliación luego y vamos a “Clase que implementa”:

5. Tomamos la clase que implementa y hacemos una copia Z de ella para poder editarla:

Para ello le agregamos una Z adelante y presionamos ENTER:

Ahora con la nueva clase Z, hacemos click en el método CHANGE_FIELD:

Agregamos el código según lo que indica la nota de SAP:

Finalmente volvemos hacia atrás y agregamos el reporte de la IW38 al filtro para visualización:

Finalmente activamos. Si volvemos a la SE18, veremos que ahora aparece implementado:

Finalmente en la IW38 validamos:

Links: 1509429 – Customer-defined fields are not displayed in all PM lists after upgrade

SU53 – Obtener del BUFFER errores de autorización

Caso: se solicita obtener los errores de autorización del usuario, tal cual cuando se ejecuta la SU53.

Solución: No encontré una solución perfecta. De lo que pude investigar fue “simular” la SU53, obteniendo desde el BUFFER del usuario los resultados.

La SU53, al ser ejecutada, graba el último error de autorización en la tabla USR07. Pero sólo guarda el último, por lo cual una opción sería ejecutar un JOB (creándolo desde el mismo usuario) para obtener el buffer y así ir guardando cada X tiempo los errores de autorización leyéndolos desde el BUFFER, sin tener que ejecutar la SU53.

  1. Les paso esta nota que aclara un poco el tema: http://solveissue.com/note?id=1974803
  2. El programa en cuestión es el siguiente:
REPORT  zleer_su53.
 
DATA:   BEGIN OF usr07key,
          objct LIKE usr07-objct,
          fiel0 LIKE usr07-fiel0,
          fiel1 LIKE usr07-fiel0,
          fiel2 LIKE usr07-fiel0,
          fiel3 LIKE usr07-fiel0,
          fiel4 LIKE usr07-fiel0,
          fiel5 LIKE usr07-fiel0,
          fiel6 LIKE usr07-fiel0,
          fiel7 LIKE usr07-fiel0,
          fiel8 LIKE usr07-fiel0,
          fiel9 LIKE usr07-fiel0,
        END OF usr07key.
 
DATA:   BEGIN OF usr07val1,
          val01 LIKE usr07-val01,
          val02 LIKE usr07-val01,
          val03 LIKE usr07-val01,
          val04 LIKE usr07-val01,
          val05 LIKE usr07-val01,
          val06 LIKE usr07-val01,
        END OF usr07val1.
 
DATA:   BEGIN OF usr07val2,
          val07 LIKE usr07-val01,
          val08 LIKE usr07-val01,
          val09 LIKE usr07-val01,
          val10 LIKE usr07-val01,
        END OF usr07val2.
 
DATA:   g_buffer_method(10),
        usr07             TYPE usr07.
 
 
CALL 'C_SAPGPARAM'
     ID 'NAME' FIELD 'auth/new_buffering'
     ID 'VALUE' FIELD g_buffer_method.
 
GET PARAMETER ID 'XU1' FIELD usr07key.                      "#EC EXISTS
GET PARAMETER ID 'XU2' FIELD usr07val1.                     "#EC EXISTS
GET PARAMETER ID 'XU7' FIELD usr07val2.                     "#EC EXISTS
 
CLEAR usr07.
usr07-bname = sy-uname.
MOVE-CORRESPONDING usr07key  TO usr07.
MOVE-CORRESPONDING usr07val1 TO usr07.
MOVE-CORRESPONDING usr07val2 TO usr07.
 
MOVE sy-datum TO usr07-cdate.
MOVE sy-uzeit TO usr07-ctime.
 
WRITE / : usr07-bname.
WRITE / : usr07-objct.
WRITE / : usr07-fiel0.
WRITE / : usr07-fiel1.
WRITE / : usr07-VAL01.

3. También encontré una transacción ZSU53 que puede servirles, lo que hace es generar el error de autorización y muestra qué perfiles necesita el usuario para cumplir con dicha autorización:

http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/202d833a-79ae-2c10-e4a7-d51218a7efb4?QuickLink=index&overridelayout=true&45629732722609

https://code.google.com/p/zsu53/

4. También encontré una BAPI que ejecuta en fondo la SU53 para obtener en un texto el resultado: http://searchsap.techtarget.com/tip/BAPI-to-retrieve-Check-Values-like-SU53-result

Función para validar RUT (Documento de Identidad en Chile)

Caso: se busca crear una función que valide el RUT de una persona/empresa

Solución: se crea la siguiente función:

FUNCTION zvalidar_rut.
*"----------------------------------------------------------------------
*"*"Interfase local
*"  IMPORTING
*"     REFERENCE(KUNNR) TYPE  ICNUM
*"  EXPORTING
*"     REFERENCE(RESP) TYPE  SY-SUBRC
*"     REFERENCE(RUTHIGH) TYPE  ICNUM
*"     REFERENCE(RUTLOW) TYPE  ICNUM
*"     REFERENCE(RINGLOW) TYPE  ICNUM
*"----------------------------------------------------------------------
 
  DATA: rut      TYPE char50, 
		rut_aux  TYPE char50, 
		rut_cort TYPE char50,
		dv(01)   TYPE c, dv_aux TYPE c,
		nmax     TYPE i, nroc TYPE i,
		suma     TYPE i, contador TYPE i,
		long     TYPE i,
		kunnr2   TYPE kna1_bf-stcd1.
 
  rut = kunnr.
  TRANSLATE rut USING '- '.
  CONDENSE rut NO-GAPS.
 
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
    EXPORTING
*     input  = kunnr
      input  = rut
    IMPORTING
      output = rut.
 
  long =  STRLEN( rut ).
 
  IF long = 8.
    CONCATENATE rut+0(7) '-' rut+7(8) INTO rut.
  ENDIF.
 
  IF long = 9.
    CONCATENATE rut+0(8) '-' rut+8(9) INTO rut.
  ENDIF.
 
  TRANSLATE rut TO UPPER CASE. CONDENSE rut NO-GAPS.
 
  * Quito caracteres no correspondientes
  long = STRLEN( rut ). contador = 0. resp = 0.
  IF long < 2.
    resp = 4.
  ENDIF.
  CHECK long >= 2.
  DO long TIMES.
    IF rut+contador(01) CO '0123456789Kk'.
      CONCATENATE rut_aux rut+contador(01) INTO rut_aux.
      ringlow = rut_aux.
    ENDIF.
    ADD 1 TO contador.
  ENDDO.
 
  rut = rut_aux. CONDENSE rut NO-GAPS.
 
  IF NOT ( rut IS INITIAL ).
    long = STRLEN( rut ). long = long - 1.
    dv = rut+long(1). nmax = long - 1.
    rut_aux = rut+0(long).
    contador = 2.
    DO long TIMES.
      nroc = rut_aux+nmax(01).
      suma = suma + ( nroc * contador ).
      nmax = nmax - 1. contador = contador + 1.
      IF contador > 7. contador = 2. ENDIF.
    ENDDO.
    suma = 11 - suma MOD 11.
    IF suma = 10.
      dv_aux = 'K'.
    ELSEIF suma > 10.
      dv_aux = '0'.
    ELSE.
      dv_aux = suma.
    ENDIF.
    IF dv NE dv_aux.
      resp = 4.
    ENDIF.
  ELSE.
    resp = 4. "Incorrecto.
  ENDIF.
  CONCATENATE rut_aux '-' dv_aux INTO ruthigh.
  CONCATENATE rut_aux dv_aux INTO rutlow.
 
* Validar Guión XL ( ALT 196 )
* Validar Rut contenga caracteres válidos
 
  kunnr2 = kunnr.
 
  CALL FUNCTION 'TAX_NUMBER_CHECK'
         EXPORTING
           country                  = 'CL'
*          NATURAL_PERSON_FLAG      = 'X'
*          REGION                   = ' '
*          STKZU                    = ' '
          tax_code_1                = kunnr2
*         TAX_CODE_2                = ' '
*         TYPE_OF_TAX_CODE_1        = ' '
*         TAX_CODE_3                = ' '
*         TAX_CODE_4                = ' '
        EXCEPTIONS
          not_valid                 = 1
          different_fprcd           = 2
          OTHERS                    = 3
                 .
  IF sy-subrc <> 0.
    resp = 4.
  ENDIF.
 
* Validar como máximo 10 caracteres
  long =  STRLEN( kunnr ).
 
  IF long > 10.
    resp = 4.
  ENDIF.
 
ENDFUNCTION.

Ayuda de búsqueda en dynpro para Fecha-Hora

Caso: Se desea agregar un matchcode en campos de fecha y hora de una dynpro.

Solución: En el ejemplo, se utilizan las ayudas de búsqueda CACS_CALENDAR y SRM_F4_UZEIT para mostrar el matchcode correspondiente a cada caso.

1. Para la fecha

Quedando al presionar el matchcode:

2. Para la hora

Presionando el matchcode muestra:

RSSCD100 – Ver datos de Tablas CDHDR CDPOS

Caso: Se desea visualizar la fecha y hora de un pedido de compras.

Solución: Utilizamos la transacción RSSCD100, para ver el contenido de las tablas CDHDR y CDPOS

Fuentes:

http://www.sap123.com/a/47/

http://sap.ittoolbox.com/groups/technical-functional/sap-log-mm/how-to-get-data-from-table-cdpos-cdhdr-4526724

Categorías:ABAP/4 Etiquetas: , ,

Listbox en SELECT-OPTION

Caso: Se desea poner un listobox o campo de selección en un SELECT-OPTION.

Solución: Utilizamos el siguiente código.

REPORT  zprueba_abap.
TYPE-POOLS: vrm .
 
DATA: g_lista   TYPE vrm_values,
      g_name   TYPE vrm_id,
      g_value  LIKE LINE OF g_lista.
 
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
PARAMETERS    :   s_lista TYPE c LENGTH 30 AS LISTBOX VISIBLE LENGTH 30.
SELECTION-SCREEN END OF BLOCK b1.
 
AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_lista.
  PERFORM armar_listbox.
 
*&---------------------------------------------------------------------*
*&      Form  armar_listbox
*&---------------------------------------------------------------------*
FORM armar_listbox.
  REFRESH g_lista.
  g_name = 'S_LISTA'.
  g_value-key = '1'. g_value-text = 'Santiago'.
  APPEND g_value TO g_lista.
  g_value-key = '2'. g_value-text = 'Viña del Mar'.
  APPEND g_value TO g_lista.
  g_value-key = '3'. g_value-text = 'Valparaíso'.
  APPEND g_value TO g_lista.
  g_value-key = '4'. g_value-text = 'San Felipe'.
  APPEND g_value TO g_lista.
  g_value-key = '5'. g_value-text = 'Con Con'.
  APPEND g_value TO g_lista.
  g_value-key = '6'. g_value-text = 'San Javier'.
  APPEND g_value TO g_lista.
 
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = g_name
      values = g_lista.
 
ENDFORM.                    "armar_listbox

Screenshot_1

Categorías:ABAP/4 Etiquetas: , ,

Color en columna de ALV

Caso: Se desea ponerle color a una columna de un ALV.

Solución: Para pintar una columna, podemos utilizar, en el fieldcat del ALV el campo EMPHASIZE, por ejemplo:

lw_fieldcat-emphasize = ‘C500’.

En el siguiente programa podemos listar las distintas posibilidades de color que hay.

REPORT  zprueba_color_alv.
 
TYPE-POOLS: slis.
 
* Tabla interna de prueba (se agrega el campo CELLCOLORS.
TYPES: BEGIN OF tty_salida,
        cod_color             TYPE char4,
        cellcolors            TYPE lvc_t_scol,
      END OF   tty_salida.
 
TYPES: ty_salida   TYPE STANDARD TABLE OF tty_salida.
 
DATA:  t_salida       TYPE ty_salida,
       wa_salida      TYPE LINE OF ty_salida,
       i_fieldcat     TYPE slis_t_fieldcat_alv,
       r_layout       TYPE slis_layout_alv,
       lv_color       TYPE numc1,
       lv_intensidad  TYPE numc2,
       lv_contador    TYPE numc3,
       lv_i           TYPE c,
       lv_j           TYPE c,
       lv_k           TYPE c.
 
INITIALIZATION.
* Agrego los códigos de color
  lv_color      = '1'.
  WHILE ( lv_color <= 7 ).
    lv_intensidad = '00'.
    WHILE ( lv_intensidad < 20 ).
      CONCATENATE 'C' lv_color lv_intensidad INTO wa_salida-cod_color.
      APPEND wa_salida TO t_salida.
      ADD 1 TO lv_intensidad.
 
    ENDWHILE.
    ADD 1 TO lv_color.
  ENDWHILE.
 
* CARGO FIELDCAT.
  REFRESH i_fieldcat.
  PERFORM f_init_fieldcat     TABLES i_fieldcat.
 
* LAYOUT, AGREGO COLORES DEPENDIENDO DE LA CELDA
  CLEAR r_layout.
  PERFORM f_init_layout       CHANGING r_layout.
 
* ALV GRID
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program      = sy-repid
      i_callback_user_command = 'F_USER_COMMAND_01'
      is_layout               = r_layout
      it_fieldcat             = i_fieldcat[]
    TABLES
      t_outtab                = t_salida
    EXCEPTIONS
      program_error           = 1
      OTHERS                  = 2.
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.
 
*&---------------------------------------------------------------------*
*&      Form  f_init_fieldcat
*&---------------------------------------------------------------------*
FORM f_init_fieldcat  TABLES ptc_fieldcat TYPE slis_t_fieldcat_alv.
 
  DATA: r_fieldcat  TYPE slis_fieldcat_alv,
        l_pos       TYPE i VALUE 0.
 
  CLEAR r_fieldcat.
  l_pos = l_pos + 1.
  r_fieldcat-col_pos       = l_pos.
  r_fieldcat-fieldname     = 'COD_COLOR'.
  r_fieldcat-tabname       = 'T_SALIDA'.
  r_fieldcat-seltext_l     = 'Material'.
  APPEND r_fieldcat TO ptc_fieldcat.
 
ENDFORM.                    " f_init_fieldcat
 
*&---------------------------------------------------------------------*
*&      Form  f_init_layout
*&---------------------------------------------------------------------*
FORM f_init_layout  CHANGING playout TYPE slis_layout_alv.
* Variables
  DATA l_color               TYPE lvc_s_scol.
 
 
* Field-Symbols
  FIELD-SYMBOLS <fs_report>  LIKE LINE OF t_salida.
 
* ASIGNAMOS EL CAMPO CELLCOLORS AL LAYOUT
  playout-coltab_fieldname  = 'CELLCOLORS'.
 
  UNASSIGN <fs_report>.
 
  LOOP AT t_salida ASSIGNING <fs_report>.
    lv_i = <fs_report>-cod_color+1(1).
    lv_j = <fs_report>-cod_color+2(1).
    lv_k = <fs_report>-cod_color+3(1).
 
    l_color-fname     = 'COD_COLOR' .
    l_color-color-col = lv_i. "COLOR
    l_color-color-int = lv_j. "INTENSIDAD
    l_color-color-inv = lv_k. "INVERSO
    APPEND l_color TO <fs_report>-cellcolors.
 
  ENDLOOP.
ENDFORM.                    " f_init_layout
 

 

Exportar tabla con columnas a Excel

Caso: Se desea exportar a Excel el contenido de una tabla SAP, incluyendo como cabecera el nombre de cada columna (la descripción de la misma, no el nombre técnico del campo).

Solución: Se solicita el nombre del archivo Excel y luego se extrae de la tabla indicada deseada (en este caso la T001) las cabeceras de columna y luego su contenido.

Como mejora podría hacerse un PARAMETER para solicitar la tabla a extraer y otro para indicar el archivo Excel…

REPORT  zprueba_formato.
TYPE-POOLS abap.
 
CONSTANTS: c_tabla    TYPE tabname VALUE 'T001',        " Tabla a listar
           c_t_salida TYPE tabname VALUE 'LT_SALIDA'.   " Tabla de salida
 
DATA: lt_campos   TYPE STANDARD TABLE OF dd03l WITH HEADER LINE,
      lt_rollname TYPE STANDARD TABLE OF dd04t WITH HEADER LINE,
      lt_cabeceras TYPE STANDARD TABLE OF fieldnames,
      wa_cabeceras TYPE fieldnames.
 
DATA: lt_salida     TYPE TABLE OF t001,           " Tabla a listar
      wa_salida     TYPE t001,                    " Tabla a listar
      lc_tabname    TYPE tabname,
      lc_tabint     TYPE tabname,
      lv_encoding   TYPE abap_encoding,
      lc_archivo    TYPE string,
      lv_file       TYPE string.
 
FIELD-SYMBOLS:  <fs_tab> TYPE STANDARD TABLE,
                <fs_it> TYPE STANDARD TABLE.
 
REFRESH: lt_campos[],
         lt_rollname[],
         lt_cabeceras[].
 
lv_encoding = '4103'.
 
PERFORM seleccionar_archivo CHANGING lv_file.
lc_tabname = c_tabla.
lc_tabint  = c_t_salida.
 
ASSIGN (lc_tabint) TO <fs_it>.
REFRESH <fs_it>.
SELECT *
  INTO TABLE <fs_it>
  FROM (lc_tabname).
 
*********************
* Cabecera
SELECT tabname position fieldname rollname
  FROM dd03l
  INTO CORRESPONDING FIELDS OF TABLE lt_campos
 WHERE tabname EQ lc_tabname.
 
SELECT rollname scrtext_s scrtext_m scrtext_l
  INTO CORRESPONDING FIELDS OF TABLE lt_rollname
  FROM dd04t
   FOR ALL ENTRIES IN lt_campos
 WHERE rollname = lt_campos-rollname
   AND ddlanguage = sy-langu.
 
SORT lt_campos BY position.
DELETE lt_campos WHERE fieldname(1) = '.'.
 
* Obtengo las cabeceras de columna y las agrego en lt_cabeceras para exportarlas
CLEAR wa_cabeceras.
LOOP AT lt_campos.
  READ TABLE lt_rollname WITH KEY rollname = lt_campos-rollname.
  CLEAR wa_cabeceras.
  wa_cabeceras-fieldname = lt_rollname-scrtext_m.
  APPEND wa_cabeceras TO lt_cabeceras.
ENDLOOP.
 
lc_archivo = lv_file.
CALL FUNCTION 'GUI_DOWNLOAD'
  EXPORTING
    filename              = lc_archivo
    filetype              = 'DAT'
    write_field_separator = 'X'
    write_bom             = 'X'
    codepage              = lv_encoding
  TABLES
    data_tab              = <fs_it>
    fieldnames            = lt_cabeceras.
 
 
 
*&---------------------------------------------------------------------*
*&      Form  seleccionar_archivo
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM seleccionar_archivo CHANGING po_file.
 
  DATA: v_usr_action   TYPE i,
        v_path         TYPE string,   " directorio del archivo
        v_fullpath     TYPE string,   " ruta del arhivo completa
        v_filename     TYPE string.   " nombre del archivo
 
  CLEAR: v_usr_action,
         v_path,
         v_fullpath,
         v_filename.
 
  CALL METHOD cl_gui_frontend_services=>file_save_dialog
    EXPORTING
      initial_directory    = 'C:\'
      file_filter          = '*.XLS'
      default_extension    = 'XLS'
    CHANGING
      filename             = v_filename
      path                 = v_path
      fullpath             = v_fullpath
      user_action          = v_usr_action
    EXCEPTIONS
      cntl_error           = 1
      error_no_gui         = 2
      not_supported_by_gui = 3
      OTHERS               = 4.
 
  IF sy-subrc IS INITIAL.
    IF v_usr_action EQ cl_gui_frontend_services=>action_ok.
      MOVE v_fullpath TO po_file.
    ENDIF.
  ENDIF.
 
ENDFORM.                    "seleccionar_Archivo