miércoles, 24 de agosto de 2011

Programa ABAP listado de Compras

*Un ejemplo de uso de un ALV que al darle doble click trae las posiciones de un pedido *de compras (lleva un include, esta mas abajo).
REPORT ZPEDIDOS_COMPRAS .
TABLES: EKKO.


*TABLAS
data i_ekko like ekko occurs 0 with header line."cabecera compras
data i_ekpo like ekpo occurs 0 with header line."Posiciones doc compras
data I_eket like eket occurs 0 with header line."repartos del plan entr
data i_ekkn like ekkn occurs 0 with header line."imputacion doc compras
data i_lfa1 like lfa1 occurs 0 with header line."Maestro de proveedores

data begin of i_out occurs 0.
data:
EBELN like EKPO-EBELN,"documento compras
* FRYEAR like CF001-YEARB,"ejercicio
* PERIO like COEPB-PERIO,"periodo
AEDAT like EKKO-AEDAT,"Fecha de creacion del registro
EINDT like EKET-EINDT,"fecha de entrega de posicion
EBELP like EKPO-EBELP,"posicion
* "BNFPO like EKET-BNFPO,"Numero de posicion de la solicitud de
TXZ01 like EKPO-TXZ01,"Texto Breve
MENGE like EKKN-MENGE,"Cantidad
* WEMNG like EKET-WEMNG,"Cantidad entrada de mercancias
* "CANTIDAD PENDIENTE
* OWEMG like RM06A-owemg,"Cantidad Pendiente
MEINS like EKPO-MEINS,"unidad de medida
NETPR like EKPO-NETPR,"Precio neto
LIFNR like EKKO-LIFNR,"Proveedor
NAME1 like LFA1-NAME1,"Nombre del proovedor
NETWR like EKPO-NETWR,"valor neto pedido en moneda de pedido
WAERS like EKKO-WAERS,"Moneda del documento
NTGEW like EKPO-NTGEW,"peso
ORT01 like LFA1-ORT01,"Poblacion
WERKS like EKPO-WERKS."Centro
* ZNETWR like zmiscampos-ZNETWR,"valor entregado
* "IMPORTE PENDIENTE
* OWEWR like RM06A-OWEWR,"valor pendiente entrada de mercancia
* BEDAT like EKKO-BEDAT,"Fecha de documento de compras

* BANFN like EKET-BANFN,"Numero de la solicitud de pedido
* AFNAM like EKPO-AFNAM,"Nombre del solicitante
* SAKTO like EKKN-SAKTO,"Numero de la cuenta de mayor
* KOSTL like EKKN-KOSTL."Centro de coste

* EKKN like EKKN-NETWR,"Valor neto de pedido en mon pedido
* BRTWR like EKPO-BRTWR,"valor bruto pedido en moneda del pedido
*
* KDATB like EKKO-KDATB,"in. periodo de validez
* KDATE like EKKO-KDATE."fin periodo de validez
data end of i_out.
data i_out2 like i_out occurs 0 with header line.
data begin of i_TEMP occurs 0.
data:
EBELN like EKPO-EBELN,"documento compras
* FRYEAR like CF001-YEARB,"ejercicio
* PERIO like COEPB-PERIO,"periodo
AEDAT like EKKO-AEDAT,"Fecha de creacion del registro
EINDT like EKET-EINDT,"fecha de entrega de posicion
* EBELP like EKPO-EBELP,"posicion
* "BNFPO like EKET-BNFPO,"Numero de posicion de la solicitud de
* TXZ01 like EKPO-TXZ01,"Texto Breve
* MENGE like EKKN-MENGE,"Cantidad
* WEMNG like EKET-WEMNG,"Cantidad entrada de mercancias
* "CANTIDAD PENDIENTE
* OWEMG like RM06A-owemg,"Cantidad Pendiente
* MEINS like EKPO-MEINS,"unidad de medida
* NETPR like EKPO-NETPR,"Precio neto
LIFNR like EKKO-LIFNR,"Proveedor
NAME1 like LFA1-NAME1,"Nombre del proovedor
NETWR like EKPO-NETWR,"valor neto pedido en moneda de pedido
WAERS like EKKO-WAERS,"Moneda del documento
NTGEW like EKPO-NTGEW,"peso
ORT01 like LFA1-ORT01,"Poblacion
WERKS like EKPO-WERKS."Centro
* ZNETWR like zmiscampos-ZNETWR,"valor entregado
* "IMPORTE PENDIENTE
* OWEWR like RM06A-OWEWR,"valor pendiente entrada de mercancia
* BEDAT like EKKO-BEDAT,"Fecha de documento de compras

* BANFN like EKET-BANFN,"Numero de la solicitud de pedido
* AFNAM like EKPO-AFNAM,"Nombre del solicitante
* SAKTO like EKKN-SAKTO,"Numero de la cuenta de mayor
* KOSTL like EKKN-KOSTL."Centro de coste

* EKKN like EKKN-NETWR,"Valor neto de pedido en mon pedido
* BRTWR like EKPO-BRTWR,"valor bruto pedido en moneda del pedido
*
* KDATB like EKKO-KDATB,"in. periodo de validez
* KDATE like EKKO-KDATE."fin periodo de validez
data end of i_TEMP.
*VARIABLES
data: ekpo_lines TYPE i,
gd_percent TYPE i.

* ALV
data repname like sy-repid.

SELECTION-SCREEN BEGIN OF BLOCK block1 WITH FRAME TITLE text-001.


SELECT-OPTIONS:
* SO_KOSTL for i_EKKN-KOSTL,"centro de coste
SO_EBELN for i_EKPO-EBELN,"documento compras
SO_AEDAT for ekko-AEDAT obligatory.
SELECTION-SCREEN END OF BLOCK block1.

INCLUDE ZLISTA_COMPRASI.
*INCLUDE ZPEDIDOS_COMPRASI.
at user-command.
break-point.

START-OF-SELECTION.
perform f_trae_datos.
perform f_procesa_datos.
perform f_suma_iguales.
perform f_genera_alv.







*********INCLUDE************(ZLISTA_COMPRASI)
*----------------------------------------------------------------------*
***INCLUDE ZPEDIDOS_COMPRASI .
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form f_trae_datos
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM f_trae_datos.
*traemos las cabeceras de los doc de compras de acuerdo a parametros
Select * from ekko into table i_ekko
where AEDAT in SO_AEDAT
and EBELN in SO_EBELN.
if sy-subrc = 0.
*traemos datos Posiciones de doc compras
Select * from EKPO into table i_ekpo
for all entries in i_ekko
where EBELN = i_ekko-EBELN.
*traemos datos imputacion doc compras
Select * from EKKN into table i_ekkn
for all entries in i_ekko
where EBELN = i_ekko-EBELN.
*traemos datos repartos plan de entregas
Select * from EKET into table i_ekET
for all entries in i_ekko
where EBELN = i_ekko-EBELN.
*traemos datos de maestro de proveedores
Select * from LFA1 into table i_lfa1
for all entries in i_ekko
where lifnr = i_ekko-lifnr.
endif."sy-subrc
ENDFORM. " f_trae_datos
*&---------------------------------------------------------------------*
*& Form f_procesa_datos
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM f_procesa_datos.
describe table i_ekpo lines ekpo_lines.



loop at i_ekpo.
PERFORM progress_bar USING 'Cargando...'(002)
sy-tabix
ekpo_lines.


read table i_ekko with key ebeln = i_ekpo-EBELN.
if sy-subrc = 0.
move-corresponding i_ekko to i_out.
endif.

read table i_ekkn with key ebeln = i_ekpo-EBELN.
if sy-subrc = 0.
move-corresponding i_ekkn to i_out.
endif.

read table i_eket with key ebeln = i_ekpo-EBELN.
if sy-subrc = 0.
move-corresponding i_eket to i_out.
endif.

read table i_lfa1 with key lifnr = i_ekko-lifnr.
if sy-subrc = 0.
move-corresponding i_lfa1 to i_out.
endif.

*i_out-perio = i_eket-EINDT+4(2).
*i_out-FRYEAR = i_eket-EINDT+0(4).
move-corresponding i_ekpo to i_out.
append i_out.
clear i_out.
endloop.

*BORRAMOS LOS QUE NO ESTEN EN EL PARAMETRO CENTRO DE COSTE
*if not SO_KOSTL is initial.
*delete i_out where not kostl in SO_KOSTL.
*endif.
*TRAEMOS LOS CAMPOS
DATA: BEGIN OF vlist OCCURS 0,
filler1(1000) TYPE c,
field1(100) TYPE c,
END OF vlist.

DATA BEGIN OF itab_list OCCURS 0.
INCLUDE STRUCTURE abaplist.
DATA END OF itab_list.

DATA BEGIN OF vlist_s OCCURS 0.
DATA line(100).
DATA END OF vlist_s.
DATA TPOS(1).
data texto(100).
*LOOP A LA TABLA DE SALIDA PARA LLENAR LOS 2 CAMPOS CANTIDAD PENDIENTE
* E IMPORTE PENDIENTE USANDO LA TRANSACCION me2l
*LOOP AT I_OUT.
*clear vlist.
*refresh vlist.
*SUBMIT RM06EL00 AND RETURN
* WITH LISTU = 'BEST'
* WITH S_EBELN = I_OUT-EBELN
* EXPORTING LIST TO MEMORY.
*
*CALL FUNCTION 'LIST_FROM_MEMORY'
* TABLES
* listobject = itab_list
* EXCEPTIONS
* not_found = 4
* OTHERS = 8.
*
*CALL FUNCTION 'LIST_TO_ASCI'
* EXPORTING
* list_index = -1
* TABLES
* listasci = vlist
* listobject = itab_list
* EXCEPTIONS
* empty_list = 1
* list_index_invalid = 2
* OTHERS = 3.
*
**DE LA LISTA QUE TRAE TOMAMOS PARA LA POSICION REQUERIDA LOS CAMPOS
*LOOP AT VLIST.
* condense vlist-filler1.
* split vlist at space into table vlist_s.
* read table vlist_s index 2.
* texto = I_OUT-EBELP.
* if vlist_s-line cs texto.
* tpos = 'X'.
* endif.
* if tpos = 'X'.
* read table vlist_s index 3.
* if vlist_s-line = 'entregar'.
* read table vlist_s index 4.
* perform f_elimina_caracteres using vlist_s-line.
* I_OUT-OWEMG = vlist_s-line.
* read table vlist_s index 6.
* perform f_elimina_caracteres using vlist_s-line.
* I_OUT-OWEWR = vlist_s-line.
*
**EUROS
* if i_out-waers = 'EUR'.
* I_OUT-OWEWR = I_OUT-OWEWR * 10.
* endif.
*
* tpos = ''.
* "valor entregado
* I_OUT-ZNETWR = I_OUT-NETWR - I_OUT-OWEWR.
* modify i_out.
* exit.
* endif.
* endif."X
*
*ENDLOOP.
*ENDLOOP. "I_OUT
ENDFORM. " f_procesa_datos
*&---------------------------------------------------------------------*
*& Form f_genera_alv
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM f_genera_alv.
repname = sy-repid.
PERFORM obt_descrip_campos_tabla USING repname 'I_TEMP'.
PERFORM carac_gen_listado.
PERFORM visualizar_lista TABLES I_TEMP USING 'I_TEMP' repname .
ENDFORM. " f_genera_alv


**------------------------------------------------
** f_elimina_caracteres.
**------------------------------------------------
form f_elimina_caracteres changing texto.
data: len type i, caracter, va type i,texto2(5000) type c.
*creamos tabla interna con los caracteres a eliminar de el archivo
data: begin of i_careli occurs 0,
car,
end of i_careli.
*cuales caracteres queremos quitar =,<,>,~,/,”,’,+,*,|,:,
i_careli-car = ','.append i_careli.
va = 0.

len = strlen( texto ).
while va <= len.

caracter = texto+va(+1).
loop at i_careli.
if i_careli-car = caracter.
caracter = ''.
endif.
endloop.
concatenate texto2 caracter into texto2.
va = va + 1.
endwhile.
texto = texto2.
endform.

*&---------------------------------------------------------------------*
*& Form f_suma_iguales
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM f_suma_iguales.
data suma like i_out-netwr.
data vEBELN like i_out-EBELN.

loop at i_out.
at new EBELN.
vEBELN = i_out-ebeln.
suma = 0.
loop at i_out where EBELN = vEBELN.
suma = suma + i_out-netwr.
endloop.
move-corresponding i_out to i_temp.
i_temp-netwr = suma.
read table i_ekko with key EBELN = VEBELN.
if sy-subrc = 0.
i_temp-aedat = i_ekko-aedat.
endif.
append i_temp.
endat.
endloop.

I_OUT2[] = I_OUT[].
ENDFORM. " f_suma_iguales

*&---------------------------------------------------------------------*
*& 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.
if w_percentage = 100.
w_percentage = 99.
endif.
w_percent_char = w_percentage.
SHIFT w_percent_char LEFT DELETING LEADING ' '.
CONCATENATE p_value w_percent_char '% ' 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.




















































*----------------------------------------------------------------------*
* INCLUDE ZALV *
*----------------------------------------------------------------------*

************************************************************************
* Include ZALV: Subrutinas para listado ALV. *
************************************************************************

* Es necesario incluir este include en el inicio del programa.
* El inicio del código tiene que empezar por STAR-OF-SELECTION, o no
* lo reconocerá.
* IMPORTANTISIMO. Es obligatorio incluir la 1ª form, y la última.

* Listado de Forms.
* 1.- OBT_DESCRIP_CAMPOS_TABLA "Esta form es OBLIGATORIA.

* 2.- CAMB_DESCRIP_CAMPOS_TABLA "Cambia la descrip de cabecera
* 3.- ELIM_CAMPOS_DE_VISUALIZACION"No se visualizan los campos seleccio
* 4.- CARAC_GEN_LISTADO "Da formato al listado
* 5.- ASIGNAR_MONEDA_COLUMNA "Asignamos una campo de moneda
* 6.- ASIGNAR_UNIDAD_MEDIDA "Asignamos una unidad de medida
* 7.- ALV_F4 "Match code para varientes
* 8.- CHEQUEO_VARIANTE_EXISTE "Comprueba que exista la variante
* 9.- ASIGNAR_VARIANTE "Asignamos la variante al listado
* 10.- ENCABEZADO "Llamamos a esta función para inserta
* 11.- ASIGN_O_QUITAR_CAMPO_CLAVE "Asigna o quita la prop. de Campo Cla
* 12.- Indicar_campo_checkbox "Definir una columna como checkbox

* 13.- ASIGNAR_USER_COMMAND "Equivalente a AT USER-COMMAND
* 14.- Asignar_TOP_OF_PAGE "Deberemos crear FORM TOP_OF_PAGE2
* 15.- Asignar_PF_STATUS "Asigna un STATUS a un listado

* 16.- VISUALIZAR_LISTA "Visualizar la lista. OBLIGATORIA
* 17.- Asignar END_OF_PAGE "
* 18.- Opciones de Impresión
* 19.- Asignar_edit_campo "Campo editable en alv
* 20.- Asignar_hotspot "Activa o desactiva el hotspot

* Normalmente como mínimo es necesario este código si la tabla es I_TAB
* repname = sy-repid.
* PERFORM obt_descrip_campos_tabla USING repname 'I_TAB'.
* PERFORM carac_gen_listado.
* PERFORM visualizar_lista TABLES I_TAB USING 'I_TAB' repname .


*$*$ Definición de variables para el listado
TYPE-POOLS: slis.
DATA: "repname LIKE sy-repid ,
layout TYPE slis_layout_alv,
printer TYPE slis_print_alv,
f2code LIKE sy-ucomm VALUE '&ETA',
fieldtab TYPE slis_t_fieldcat_alv,
heading TYPE slis_listheader OCCURS 0 ,
g_save(1) TYPE c VALUE 'A',
fausti LIKE tbsl-faus1, " string de campos obligatorios
event TYPE slis_alv_event OCCURS 0 with header line,
events TYPE slis_alv_event OCCURS 0,
sort TYPE slis_t_sortinfo_alv,
sort_header TYPE slis_sortinfo_alv,
variant LIKE disvariant,
user_command TYPE slis_formname,
status TYPE slis_formname.

CONSTANTS:
formname_top_of_page TYPE slis_formname VALUE 'TOP_OF_PAGE',
formname_end_of_list TYPE slis_formname VALUE 'END_OF_LIST',
formname_user_command TYPE slis_formname VALUE 'USER_COMMAND',
formname_pf_status_set TYPE slis_formname VALUE 'PF_STATUS'.

FIELD-SYMBOLS TYPE slis_fieldcat_alv.

*$*$ Definición de Forms de listado

*__________________________________________Form obt_descrip_campos_tabla
FORM obt_descrip_campos_tabla USING p_repname
p_tablename TYPE slis_tabname.
* Esta es la primera form que se tiene que llamar. Así recogemos
* Los atributos de todos los campos de la tabla interna.
* Importante!!: La tabla interna no se tiene que definir como un data
* referenciado a una estructura type (Si se hace de este modo no
* reconocerá ningún campo). Utilizar siempre:
* Data begin of ..... occurs 0.
* Data end of ......
* No utilizar tampoco: Data: itab type standard table of ...............
REFRESH fieldtab.
CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
EXPORTING
i_program_name = p_repname
i_internal_tabname = p_tablename
i_inclname = p_repname
CHANGING
ct_fieldcat = fieldtab.

ENDFORM.

*_________________________________________FORM Camb_descrip_campos_tabla
FORM camb_descrip_campos_tabla USING p_campo TYPE slis_fieldname
p_descrip.

* Para utilizar esta form previamente tenemos que haber llamado a la
* form obt_descrip_campos_tabla. Tenemos que pasarle el campo de la
* tabla interna y la descripción que queremos que aparezca en la
* cabecera de la columna.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-seltext_l = p_descrip.
* -seltext_m = p_descrip.
* -seltext_s = p_descrip.
* -reptext_ddic = p_descrip.
ENDIF.

ENDFORM.

*______________________________________FORM elim_campos_de_visualizacion
FORM elim_campos_de_visualizacion USING p_campo TYPE slis_fieldname.
* Consigue que un campo clave se pueda quitar de la visualización.
* P. Ej. Mandante.
* Tambien elimina de la visualización cualquier campo que no sea clave.
* Desde dentro del listado estos campos se pueden volver a visualizar.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-key_sel = 'X'.
-no_out = 'X'.
ENDIF.
ENDFORM.
*_______________________________________________Carac. gen. del listado.
FORM carac_gen_listado.
*Esta Form contiene características generales del listado. Si se quieren
*estas mismas llamar a la Form, en caso contrario implementarlas desde
*el programa. La estructura de características generales es 'LAYOUT'.
*En El campo INFO_FIELDNAME se le indica la columna que contiene el
*color para cada registro. Si dicha columna, no tiene valor para algún
*registro, dicho registro tendrá el color standard que le toque.
* El formato que tiene que tener la columa COLOR es:
* 'Cxy':
* C = color (all codes must start with 'C')
* x = color number ('1'-'9')
* y = bold ('0' = off, '1' = on)

*__Indicamos que queremos el listado cebreado
layout-zebra = 'X'.
*__No afecta porque tenemos user-commmand
layout-detail_popup = 'X'.
*__Indicamos que Al hacer doble click el user-command = 'DOBCLICK'.
layout-f2code = 'USER_COMMAND'.
*__Si queremos que al hacer doble click despliegue la ventana desasteris
* layout-f2code = '&ETA'.
layout-info_fieldname = 'COLOR'.
* layout-flexible_key = 'X'. "Permite mover campos clave.
layout-colwidth_optimize = 'X'.
layout-detail_initial_lines = 'X'.
layout-detail_titlebar = 'Información Adicional'. "Titulo popup
layout-totals_only = 'X'.
layout-detail_popup = 'X'.

ENDFORM. " BUILD_LAYOUT

*____________________________________________FORM asignar_moneda_columna
FORM asignar_moneda_columna USING p_columna TYPE slis_fieldname
p_campo_moneda TYPE slis_fieldname.
* En esta form hay que pasar la columna que tiene los importes, y la
* Columna que contiene la moneda para cada registro.
READ TABLE fieldtab WITH KEY fieldname = p_columna ASSIGNING .
IF sy-subrc EQ 0.
-cfieldname = p_campo_moneda.
ENDIF.

ENDFORM.

*_____________________________________________FORM asignar_unidad_medida
FORM asignar_unidad_medida USING p_columna TYPE slis_fieldname
p_campo_moneda TYPE slis_fieldname.
* En esta form hay que pasar la columna que tiene las cantidades, y la
* Columna que contiene la unidad para cada registro.
READ TABLE fieldtab WITH KEY fieldname = p_columna ASSIGNING .
IF sy-subrc EQ 0.
-qfieldname = p_campo_moneda.
ENDIF.

ENDFORM.

*____________________________________________________________Form Alv_F4
FORM alv_f4 USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.

* Esta form devuelve un matchcode con las variantes existentes.
* Tan solo se tiene que poner si se quiere cargar una variante de
* visualización.
* Para poner esta form se tiene que poner:

**** at selection-screen on value-request for p_variante. *****
**** perform alv_f4 using (Nombreprograma) (Variable_variante). *****
variant-report = p_repname.
CALL FUNCTION 'REUSE_ALV_VARIANT_F4'
EXPORTING
is_variant = variant
i_save = 'A'
IMPORTING
es_variant = variant
EXCEPTIONS
not_found = 2.
IF sy-subrc = 2.
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
p_variante = variant-variant.
ENDIF.
ENDFORM.

*___________________________________________FORM chequeo_variante_existe
FORM chequeo_variante_existe USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.

* Esta form solo se tiene que usar si se quiere cargar una variante de
* visualización al sacar el listado.
* Esta form valida que la variante introducida por pantalla exista, en
* caso contrario da un mensaje de error.

*IMPLEMENTACIÓN.
*****at selection-screen. *****
***** perform alv_check USING (Nombre_prog) (variable_variante). *****

variant-report = p_repname.
variant-variant = p_variante.
IF NOT p_variante IS INITIAL.
CALL FUNCTION 'REUSE_ALV_VARIANT_EXISTENCE'
EXPORTING
i_save = 'A'
CHANGING
cs_variant = variant
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
MESSAGE e321(m7) WITH p_variante variant-report.
ENDIF.
ENDIF.

ENDFORM.

*______________________________________________________Asignar variante.
FORM asignar_variante USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.
* Si se quiere visualizar una variante es obligatorio llamar a esta form
* No es suficiente con llamar a la función de matchcode, o a la form de
* verificación.
CLEAR variant.
variant-report = p_repname.
variant-variant = p_variante.
ENDFORM.

*_______________________________________________________FORM top_of_page
FORM encabezado USING p_linea TYPE slis_entry .
* TOP-OF-PAGE, Se tiene que pasar línea a línea. Se tiene que rellenar
* una variable TYPE slis_entry, que tiene 60 posiciones, y enviarla a
* la form, para cada nueva línea del top-of-page se tiene que volver a
* llamar a la form enviando la nueva línea.

IF events[] IS INITIAL.
DATA: ls_event TYPE slis_alv_event.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
*___Indicamos que tiene que tener TOP-OF-PAGE
READ TABLE events WITH KEY name = slis_ev_top_of_page
INTO ls_event.
IF sy-subrc = 0.
MOVE formname_top_of_page TO ls_event-form.
APPEND ls_event TO events.
ENDIF.
DELETE ADJACENT DUPLICATES FROM heading COMPARING ALL FIELDS.
DATA: hline TYPE slis_listheader.
hline-typ = 'H'.
hline-info = p_linea.
APPEND hline TO heading.
CLEAR: hline, p_linea.

ENDFORM.

*________________________________________FORM ASIGN_O_QUITAR_CAMPO_CLAVE
FORM asign_o_quitar_campo_clave USING p_campo TYPE fieldname
p_x TYPE char1.
*Esta form asigna o quita la propiedad de campo clave. Los campos clave
*Aparecen en color azul a la izquierda de la pantalla, y se quedan
*Bloqueados sin que se puedan mover.
TRANSLATE p_campo TO UPPER CASE.
READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-key = p_x.
ENDIF.
ENDFORM.

*____________________________________________form asignar_ancho_columna
FORM asignar_ancho_columna USING p_campo TYPE fieldname
long TYPE i.
* Esta rutina asigna un ancho a la columna. No es necesario indicarlo
* porque por defecto coge la longitud de la variable.
TRANSLATE p_campo TO UPPER CASE.
READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-outputlen = long.
ENDIF.

ENDFORM.

*____________________________________________Form Indicar_campo_checkbox
FORM indicar_campo_checkbox USING p_campo TYPE fieldname.

* Esta rutina asigna a una columna la propiedad de checkbox.
* El parámetro import es el nombre del campo.
layout-box_fieldname = p_campo.
ENDFORM.

*_______________________________________________________FORM top_of_page
FORM top_of_page.
*Esta función es interna, y no se tiene que llamar desde el programa de
* control
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
i_logo = 'LOGO_SOS'
it_list_commentary = heading.
ENDFORM.

*______________________________________________FORM asignar_user_command
FORM asignar_user_command.
* Se tiene que crear una form dentro del programa de control que tenga
* implementado lo que se quiere hacer en el AT-LINE-SELECTION o
* AT USER COMMAND
* La form que se construya tiene que tener la structura:

*****form user_command using r_ucomm like sy-ucomm *******
***** rs_selfield type slis_selfield. *******

* El campo r_ucomm devuelve el código '&ETA' si es un doble click
* la estructura rs_selfield contiene los siguientes campos.

* tabname : Nombre de la tabla interna
* tabindex : Indice de la tabla interna
* fieldname: Campo en el que estaba posicionado el cursor
* sel_tab_field: Nombre de la celda donde estaba posicionado el cursor
* endsum : El cursor está sobre la linea de suma final
* sumindex : Si es mayor que cero, indica que es una linea de subtotal
* value : valor del campo de la lista
* refresh : (exporting) Se refresca la lista, la lista act. desaparece.
* col_stable:(exporting) keep column positions in refresh
DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
*___Indicamos que tiene el evento User-command: At-line-selection
READ TABLE events WITH KEY name = slis_ev_user_command
ASSIGNING .
CHECK sy-subrc = 0.
MOVE formname_user_command TO -form.
ENDFORM.

*_______________________________________________Form asignar_TOP_OF_PAGE
FORM asignar_top_of_page.
* Para el TOP-OF-PAGE, tendremos que crear una rutina que se llame
* ALV_TOP_OF_PAGE. Dentro de esta rutina podremos escribir la cabecera
* que queramos al modo tradicional (Con Writes).

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_top_of_page
ASSIGNING .
CHECK sy-subrc = 0.
-form = 'ALV_TOP_OF_PAGE'.
ENDFORM.

*_____________________________________________Form asignar_SET_PF_STATUS
FORM asignar_set_pf_status USING p_status.
* Tenemos que pasar como variable el STATUS que queremos asignar al
* listado.

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_pf_status_set
ASSIGNING .
CHECK sy-subrc = 0.
-form = p_status.
SET PF-STATUS p_status.
ENDFORM.

*__________________________________________________FORM visualizar_lista
FORM visualizar_lista TABLES p_itab
USING p_tablename TYPE slis_tabname
p_repname LIKE sy-repid.
* valores del g_save.
* ' ' = No se pueden salvar las variantes de visualización
* 'X' = Solo se pueden salvar las variantes standard
* 'U' = Solo se pueden salvar las variantes de usuario
* 'A' = Se pueden guardar todas las variantes.

DATA: e_exit_caused_by_caller.


CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'
EXPORTING
i_callback_program = p_repname
i_callback_pf_status_set = status
i_structure_name = p_tablename
is_layout = layout
it_fieldcat = fieldtab
i_default = 'A'
i_save = g_save
it_sort = sort
it_events = event[]
is_variant = variant
is_print = printer
i_callback_user_command = 'USER_COMMAND'
IMPORTING
e_exit_caused_by_caller = e_exit_caused_by_caller
TABLES
t_outtab = p_itab.

ENDFORM.
*_______________________________________________Form asignar_END_OF_LIST
FORM asignar_end_of_list.
* Para el END-OF-LIST, tendremos que crear una rutina que se llame
* ALV_END_OF_LIST. Dentro de esta rutina podremos escribir un párrafo
* al final que queramos al modo tradicional (Con Writes).

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_end_of_list
ASSIGNING .
CHECK sy-subrc = 0.
-form = 'ALV_END_OF_LIST'.
ENDFORM.
*_______________________________________________Form opciones_impresora
FORM opciones_impresora.
*Esta Form contiene características para la impresora.

*__Indicamos que no salga la página de selección.
printer-no_print_selinfos = 'X'.
printer-no_print_listinfos = 'X'.

ENDFORM. " OPCIONES_IMPRESORA
*_______________________________________________Form asignar_edit_campo
*esta form permite hacer un campo de la alv que sea editable

FORM asignar_edit_campo USING p_campo TYPE slis_fieldname
char1.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-input = char1.
* -seltext_m = p_descrip.
* -seltext_s = p_descrip.
* -reptext_ddic = p_descrip.
ENDIF.
ENDFORM. " asignar_edit_campo

*&---------------------------------------------------------------------*
*& Form activar_hotspot
*&---------------------------------------------------------------------*
FORM activar_hotspot USING p1 TYPE slis_fieldname
p2.

READ TABLE fieldtab WITH KEY fieldname = p1 ASSIGNING .
IF sy-subrc = 0.
-hotspot = p2.
ENDIF.

ENDFORM. " activar_hotspot


lunes, 22 de agosto de 2011

Sym SMB no jala en Windows XP

si este programa de la noche a la mañana dejo de conectarse para compartir tus archivos via wifi con tu celular es debido a una actualización de windows simplemente con quitarla se vuelve a conectar es desde agregar o quitar programas, marcas mostrar actualizaciones la buscas y la quitas con eso ya funciona de nuevo.

las actualizaciones a quitar son:
Actualización para Windows XP (KB2536276)

Funciona también para unidades de red que no quieren conectar.

lunes, 15 de agosto de 2011

include que genera un alv

Normalmente como mínimo es necesario este código si la tabla es I_TAB
repname = sy-repid.
PERFORM obt_descrip_campos_tabla USING repname 'I_TAB'.
PERFORM carac_gen_listado.
PERFORM visualizar_lista TABLES I_TAB USING 'I_TAB' repname .

si quieres que sea un grid en vez del list simplemente en vez de usar la funcion
REUSE_ALV_LIST_DISPLAY la cambias por REUSE_ALV_GRID_DISPLAY.

*----------------------------------------------------------------------*
* INCLUDE ZALV *
*----------------------------------------------------------------------*

************************************************************************
* Include ZALV: Subrutinas para listado ALV. *
************************************************************************

* Es necesario incluir este include en el inicio del programa.
* El inicio del código tiene que empezar por STAR-OF-SELECTION, o no
* lo reconocerá.
* IMPORTANTISIMO. Es obligatorio incluir la 1ª form, y la última.

* Listado de Forms.
* 1.- OBT_DESCRIP_CAMPOS_TABLA "Esta form es OBLIGATORIA.

* 2.- CAMB_DESCRIP_CAMPOS_TABLA "Cambia la descrip de cabecera
* 3.- ELIM_CAMPOS_DE_VISUALIZACION"No se visualizan los campos seleccio
* 4.- CARAC_GEN_LISTADO "Da formato al listado
* 5.- ASIGNAR_MONEDA_COLUMNA "Asignamos una campo de moneda
* 6.- ASIGNAR_UNIDAD_MEDIDA "Asignamos una unidad de medida
* 7.- ALV_F4 "Match code para varientes
* 8.- CHEQUEO_VARIANTE_EXISTE "Comprueba que exista la variante
* 9.- ASIGNAR_VARIANTE "Asignamos la variante al listado
* 10.- ENCABEZADO "Llamamos a esta función para inserta
* 11.- ASIGN_O_QUITAR_CAMPO_CLAVE "Asigna o quita la prop. de Campo Cla
* 12.- Indicar_campo_checkbox "Definir una columna como checkbox

* 13.- ASIGNAR_USER_COMMAND "Equivalente a AT USER-COMMAND
* 14.- Asignar_TOP_OF_PAGE "Deberemos crear FORM TOP_OF_PAGE2
* 15.- Asignar_PF_STATUS "Asigna un STATUS a un listado

* 16.- VISUALIZAR_LISTA "Visualizar la lista. OBLIGATORIA
* 17.- Asignar END_OF_PAGE "
* 18.- Opciones de Impresión
* 19.- Asignar_edit_campo "Campo editable en alv
* 20.- Asignar_hotspot "Activa o desactiva el hotspot

* Normalmente como mínimo es necesario este código si la tabla es I_TAB
* repname = sy-repid.
* PERFORM obt_descrip_campos_tabla USING repname 'I_TAB'.
* PERFORM carac_gen_listado.
* PERFORM visualizar_lista TABLES I_TAB USING 'I_TAB' repname .


*$*$ Definición de variables para el listado
TYPE-POOLS: slis.
DATA: repname LIKE sy-repid ,
layout TYPE slis_layout_alv,
printer TYPE slis_print_alv,
f2code LIKE sy-ucomm VALUE '&ETA',
fieldtab TYPE slis_t_fieldcat_alv,
heading TYPE slis_listheader OCCURS 0 ,
g_save(1) TYPE c VALUE 'A',
fausti LIKE tbsl-faus1, " string de campos obligatorios
events TYPE slis_alv_event OCCURS 0,
sort TYPE slis_t_sortinfo_alv,
sort_header TYPE slis_sortinfo_alv,
variant LIKE disvariant,
user_command TYPE slis_formname,
status TYPE slis_formname.

CONSTANTS:
formname_top_of_page TYPE slis_formname VALUE 'TOP_OF_PAGE',
formname_end_of_list TYPE slis_formname VALUE 'END_OF_LIST',
formname_user_command TYPE slis_formname VALUE 'USER_COMMAND',
formname_pf_status_set TYPE slis_formname VALUE 'PF_STATUS'.

FIELD-SYMBOLS TYPE slis_fieldcat_alv.



*$*$ Definición de Forms de listado

*__________________________________________Form obt_descrip_campos_tabla
FORM obt_descrip_campos_tabla USING p_repname
p_tablename TYPE slis_tabname.
* Esta es la primera form que se tiene que llamar. Así recogemos
* Los atributos de todos los campos de la tabla interna.
* Importante!!: La tabla interna no se tiene que definir como un data
* referenciado a una estructura type (Si se hace de este modo no
* reconocerá ningún campo). Utilizar siempre:
* Data begin of ..... occurs 0.
* Data end of ......
* No utilizar tampoco: Data: itab type standard table of ...............
REFRESH fieldtab.
CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
EXPORTING
i_program_name = p_repname
i_internal_tabname = p_tablename
i_inclname = p_repname
CHANGING
ct_fieldcat = fieldtab.

ENDFORM.

*_________________________________________FORM Camb_descrip_campos_tabla
FORM camb_descrip_campos_tabla USING p_campo TYPE slis_fieldname
p_descrip.

* Para utilizar esta form previamente tenemos que haber llamado a la
* form obt_descrip_campos_tabla. Tenemos que pasarle el campo de la
* tabla interna y la descripción que queremos que aparezca en la
* cabecera de la columna.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-seltext_l = p_descrip.
* -seltext_m = p_descrip.
* -seltext_s = p_descrip.
* -reptext_ddic = p_descrip.
ENDIF.

ENDFORM.

*______________________________________FORM elim_campos_de_visualizacion
FORM elim_campos_de_visualizacion USING p_campo TYPE slis_fieldname.
* Consigue que un campo clave se pueda quitar de la visualización.
* P. Ej. Mandante.
* Tambien elimina de la visualización cualquier campo que no sea clave.
* Desde dentro del listado estos campos se pueden volver a visualizar.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-key_sel = 'X'.
-no_out = 'X'.
ENDIF.
ENDFORM.
*_______________________________________________Carac. gen. del listado.
FORM carac_gen_listado.
*Esta Form contiene características generales del listado. Si se quieren
*estas mismas llamar a la Form, en caso contrario implementarlas desde
*el programa. La estructura de características generales es 'LAYOUT'.
*En El campo INFO_FIELDNAME se le indica la columna que contiene el
*color para cada registro. Si dicha columna, no tiene valor para algún
*registro, dicho registro tendrá el color standard que le toque.
* El formato que tiene que tener la columa COLOR es:
* 'Cxy':
* C = color (all codes must start with 'C')
* x = color number ('1'-'9')
* y = bold ('0' = off, '1' = on)

*__Indicamos que queremos el listado cebreado
layout-zebra = 'X'.
*__No afecta porque tenemos user-commmand
layout-detail_popup = 'X'.
*__Indicamos que Al hacer doble click el user-command = 'DOBCLICK'.
* layout-f2code = 'DOBCLICK'.
*__Si queremos que al hacer doble click despliegue la ventana desasteris
* p_layout-f2code = '&ETA'.
layout-info_fieldname = 'COLOR'.
* layout-flexible_key = 'X'. "Permite mover campos clave.
layout-colwidth_optimize = 'X'.
layout-detail_initial_lines = 'X'.
layout-detail_titlebar = 'Información Adicional'. "Titulo popup
layout-totals_only = 'X'.
layout-detail_popup = 'X'.

ENDFORM. " BUILD_LAYOUT

*____________________________________________FORM asignar_moneda_columna
FORM asignar_moneda_columna USING p_columna TYPE slis_fieldname
p_campo_moneda TYPE slis_fieldname.
* En esta form hay que pasar la columna que tiene los importes, y la
* Columna que contiene la moneda para cada registro.
READ TABLE fieldtab WITH KEY fieldname = p_columna ASSIGNING .
IF sy-subrc EQ 0.
-cfieldname = p_campo_moneda.
ENDIF.

ENDFORM.

*_____________________________________________FORM asignar_unidad_medida
FORM asignar_unidad_medida USING p_columna TYPE slis_fieldname
p_campo_moneda TYPE slis_fieldname.
* En esta form hay que pasar la columna que tiene las cantidades, y la
* Columna que contiene la unidad para cada registro.
READ TABLE fieldtab WITH KEY fieldname = p_columna ASSIGNING .
IF sy-subrc EQ 0.
-qfieldname = p_campo_moneda.
ENDIF.

ENDFORM.

*____________________________________________________________Form Alv_F4
FORM alv_f4 USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.

* Esta form devuelve un matchcode con las variantes existentes.
* Tan solo se tiene que poner si se quiere cargar una variante de
* visualización.
* Para poner esta form se tiene que poner:

**** at selection-screen on value-request for p_variante. *****
**** perform alv_f4 using (Nombreprograma) (Variable_variante). *****
variant-report = p_repname.
CALL FUNCTION 'REUSE_ALV_VARIANT_F4'
EXPORTING
is_variant = variant
i_save = 'A'
IMPORTING
es_variant = variant
EXCEPTIONS
not_found = 2.
IF sy-subrc = 2.
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
p_variante = variant-variant.
ENDIF.
ENDFORM.

*___________________________________________FORM chequeo_variante_existe
FORM chequeo_variante_existe USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.

* Esta form solo se tiene que usar si se quiere cargar una variante de
* visualización al sacar el listado.
* Esta form valida que la variante introducida por pantalla exista, en
* caso contrario da un mensaje de error.

*IMPLEMENTACIÓN.
*****at selection-screen. *****
***** perform alv_check USING (Nombre_prog) (variable_variante). *****

variant-report = p_repname.
variant-variant = p_variante.
IF NOT p_variante IS INITIAL.
CALL FUNCTION 'REUSE_ALV_VARIANT_EXISTENCE'
EXPORTING
i_save = 'A'
CHANGING
cs_variant = variant
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
MESSAGE e321(m7) WITH p_variante variant-report.
ENDIF.
ENDIF.

ENDFORM.

*______________________________________________________Asignar variante.
FORM asignar_variante USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.
* Si se quiere visualizar una variante es obligatorio llamar a esta form
* No es suficiente con llamar a la función de matchcode, o a la form de
* verificación.
CLEAR variant.
variant-report = p_repname.
variant-variant = p_variante.
ENDFORM.

*_______________________________________________________FORM top_of_page
FORM encabezado USING p_linea TYPE slis_entry .
* TOP-OF-PAGE, Se tiene que pasar línea a línea. Se tiene que rellenar
* una variable TYPE slis_entry, que tiene 60 posiciones, y enviarla a
* la form, para cada nueva línea del top-of-page se tiene que volver a
* llamar a la form enviando la nueva línea.

IF events[] IS INITIAL.
DATA: ls_event TYPE slis_alv_event.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
*___Indicamos que tiene que tener TOP-OF-PAGE
READ TABLE events WITH KEY name = slis_ev_top_of_page
INTO ls_event.
IF sy-subrc = 0.
MOVE formname_top_of_page TO ls_event-form.
APPEND ls_event TO events.
ENDIF.
DELETE ADJACENT DUPLICATES FROM heading COMPARING ALL FIELDS.
DATA: hline TYPE slis_listheader.
hline-typ = 'H'.
hline-info = p_linea.
APPEND hline TO heading.
CLEAR: hline, p_linea.

ENDFORM.

*________________________________________FORM ASIGN_O_QUITAR_CAMPO_CLAVE
FORM asign_o_quitar_campo_clave USING p_campo TYPE fieldname
p_x TYPE char1.
*Esta form asigna o quita la propiedad de campo clave. Los campos clave
*Aparecen en color azul a la izquierda de la pantalla, y se quedan
*Bloqueados sin que se puedan mover.
TRANSLATE p_campo TO UPPER CASE.
READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-key = p_x.
ENDIF.
ENDFORM.

*____________________________________________form asignar_ancho_columna
FORM asignar_ancho_columna USING p_campo TYPE fieldname
long TYPE i.
* Esta rutina asigna un ancho a la columna. No es necesario indicarlo
* porque por defecto coge la longitud de la variable.
TRANSLATE p_campo TO UPPER CASE.
READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-outputlen = long.
ENDIF.

ENDFORM.

*____________________________________________Form Indicar_campo_checkbox
FORM indicar_campo_checkbox USING p_campo TYPE fieldname.

* Esta rutina asigna a una columna la propiedad de checkbox.
* El parámetro import es el nombre del campo.
layout-box_fieldname = p_campo.
ENDFORM.

*_______________________________________________________FORM top_of_page
FORM top_of_page.
*Esta función es interna, y no se tiene que llamar desde el programa de
* control
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
i_logo = 'LOGO_SOS'
it_list_commentary = heading.
ENDFORM.

*______________________________________________FORM asignar_user_command
FORM asignar_user_command.
* Se tiene que crear una form dentro del programa de control que tenga
* implementado lo que se quiere hacer en el AT-LINE-SELECTION o
* AT USER COMMAND
* La form que se construya tiene que tener la structura:

*****form user_command using r_ucomm like sy-ucomm *******
***** rs_selfield type slis_selfield. *******

* El campo r_ucomm devuelve el código '&ETA' si es un doble click
* la estructura rs_selfield contiene los siguientes campos.

* tabname : Nombre de la tabla interna
* tabindex : Indice de la tabla interna
* fieldname: Campo en el que estaba posicionado el cursor
* sel_tab_field: Nombre de la celda donde estaba posicionado el cursor
* endsum : El cursor está sobre la linea de suma final
* sumindex : Si es mayor que cero, indica que es una linea de subtotal
* value : valor del campo de la lista
* refresh : (exporting) Se refresca la lista, la lista act. desaparece.
* col_stable:(exporting) keep column positions in refresh
DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
*___Indicamos que tiene el evento User-command: At-line-selection
READ TABLE events WITH KEY name = slis_ev_user_command
ASSIGNING .
CHECK sy-subrc = 0.
MOVE formname_user_command TO -form.
ENDFORM.

*_______________________________________________Form asignar_TOP_OF_PAGE
FORM asignar_top_of_page.
* Para el TOP-OF-PAGE, tendremos que crear una rutina que se llame
* ALV_TOP_OF_PAGE. Dentro de esta rutina podremos escribir la cabecera
* que queramos al modo tradicional (Con Writes).

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_top_of_page
ASSIGNING .
CHECK sy-subrc = 0.
-form = 'ALV_TOP_OF_PAGE'.
ENDFORM.

*_____________________________________________Form asignar_SET_PF_STATUS
FORM asignar_set_pf_status USING p_status.
* Tenemos que pasar como variable el STATUS que queremos asignar al
* listado.

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_pf_status_set
ASSIGNING .
CHECK sy-subrc = 0.
-form = p_status.
SET PF-STATUS p_status.
ENDFORM.

*__________________________________________________FORM visualizar_lista
FORM visualizar_lista TABLES p_itab
USING p_tablename TYPE slis_tabname
p_repname LIKE sy-repid.
* valores del g_save.
* ' ' = No se pueden salvar las variantes de visualización
* 'X' = Solo se pueden salvar las variantes standard
* 'U' = Solo se pueden salvar las variantes de usuario
* 'A' = Se pueden guardar todas las variantes.

DATA: e_exit_caused_by_caller.


CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'
EXPORTING
i_callback_program = p_repname
i_callback_pf_status_set = status
i_structure_name = p_tablename
is_layout = layout
it_fieldcat = fieldtab
i_default = 'A'
i_save = g_save
it_sort = sort
it_events = events[]
is_variant = variant
is_print = printer
i_callback_user_command = 'USER_COMMAND'
IMPORTING
e_exit_caused_by_caller = e_exit_caused_by_caller
TABLES
t_outtab = p_itab.

ENDFORM.
*_______________________________________________Form asignar_END_OF_LIST
FORM asignar_end_of_list.
* Para el END-OF-LIST, tendremos que crear una rutina que se llame
* ALV_END_OF_LIST. Dentro de esta rutina podremos escribir un párrafo
* al final que queramos al modo tradicional (Con Writes).

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_end_of_list
ASSIGNING .
CHECK sy-subrc = 0.
-form = 'ALV_END_OF_LIST'.
ENDFORM.
*_______________________________________________Form opciones_impresora
FORM opciones_impresora.
*Esta Form contiene características para la impresora.

*__Indicamos que no salga la página de selección.
printer-no_print_selinfos = 'X'.
printer-no_print_listinfos = 'X'.

ENDFORM. " OPCIONES_IMPRESORA
*_______________________________________________Form asignar_edit_campo
*esta form permite hacer un campo de la alv que sea editable

FORM asignar_edit_campo USING p_campo TYPE slis_fieldname
char1.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-input = char1.
* -seltext_m = p_descrip.
* -seltext_s = p_descrip.
* -reptext_ddic = p_descrip.
ENDIF.
ENDFORM. " asignar_edit_campo

*&---------------------------------------------------------------------*
*& Form activar_hotspot
*&---------------------------------------------------------------------*
FORM activar_hotspot USING p1 TYPE slis_fieldname
p2.

READ TABLE fieldtab WITH KEY fieldname = p1 ASSIGNING .
IF sy-subrc = 0.
-hotspot = p2.
ENDIF.

ENDFORM. " activar_hotspot

include que genera un alv

Normalmente como mínimo es necesario este código si la tabla es I_TAB
repname = sy-repid.
PERFORM obt_descrip_campos_tabla USING repname 'I_TAB'.
PERFORM carac_gen_listado.
PERFORM visualizar_lista TABLES I_TAB USING 'I_TAB' repname .

si quieres que sea un grid en vez del list simplemente en vez de usar la funcion
REUSE_ALV_LIST_DISPLAY la cambias por REUSE_ALV_GRID_DISPLAY.

*----------------------------------------------------------------------*
* INCLUDE ZALV *
*----------------------------------------------------------------------*

************************************************************************
* Include ZALV: Subrutinas para listado ALV. *
************************************************************************

* Es necesario incluir este include en el inicio del programa.
* El inicio del código tiene que empezar por STAR-OF-SELECTION, o no
* lo reconocerá.
* IMPORTANTISIMO. Es obligatorio incluir la 1ª form, y la última.

* Listado de Forms.
* 1.- OBT_DESCRIP_CAMPOS_TABLA "Esta form es OBLIGATORIA.

* 2.- CAMB_DESCRIP_CAMPOS_TABLA "Cambia la descrip de cabecera
* 3.- ELIM_CAMPOS_DE_VISUALIZACION"No se visualizan los campos seleccio
* 4.- CARAC_GEN_LISTADO "Da formato al listado
* 5.- ASIGNAR_MONEDA_COLUMNA "Asignamos una campo de moneda
* 6.- ASIGNAR_UNIDAD_MEDIDA "Asignamos una unidad de medida
* 7.- ALV_F4 "Match code para varientes
* 8.- CHEQUEO_VARIANTE_EXISTE "Comprueba que exista la variante
* 9.- ASIGNAR_VARIANTE "Asignamos la variante al listado
* 10.- ENCABEZADO "Llamamos a esta función para inserta
* 11.- ASIGN_O_QUITAR_CAMPO_CLAVE "Asigna o quita la prop. de Campo Cla
* 12.- Indicar_campo_checkbox "Definir una columna como checkbox

* 13.- ASIGNAR_USER_COMMAND "Equivalente a AT USER-COMMAND
* 14.- Asignar_TOP_OF_PAGE "Deberemos crear FORM TOP_OF_PAGE2
* 15.- Asignar_PF_STATUS "Asigna un STATUS a un listado

* 16.- VISUALIZAR_LISTA "Visualizar la lista. OBLIGATORIA
* 17.- Asignar END_OF_PAGE "
* 18.- Opciones de Impresión
* 19.- Asignar_edit_campo "Campo editable en alv
* 20.- Asignar_hotspot "Activa o desactiva el hotspot

* Normalmente como mínimo es necesario este código si la tabla es I_TAB
* repname = sy-repid.
* PERFORM obt_descrip_campos_tabla USING repname 'I_TAB'.
* PERFORM carac_gen_listado.
* PERFORM visualizar_lista TABLES I_TAB USING 'I_TAB' repname .


*$*$ Definición de variables para el listado
TYPE-POOLS: slis.
DATA: repname LIKE sy-repid ,
layout TYPE slis_layout_alv,
printer TYPE slis_print_alv,
f2code LIKE sy-ucomm VALUE '&ETA',
fieldtab TYPE slis_t_fieldcat_alv,
heading TYPE slis_listheader OCCURS 0 ,
g_save(1) TYPE c VALUE 'A',
fausti LIKE tbsl-faus1, " string de campos obligatorios
events TYPE slis_alv_event OCCURS 0,
sort TYPE slis_t_sortinfo_alv,
sort_header TYPE slis_sortinfo_alv,
variant LIKE disvariant,
user_command TYPE slis_formname,
status TYPE slis_formname.

CONSTANTS:
formname_top_of_page TYPE slis_formname VALUE 'TOP_OF_PAGE',
formname_end_of_list TYPE slis_formname VALUE 'END_OF_LIST',
formname_user_command TYPE slis_formname VALUE 'USER_COMMAND',
formname_pf_status_set TYPE slis_formname VALUE 'PF_STATUS'.

FIELD-SYMBOLS TYPE slis_fieldcat_alv.



*$*$ Definición de Forms de listado

*__________________________________________Form obt_descrip_campos_tabla
FORM obt_descrip_campos_tabla USING p_repname
p_tablename TYPE slis_tabname.
* Esta es la primera form que se tiene que llamar. Así recogemos
* Los atributos de todos los campos de la tabla interna.
* Importante!!: La tabla interna no se tiene que definir como un data
* referenciado a una estructura type (Si se hace de este modo no
* reconocerá ningún campo). Utilizar siempre:
* Data begin of ..... occurs 0.
* Data end of ......
* No utilizar tampoco: Data: itab type standard table of ...............
REFRESH fieldtab.
CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
EXPORTING
i_program_name = p_repname
i_internal_tabname = p_tablename
i_inclname = p_repname
CHANGING
ct_fieldcat = fieldtab.

ENDFORM.

*_________________________________________FORM Camb_descrip_campos_tabla
FORM camb_descrip_campos_tabla USING p_campo TYPE slis_fieldname
p_descrip.

* Para utilizar esta form previamente tenemos que haber llamado a la
* form obt_descrip_campos_tabla. Tenemos que pasarle el campo de la
* tabla interna y la descripción que queremos que aparezca en la
* cabecera de la columna.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-seltext_l = p_descrip.
* -seltext_m = p_descrip.
* -seltext_s = p_descrip.
* -reptext_ddic = p_descrip.
ENDIF.

ENDFORM.

*______________________________________FORM elim_campos_de_visualizacion
FORM elim_campos_de_visualizacion USING p_campo TYPE slis_fieldname.
* Consigue que un campo clave se pueda quitar de la visualización.
* P. Ej. Mandante.
* Tambien elimina de la visualización cualquier campo que no sea clave.
* Desde dentro del listado estos campos se pueden volver a visualizar.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-key_sel = 'X'.
-no_out = 'X'.
ENDIF.
ENDFORM.
*_______________________________________________Carac. gen. del listado.
FORM carac_gen_listado.
*Esta Form contiene características generales del listado. Si se quieren
*estas mismas llamar a la Form, en caso contrario implementarlas desde
*el programa. La estructura de características generales es 'LAYOUT'.
*En El campo INFO_FIELDNAME se le indica la columna que contiene el
*color para cada registro. Si dicha columna, no tiene valor para algún
*registro, dicho registro tendrá el color standard que le toque.
* El formato que tiene que tener la columa COLOR es:
* 'Cxy':
* C = color (all codes must start with 'C')
* x = color number ('1'-'9')
* y = bold ('0' = off, '1' = on)

*__Indicamos que queremos el listado cebreado
layout-zebra = 'X'.
*__No afecta porque tenemos user-commmand
layout-detail_popup = 'X'.
*__Indicamos que Al hacer doble click el user-command = 'DOBCLICK'.
* layout-f2code = 'DOBCLICK'.
*__Si queremos que al hacer doble click despliegue la ventana desasteris
* p_layout-f2code = '&ETA'.
layout-info_fieldname = 'COLOR'.
* layout-flexible_key = 'X'. "Permite mover campos clave.
layout-colwidth_optimize = 'X'.
layout-detail_initial_lines = 'X'.
layout-detail_titlebar = 'Información Adicional'. "Titulo popup
layout-totals_only = 'X'.
layout-detail_popup = 'X'.

ENDFORM. " BUILD_LAYOUT

*____________________________________________FORM asignar_moneda_columna
FORM asignar_moneda_columna USING p_columna TYPE slis_fieldname
p_campo_moneda TYPE slis_fieldname.
* En esta form hay que pasar la columna que tiene los importes, y la
* Columna que contiene la moneda para cada registro.
READ TABLE fieldtab WITH KEY fieldname = p_columna ASSIGNING .
IF sy-subrc EQ 0.
-cfieldname = p_campo_moneda.
ENDIF.

ENDFORM.

*_____________________________________________FORM asignar_unidad_medida
FORM asignar_unidad_medida USING p_columna TYPE slis_fieldname
p_campo_moneda TYPE slis_fieldname.
* En esta form hay que pasar la columna que tiene las cantidades, y la
* Columna que contiene la unidad para cada registro.
READ TABLE fieldtab WITH KEY fieldname = p_columna ASSIGNING .
IF sy-subrc EQ 0.
-qfieldname = p_campo_moneda.
ENDIF.

ENDFORM.

*____________________________________________________________Form Alv_F4
FORM alv_f4 USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.

* Esta form devuelve un matchcode con las variantes existentes.
* Tan solo se tiene que poner si se quiere cargar una variante de
* visualización.
* Para poner esta form se tiene que poner:

**** at selection-screen on value-request for p_variante. *****
**** perform alv_f4 using (Nombreprograma) (Variable_variante). *****
variant-report = p_repname.
CALL FUNCTION 'REUSE_ALV_VARIANT_F4'
EXPORTING
is_variant = variant
i_save = 'A'
IMPORTING
es_variant = variant
EXCEPTIONS
not_found = 2.
IF sy-subrc = 2.
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
p_variante = variant-variant.
ENDIF.
ENDFORM.

*___________________________________________FORM chequeo_variante_existe
FORM chequeo_variante_existe USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.

* Esta form solo se tiene que usar si se quiere cargar una variante de
* visualización al sacar el listado.
* Esta form valida que la variante introducida por pantalla exista, en
* caso contrario da un mensaje de error.

*IMPLEMENTACIÓN.
*****at selection-screen. *****
***** perform alv_check USING (Nombre_prog) (variable_variante). *****

variant-report = p_repname.
variant-variant = p_variante.
IF NOT p_variante IS INITIAL.
CALL FUNCTION 'REUSE_ALV_VARIANT_EXISTENCE'
EXPORTING
i_save = 'A'
CHANGING
cs_variant = variant
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
MESSAGE e321(m7) WITH p_variante variant-report.
ENDIF.
ENDIF.

ENDFORM.

*______________________________________________________Asignar variante.
FORM asignar_variante USING p_repname LIKE sy-repid
p_variante LIKE disvariant-variant.
* Si se quiere visualizar una variante es obligatorio llamar a esta form
* No es suficiente con llamar a la función de matchcode, o a la form de
* verificación.
CLEAR variant.
variant-report = p_repname.
variant-variant = p_variante.
ENDFORM.

*_______________________________________________________FORM top_of_page
FORM encabezado USING p_linea TYPE slis_entry .
* TOP-OF-PAGE, Se tiene que pasar línea a línea. Se tiene que rellenar
* una variable TYPE slis_entry, que tiene 60 posiciones, y enviarla a
* la form, para cada nueva línea del top-of-page se tiene que volver a
* llamar a la form enviando la nueva línea.

IF events[] IS INITIAL.
DATA: ls_event TYPE slis_alv_event.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
*___Indicamos que tiene que tener TOP-OF-PAGE
READ TABLE events WITH KEY name = slis_ev_top_of_page
INTO ls_event.
IF sy-subrc = 0.
MOVE formname_top_of_page TO ls_event-form.
APPEND ls_event TO events.
ENDIF.
DELETE ADJACENT DUPLICATES FROM heading COMPARING ALL FIELDS.
DATA: hline TYPE slis_listheader.
hline-typ = 'H'.
hline-info = p_linea.
APPEND hline TO heading.
CLEAR: hline, p_linea.

ENDFORM.

*________________________________________FORM ASIGN_O_QUITAR_CAMPO_CLAVE
FORM asign_o_quitar_campo_clave USING p_campo TYPE fieldname
p_x TYPE char1.
*Esta form asigna o quita la propiedad de campo clave. Los campos clave
*Aparecen en color azul a la izquierda de la pantalla, y se quedan
*Bloqueados sin que se puedan mover.
TRANSLATE p_campo TO UPPER CASE.
READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-key = p_x.
ENDIF.
ENDFORM.

*____________________________________________form asignar_ancho_columna
FORM asignar_ancho_columna USING p_campo TYPE fieldname
long TYPE i.
* Esta rutina asigna un ancho a la columna. No es necesario indicarlo
* porque por defecto coge la longitud de la variable.
TRANSLATE p_campo TO UPPER CASE.
READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-outputlen = long.
ENDIF.

ENDFORM.

*____________________________________________Form Indicar_campo_checkbox
FORM indicar_campo_checkbox USING p_campo TYPE fieldname.

* Esta rutina asigna a una columna la propiedad de checkbox.
* El parámetro import es el nombre del campo.
layout-box_fieldname = p_campo.
ENDFORM.

*_______________________________________________________FORM top_of_page
FORM top_of_page.
*Esta función es interna, y no se tiene que llamar desde el programa de
* control
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
i_logo = 'LOGO_SOS'
it_list_commentary = heading.
ENDFORM.

*______________________________________________FORM asignar_user_command
FORM asignar_user_command.
* Se tiene que crear una form dentro del programa de control que tenga
* implementado lo que se quiere hacer en el AT-LINE-SELECTION o
* AT USER COMMAND
* La form que se construya tiene que tener la structura:

*****form user_command using r_ucomm like sy-ucomm *******
***** rs_selfield type slis_selfield. *******

* El campo r_ucomm devuelve el código '&ETA' si es un doble click
* la estructura rs_selfield contiene los siguientes campos.

* tabname : Nombre de la tabla interna
* tabindex : Indice de la tabla interna
* fieldname: Campo en el que estaba posicionado el cursor
* sel_tab_field: Nombre de la celda donde estaba posicionado el cursor
* endsum : El cursor está sobre la linea de suma final
* sumindex : Si es mayor que cero, indica que es una linea de subtotal
* value : valor del campo de la lista
* refresh : (exporting) Se refresca la lista, la lista act. desaparece.
* col_stable:(exporting) keep column positions in refresh
DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
*___Indicamos que tiene el evento User-command: At-line-selection
READ TABLE events WITH KEY name = slis_ev_user_command
ASSIGNING .
CHECK sy-subrc = 0.
MOVE formname_user_command TO -form.
ENDFORM.

*_______________________________________________Form asignar_TOP_OF_PAGE
FORM asignar_top_of_page.
* Para el TOP-OF-PAGE, tendremos que crear una rutina que se llame
* ALV_TOP_OF_PAGE. Dentro de esta rutina podremos escribir la cabecera
* que queramos al modo tradicional (Con Writes).

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_top_of_page
ASSIGNING .
CHECK sy-subrc = 0.
-form = 'ALV_TOP_OF_PAGE'.
ENDFORM.

*_____________________________________________Form asignar_SET_PF_STATUS
FORM asignar_set_pf_status USING p_status.
* Tenemos que pasar como variable el STATUS que queremos asignar al
* listado.

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_pf_status_set
ASSIGNING .
CHECK sy-subrc = 0.
-form = p_status.
SET PF-STATUS p_status.
ENDFORM.

*__________________________________________________FORM visualizar_lista
FORM visualizar_lista TABLES p_itab
USING p_tablename TYPE slis_tabname
p_repname LIKE sy-repid.
* valores del g_save.
* ' ' = No se pueden salvar las variantes de visualización
* 'X' = Solo se pueden salvar las variantes standard
* 'U' = Solo se pueden salvar las variantes de usuario
* 'A' = Se pueden guardar todas las variantes.

DATA: e_exit_caused_by_caller.


CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'
EXPORTING
i_callback_program = p_repname
i_callback_pf_status_set = status
i_structure_name = p_tablename
is_layout = layout
it_fieldcat = fieldtab
i_default = 'A'
i_save = g_save
it_sort = sort
it_events = events[]
is_variant = variant
is_print = printer
i_callback_user_command = 'USER_COMMAND'
IMPORTING
e_exit_caused_by_caller = e_exit_caused_by_caller
TABLES
t_outtab = p_itab.

ENDFORM.
*_______________________________________________Form asignar_END_OF_LIST
FORM asignar_end_of_list.
* Para el END-OF-LIST, tendremos que crear una rutina que se llame
* ALV_END_OF_LIST. Dentro de esta rutina podremos escribir un párrafo
* al final que queramos al modo tradicional (Con Writes).

DATA: ls_event TYPE slis_alv_event.
FIELD-SYMBOLS LIKE ls_event.
IF events[] IS INITIAL.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = events.
ENDIF.
READ TABLE events WITH KEY name = slis_ev_end_of_list
ASSIGNING .
CHECK sy-subrc = 0.
-form = 'ALV_END_OF_LIST'.
ENDFORM.
*_______________________________________________Form opciones_impresora
FORM opciones_impresora.
*Esta Form contiene características para la impresora.

*__Indicamos que no salga la página de selección.
printer-no_print_selinfos = 'X'.
printer-no_print_listinfos = 'X'.

ENDFORM. " OPCIONES_IMPRESORA
*_______________________________________________Form asignar_edit_campo
*esta form permite hacer un campo de la alv que sea editable

FORM asignar_edit_campo USING p_campo TYPE slis_fieldname
char1.

READ TABLE fieldtab WITH KEY fieldname = p_campo ASSIGNING .
IF sy-subrc EQ 0.
-input = char1.
* -seltext_m = p_descrip.
* -seltext_s = p_descrip.
* -reptext_ddic = p_descrip.
ENDIF.
ENDFORM. " asignar_edit_campo

*&---------------------------------------------------------------------*
*& Form activar_hotspot
*&---------------------------------------------------------------------*
FORM activar_hotspot USING p1 TYPE slis_fieldname
p2.

READ TABLE fieldtab WITH KEY fieldname = p1 ASSIGNING .
IF sy-subrc = 0.
-hotspot = p2.
ENDIF.

ENDFORM. " activar_hotspot