viernes, 30 de noviembre de 2007

Cubbic

Continúo en SAP hasta febrero, y a partir de ahí, continúo con un proyecto nuevo (para mí, porque el proyecto ya está empezado).
Se trata de un buscador en boletines oficiales españoles, de momento están indexados el BOME, el BOJA, y el BOCM (Melilla, Junta de Andalucía y Comunidad de Madrid).
Le pongo un link permanente y un banner.

http://www.cubbic.es (se me había olvidado)

jueves, 22 de noviembre de 2007

Comprobar la existencia de una RUTA

En primer lugar, hay que aclarar que en los sistemas UNIX, todo se trata como un fichero; por lo tanto, el siguiente report primero "chequea" si la ruta es UNIX o es WINDOWS, y después pasa a comprobarla.
*&---------------------------------------------------------------------*
*& Report Z_COMPROBAR_RUTA
*&
*&---------------------------------------------------------------------*
*& Comprueba si la RUTA de un fichero existe
*&---------------------------------------------------------------------*
*& Alberto García de Haro
*& http://misprogramasabap.blogspot.com
*&---------------------------------------------------------------------*
*& Elementos de datos:
*& p_unix: Fichero UNIX
*& p_locl: Fichero local (Windows)
*& p_ruta: Ruta del fichero
*&---------------------------------------------------------------------*

REPORT z_comprobar_ruta.

CONSTANTS: long TYPE i VALUE 1024.

DATA: gv_existe TYPE c,
gv_ruta TYPE string.

SELECTION-SCREEN BEGIN OF BLOCK bl1.
PARAMETERS:
p_unix RADIOBUTTON GROUP gr1,
p_locl RADIOBUTTON GROUP gr1,
p_ruta LIKE rlgrap-filename.
SELECTION-SCREEN END OF BLOCK bl1.

START-OF-SELECTION.
IF p_locl EQ 'X'. "Fichero local
MOVE p_ruta TO gv_ruta.

CALL METHOD cl_gui_frontend_services=>directory_exist
EXPORTING
directory = gv_ruta
RECEIVING
result = gv_existe
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
wrong_parameter = 3
not_supported_by_gui = 4
OTHERS = 5.
ELSE. "Fichero UNIX

OPEN DATASET p_ruta FOR INPUT
IN TEXT MODE ENCODING DEFAULT.
IF sy-subrc EQ 0.
gv_existe = 'X'.
CLOSE DATASET gv_ruta.
ELSE.
gv_existe = space.
ENDIF.

ENDIF.


PERFORM extraer_ruta USING p_ruta.

END-OF-SELECTION.
WRITE /.
IF gv_existe EQ space.
WRITE 'No existe la ruta'.
ELSE.
WRITE 'Sí existe la ruta'.
ENDIF.

*&---------------------------------------------------------------------*
*& Form extraer_ruta
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_GV_RUTA text
*----------------------------------------------------------------------*
FORM extraer_ruta USING p_gv_ruta.

*Tabla para ir metiendo las palabras
DATA:
BEGIN OF lt_tab OCCURS 10,
campo(long) TYPE c,
END OF lt_tab,

"Palabras
lv_word1(long) TYPE c,
lv_word2(long) TYPE c,


lv_ruta LIKE rlgrap-filename, "Ruta SIN fichero
lv_fich(long) TYPE c. "Nombre del fichero

*Inicio del proceso
REFRESH lt_tab.

MOVE p_gv_ruta TO lv_ruta.
DO.

SPLIT lv_ruta AT '/' INTO lv_word1 lv_word2.
IF NOT lv_word1 IS INITIAL and not lv_word2 is initial .
MOVE lv_word1 TO lt_tab.
APPEND lt_tab. CLEAR lt_tab.
ENDIF.
MOVE lv_word2 TO lv_ruta.

IF lv_word2 IS INITIAL. "No se puede separar más
MOVE lv_word1 TO lv_fich.
EXIT.
ENDIF.
ENDDO.
"Ahora obtengo la ruta

CLEAR lv_ruta.

LOOP AT lt_tab.
CONCATENATE lv_ruta lt_tab-campo
INTO lv_ruta SEPARATED BY '/'.
ENDLOOP.

WRITE:
'La ruta SIN fichero es',
lv_ruta, /,
'El fichero es',
lv_fich.

ENDFORM. " extraer_ruta

martes, 20 de noviembre de 2007

Leer checkboxes en un listado

Este problema se me planteó durante un borrado masivo de documentos preliminares.

Para ello, el propio SAP propone un report en su nota 971193. (Estaría bien poner los pdf en el blog, pero como son de SAP y tendrán copyright, mejor no).

El report que propone, básicamente, lista todos los documentos preliminares (parked documents), y al pulsar el botón de SAVE (para el que proponen un diskete, en el status DELE) se borran. Pero, ¿qué pasa si no quiero borrarlos todos?

Lo más fácil es poner, como encabezado de cada línea, un checkbox; y si está marcado se borra el documento correspondiente a esta línea. Para ello, hay que tener en cuenta lo siguiente:

1. El estatus DELE (al menos cuando empecé a trabajar con el report) tenía en el botón de “marcar todos” el código de función &ALL, que también estaba asociado a la tecla de función F2. Esto provocaba que, si se intentaba seleccionar sólo una línea, saltase el código de F2 que tenía asociada la función “Seleccionar todos (&ALL)”, y no funcionase. Para corregirlo, a la tecla de función “F2” le asocié el nuevo código “&ONE”, y para el código de función “&ALL” asocié la tecla de función F5, como puede apreciarse en las imágenes.
Además, agregué una función de refresco de imagen.




2. En el report propuesto, hice las siguientes modificaciones:
2.1. En la tabla TBKPF, añadí un campito para que recogiese/mostrase el valor del checkbox asociado:

data: begin of tbkpf occurs 5,
tratar type c.
include structure vbkpf.
data: end of tbkpf.

2.2. Tanto la selección de datos como la impresión por pantalla del listado, los metí en dos performs. Además, cambié la selección porque los bucles SELECT...ENDSELECT no me gustan. No tiene sentido mostrar el código de dichos performs (al final de esta entrada lo incluiré entero), sin embargo sus nombres son:

*Meto el select en un perform
perform seleccionar_vbkpf.

*Meto la impresión de la pantalla en otro perfrom
perform escribir_listado.

2.3. Al pulsar el botón de borrado (sy-ucomm = ‘DELE’), le pedí que revisara los documentos marcados con instrucciones READ LINE en la subrutina revisar_marcados; previamente, había guardado el número de líneas que se muestran por pantalla en la variable global gv_lineas declarada así:
data: gv_lineas like sy-linno.

Esta variable se establece después de hacer el listado con sentencias write (en concreto, en el perform “escribir_listado”, haciendo:
gv_lineas = sy-linno.
2.4. También al pulsar el botón de borrado, se llamaba al form “fbv0_dele.”. modifiqué una sóla línea de este form para que tuviera en cuenta que hiciera el loop a la tabla TBKPF, con la condición de que el campo “tratar” estuviera marcado, lo cual se revisaba como he dicho en el form revisar_marcados.

loop at tbkpf
"Añado condición
where tratar eq 'X'.
(...)
endloop.

3. Al escribir/leer el contenido de la tabla en el listado, hay que tener en cuenta que es preferible meter el checkbox en una variable global (gv_check) de tipo carácter, que escribir el campo de la tabla en sí (tbkpf-tratar), ya que en caso contrario cada vez que seleccionásemos una línea habría que modificar la tabla y reescribir el listado, con los inconvenientes que ello conlleva: modificar una tabla (aunque sea interna) es un proceso costoso, y un listado no se puede reescribir más de un número determinado de veces (según la parametrización del sistema donde hice el report, 20).
4. El botón “BACK” provocaba, durante el listado, que mostrase la pantalla anterior no por evento sino por apariencia; es decir, en lugar de mostrarse la pantalla de selección, aparecía la modificación anterior hecha en la pantalla. Por ejemplo, si después de ejecutar la pantalla de selección, durante el listado, primero seleccionábamos todos los check-boxes, luego los deseleccionábamos, luego marcábamos uno, y dábamos para atrás, resultaría que se mostrarían todos desmarcados (primera pulsación) luego todos marcados (segunda pulsación) y luego la pantalla de selección. ¡Un engorro! Por eso, deshabilité el botón “DELE” en el PF-STATUS:
start-of-selection.
set pf-status 'DELE' excluding 'BACK'.
Y lo volvía a incluirlo al pulsar el botón ‘DELE’.
end-of-selection.

at user-command.
(…)
case sy-ucomm.
when 'DELE'.
perform revisar_marcados. "Comprueba los marcados
set pf-status 'DELE'. "Habilita el botón “Back”


Estas han sido las modificaciones, ahora el report enterito:

*&---------------------------------------------------------------------*
*& Report ZDELEPARKED *&
*&---------------------------------------------------------------------*
*&
*& Borrado masivo de documentos preliminares
*& Modificado por Alberto García de Haro
*& a partir del report propuesto por SAP en la nota971193
*& 20 de noviembre de 2007
*& http://misprogramasabap.blogspot.com
*&---------------------------------------------------------------------*

report zdeleparked.

tables: vbkpf, t020.

data: mode type c value 'N'.
data: begin of tbkpf occurs 5,
tratar type c.
include structure vbkpf.
data: end of tbkpf.
data: begin of it020 occurs 0.
include structure t020.
data: end of it020.
data: begin of bdcdata occurs 0.
include structure bdcdata.
data: end of bdcdata.
data: begin of messtab occurs 0.
include structure bdcmsgcoll.
data: end of messtab.
data: char(20) type c,
count type i,
xdele.
data: wa_tbkpf like line of tbkpf,
gv_check type c,
gv_veces type i, "Veces que se ha mostrado el listado
gv_belnr like vbkpf-belnr,
gv_lineas like sy-linno,
gv_index like sy-tabix.

data: tmarcados like tbkpf occurs 10.
********pantalla de selección
select-options:
bukrs for vbkpf-bukrs memory id buk,
belnr for vbkpf-belnr,
gjahr for vbkpf-gjahr memory id gjr
default sy-datum(4).


selection-screen skip 1.
selection-screen begin of block 2 with frame title text-001.
select-options:
budat for vbkpf-budat,
bldat for vbkpf-bldat,
blart for vbkpf-blart,
xblnr for vbkpf-xblnr,
bktxt for vbkpf-bktxt,
usnam for vbkpf-usnam. "default sy-uname.
selection-screen end of block 2.

selection-screen begin of block 3 with frame title text-002.
select-options:
xwffr for vbkpf-xwffr,
xprfg for vbkpf-xprfg,
xfrge for vbkpf-xfrge.
selection-screen end of block 3.

**************eventos
initialization.
clear: gv_lineas, gv_veces.

at selection-screen.

start-of-selection.
set pf-status 'DELE' excluding 'BACK'.

call function 'AUTHORITY_CHECK_TCODE'
exporting
tcode = 'FBV0'
exceptions
ok = 1
others = 4.
if sy-subrc = 4.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
exit.
endif.

*Meto el select en un perform
perform seleccionar_vbkpf.

*Meto la impresión de la pantalla en otro perfrom
perform escribir_listado.

end-of-selection.


at user-command.
clear gv_belnr.
clear: char.
if count > 0.

case sy-ucomm.
when 'DELE'.
perform revisar_marcados. "Comprueba los marcados
set pf-status 'DELE'. "Habilita el botón “Back”
if xdele = space.
call function 'POPUP_TO_CONFIRM_LOSS_OF_DATA'
exporting
titel = text-003
textline1 = text-004
textline2 = space
importing
answer = char(1).
if char(1) = 'J'.
perform fbv0_dele.
xdele = 'X'.
else.
exit.
endif.
else.
message i899(f5) with text-007.
endif.
when 'BACK'.

exit.

when '&ONE'. "Marca/desmarca uno.
perform marcar_uno.

when '&ALL'. "Marcar todos
perform marcar_todos.

when '&SAL'.
perform desmarcar_todos.
* when 'BACK'.

when 'FRSH'. "Refrescar
if gv_veces lt 20. "Sólo se permiten 20 anidamientos
perform seleccionar_vbkpf.
perform escribir_listado.
else.
message e368(00) with text-e01.
endif.
when others.
exit.
endcase.
endif.

*&---------------------------------------------------------------------*
*& Form FBV0_DELE
*&---------------------------------------------------------------------* *
*& Find out, how document was parked (classically or by ENJOY)
*&---------------------------------------------------------------------* *

form fbv0_dele.
refresh messtab.
loop at tbkpf
"Añado condición
where tratar eq 'X'.
clear t020.
select single * from t020 where tcode = tbkpf-tcode.
if t020-gener = space. "parked by classical transaction
perform fbv0_dele1 using tbkpf-gjahr
tbkpf-belnr
tbkpf-bukrs.
else. "parked by ENJOY
perform fbv0_dele2 using tbkpf-gjahr
tbkpf-belnr
tbkpf-bukrs.
endif.
endloop.
check sy-subrc eq 0.
loop at messtab.
write: / messtab.
endloop.
endform. "FBV0_DELE

*&---------------------------------------------------------------------*
*& Form FBV0_DELE1
*&---------------------------------------------------------------------*
*& Classically parked documents
*&---------------------------------------------------------------------*

form fbv0_dele1 using i_gjahr like bkpf-gjahr
i_belnr like bkpf-belnr
i_bukrs like bkpf-bukrs.

data: xdate(10) type c.
refresh bdcdata.
perform bdc_dynpro using 'SAPMF05V'
'0100'.
perform bdc_field using 'BDC_OKCODE'
'/00'.
perform bdc_field using 'BDC_CURSOR'
'RF05V-GJAHR'.
perform bdc_field using 'RF05V-BUKRS'
i_bukrs.
perform bdc_field using 'RF05V-BELNR'
i_belnr.
perform bdc_field using 'RF05V-GJAHR'
i_gjahr.
perform bdc_dynpro using 'SAPLF040'
'0700'.
perform bdc_field using 'BDC_CURSOR'
'BKPF-XBLNR'.
perform bdc_field using 'BDC_OKCODE'
'BL'.
perform bdc_dynpro using 'SAPLSPO1'
'0200'.
perform bdc_field using 'BDC_CURSOR'
'SPOP-OPTION1'. "Button YES
perform bdc_field using 'BDC_OKCODE'
'ENTER'.

call transaction 'FBV0' using bdcdata
mode mode
update 'S'.

call function 'MESSAGE_TEXT_BUILD'
exporting
msgid = sy-msgid
msgnr = sy-msgno
msgv1 = sy-msgv1
msgv2 = sy-msgv2
msgv3 = sy-msgv3
msgv4 = sy-msgv4
importing
message_text_output = messtab
exceptions
others = 4.
append messtab.
endform. "FBV0_DELE2

*&---------------------------------------------------------------------*
*& Form fbv0_dele2
*&---------------------------------------------------------------------*
*& Documents parked by ENJOY
*&---------------------------------------------------------------------*

form fbv0_dele2 using i_gjahr
i_belnr
i_bukrs.
data: xdate(10) type c.
refresh bdcdata.
perform bdc_dynpro using 'SAPMF05V'
'0100'.
perform bdc_field using 'BDC_OKCODE'
'/00'.
perform bdc_field using 'BDC_CURSOR'
'RF05V-GJAHR'.
perform bdc_field using 'RF05V-BUKRS'
i_bukrs.
perform bdc_field using 'RF05V-BELNR'
i_belnr.
perform bdc_field using 'RF05V-GJAHR'
i_gjahr.

if t020-koart = 'D'.
perform bdc_dynpro using 'SAPMF05A'
'1200'.
perform bdc_field using 'BDC_CURSOR'
'INVFO-ACCNT'.
elseif t020-koart = 'K'.
perform bdc_dynpro using 'SAPMF05A'
'1100'.
perform bdc_field using 'BDC_CURSOR'
'INVFO-ACCNT'.
elseif t020-koart = 'S'.
perform bdc_dynpro using 'SAPMF05A'
'1001'.
perform bdc_field using 'BDC_CURSOR'
'ACGL_HEAD-BLDAT'.
endif.

perform bdc_field using 'BDC_OKCODE'
'=9-PD'.

perform bdc_dynpro using 'SAPLSPO1'
'0200'.
perform bdc_field using 'BDC_CURSOR'
'SPOP-OPTION1'. "Button YES
perform bdc_field using 'BDC_OKCODE'
'ENTER'.

call transaction 'FBV0' using bdcdata
mode mode
update 'S'.

call function 'MESSAGE_TEXT_BUILD'
exporting
msgid = sy-msgid
msgnr = sy-msgno
msgv1 = sy-msgv1
msgv2 = sy-msgv2
msgv3 = sy-msgv3
msgv4 = sy-msgv4
importing
message_text_output = messtab
exceptions
others = 4.

append messtab.

endform. " fbv0_dele2

*&---------------------------------------------------------------------*
*& Form BDC_DYNPRO
*&---------------------------------------------------------------------*
form bdc_dynpro using program dynpro.
clear bdcdata.
bdcdata-program = program.
bdcdata-dynpro = dynpro.
bdcdata-dynbegin = 'X'.
append bdcdata.
endform. "BDC_DYNPRO

*&---------------------------------------------------------------------*
*& Form BDC_FIELD
*&---------------------------------------------------------------------*
form bdc_field using fnam fval.
clear bdcdata.
bdcdata-fnam = fnam.
bdcdata-fval = fval.
append bdcdata.
endform. "BDC_FIELD
*&---------------------------------------------------------------------*
*& Form seleccionar_vbkpf
*&---------------------------------------------------------------------*
* Selección de datos de la tabla vbkpf
*----------------------------------------------------------------------*

form seleccionar_vbkpf .
*Añado into corresponding fields
*Y cambio este select...endselect por un select
*into corresponding fields of table y hacer count = sy-dbcnt

* select * from vbkpf into corresponding fields of tbkpf
* where ausbk in bukrs
* and belnr in belnr
* and gjahr in gjahr
* and budat in budat
* and bldat in bldat
* and blart in blart
* and bktxt in bktxt
* and xblnr in xblnr
* and usnam in usnam
* and bstat eq 'V'
* and xwffr in xwffr
* and xfrge in xfrge
* and xprfg in xprfg.
* append tbkpf.
* count = count + 1.
* endselect.
* sort tbkpf by ausbk belnr gjahr.

"La tabla, bien limpita
clear tbkpf. refresh tbkpf.

select * from vbkpf
into corresponding fields of table tbkpf
where ausbk in bukrs
and belnr in belnr
and gjahr in gjahr
and budat in budat
and bldat in bldat
and blart in blart
and bktxt in bktxt
and xblnr in xblnr
and usnam in usnam
and bstat eq 'V'
and xwffr in xwffr
and xfrge in xfrge
and xprfg in xprfg
order by ausbk belnr gjahr.
clear count.
count = sy-dbcnt.

endform. " seleccionar_vbkpf
*&---------------------------------------------------------------------*
*& Form escribir_listado
*&---------------------------------------------------------------------*
* Muestra por pantalla el contenido de TBKPF, salvo el campo
* TBKPF-TRATAR; en su lugar escribe un CHECKBOX
*----------------------------------------------------------------------*

form escribir_listado .

if count = 0.
write: /, text-005.
else.
write: /, text-006, count, /.
uline.
*Una cabecera

write:
* at 3(5) 'AUSBK',
* at 9(5) 'BUKRS',
* at 15(10) 'BELNR',
* at 26(7) 'GJAHR'.
at 3(5) 'Soc.',
at 9(5) 'Soc.',
at 15(10) 'Doc.',
at 26(9) 'Ejercicio'.
uline.

format hotspot on.
loop at tbkpf.
gv_check = space.
write:
/,
gv_check as checkbox, "No escribe de tabla...
at 3(5) tbkpf-ausbk,
at 9(5) tbkpf-bukrs,
at 15(10) tbkpf-belnr,
at 26(7) tbkpf-gjahr.
hide: tbkpf-tratar, tbkpf-belnr.
endloop.
gv_lineas = sy-linno.
endif.
add 1 to gv_veces.


endform. " escribir_listado
*&---------------------------------------------------------------------*
*& Form revisar_marcados
*&---------------------------------------------------------------------*
* Al activar un checkbox, no se genera evento (no hay fcode)
* en este perform se revisan las casillas que están marcadas
* y se actualiza la tabla tbkpf usando la tabla local lt_tbkpf.
*----------------------------------------------------------------------*

form revisar_marcados.

data: wa_linea(255) type c,
lt_tbkpf like tbkpf occurs 5 with header line,
wa_tbkpf like line of tbkpf,
lv_belnr(10) type c,
lv_tratar type c,
lv_long type i,
lv_times type i.

clear:
wa_linea, lv_belnr, lv_tratar, lv_long, lv_times, lt_tbkpf.
refresh lt_tbkpf.

do gv_lineas times.

read line sy-index line value into wa_linea.
"Comprobamos que sea una línea con "datos"
"Y también que se tenga que tratar dicha línea
if wa_linea+2(4) eq 'AENA' and
wa_linea(1) eq 'X'.
"Comprobamos el CHECKBOX
lv_tratar = wa_linea(1).
"COMPROBAMOS EL PEDIDO
lv_belnr = wa_linea+14(10).
lv_long = strlen( lv_belnr ).
lv_times = 10 - lv_long.
do lv_times times.
concatenate '0' lv_belnr into lv_belnr.
enddo.
read table tbkpf with key belnr = lv_belnr.
"Modificamos la tabla si es necesario
if sy-subrc eq 0. "Ha leído la tabla
tbkpf-tratar = lv_tratar.
move-corresponding tbkpf to lt_tbkpf.
append lt_tbkpf. clear lt_tbkpf.
endif.
"La tabla se ha modificado
endif.
enddo.


* "Ahora modifico la tabla
loop at lt_tbkpf.
loop at tbkpf where belnr = lt_tbkpf-belnr.
tbkpf-tratar = 'X'.
modify tbkpf.
endloop.
endloop.

endform. " revisar_marcados
*&---------------------------------------------------------------------*
*& Form marcar_todos
*&---------------------------------------------------------------------*
* Marca todos los checkboxes del listado
*----------------------------------------------------------------------*

form marcar_todos .

do gv_lineas times.

read line sy-index field value gv_check.
gv_check = 'X'.
modify line sy-index field value gv_check.

enddo.

endform. " marcar_todos
*&---------------------------------------------------------------------*
*& Form DESMARCAR_TODOS
*&---------------------------------------------------------------------*
* Desmarca todos los checkboxes del listado
*----------------------------------------------------------------------*
form desmarcar_todos .

do gv_lineas times.

read line sy-index field value gv_check.
gv_check = ' '.
modify line sy-index field value gv_check.

enddo.


endform. " DESMARCAR_TODOS

*&---------------------------------------------------------------------*
*& Form marcar_uno
*&---------------------------------------------------------------------*
* Marca un solo elemento,
* - cuando se selecciona una línea (ya que FORMAT HOTSPOT = ON)
* - cuando se pulsa el botón &ONE (actualmente deshabilitado)
*----------------------------------------------------------------------*

form marcar_uno .

data: lv_lilli like sy-lilli.
lv_lilli = sy-lilli.

read line sy-lilli field value gv_check.
if gv_check eq 'X'.
gv_check = space.
else.
gv_check = 'X'.
endif.

modify line lv_lilli field value gv_check.

endform. " marcar_uno

martes, 9 de octubre de 2007

Call Transaction VS. Submit

A la hora de llamar a un programa desde otro programa, si este es de tipo report y además tiene una transacción que lo ejecute, se puede emplear tanto un "CALL" como un "SUBMIT". ¿Cuáles son las diferencia entre uno y otro? Que yo sepa:


1. El CALL TRANSACTION puede llamar a cualquier tipo de programas, sólo hay que crearles una transacción (si no la tienen).


2. El CALL TRANSACTION permite usar una tabla de tipo BDCDATA, y simular un conjunto de acciones (como en un batch input). También permite usar parámetros.


3. El SUBMIT ejecuta el programa sin preguntar por la pantalla por defecto (es decir, si no se le pasan valores a los rangos, toma los que haya por defecto en el caso de que haya pantalla de selección). También permite el uso de parámetros.

Para ilustrarlo, he hecho el siguiente programita, que básicamente llama a la trasacción WE05 usando el primer número de idoc que encuentre ese día.


*&---------------------------------------------------------------------*
*& Report Z_AGH_CALL
*&
*&---------------------------------------------------------------------*
*& Tres ejemplos para llamar a una transacción.
*& Se usará de ejemplo la transacción WE05 y se le pasará el
*& Número de idoc
*&---------------------------------------------------------------------*
*& Alberto García de Haro
*& http://misprogramasabap.blogspot.com/
*&---------------------------------------------------------------------*
*& Textos de selección:
* P_BDC Call Transacion y bdcdata
* P_PAR Call Transaction y parámetros
* P_SUB Submit
*& Símbolos de texto
* 001 Opciones de ejecución
*&---------------------------------------------------------------------*
report z_agh_call.
*&---------------------------------------------------------------------*
*& TOP: variables, tablas internas, etc.
*&---------------------------------------------------------------------*
data: obj like edidc-docnum.
data: begin of i_bdc_data occurs 10.
include structure bdcdata.
data: end of i_bdc_data.
data: begin of i_rspar occurs 10.
include structure rsparams.
data: end of i_rspar.
tables:
usr02.
data: begin of i_users occurs 10.
include structure usr02.
data: end of i_users.
*&---------------------------------------------------------------------*
*& PANTALLA DE SELECCIÓN
*&---------------------------------------------------------------------*
selection-screen begin of block bl1 with frame title text-001.
parameters:
p_sub radiobutton group gr1,
p_par radiobutton group gr1,
p_bdc radiobutton group gr1.
selection-screen end of block bl1.
*&---------------------------------------------------------------------*
*& EVENTOS
*&---------------------------------------------------------------------*
start-of-selection.
perform seleccionar_idoc changing obj.

if p_sub eq 'X'.
perform llamada_submit.
elseif p_par eq 'X'.
perform llamada_parametros.
else. "debe ser p_bdc eq 'X'
perform llamada_bdcdata.
endif.
*&---------------------------------------------------------------------*
*& SUBRUTINAS
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form seleccionar_idoc
*&---------------------------------------------------------------------*
* Selecciona un número de idoc
*----------------------------------------------------------------------*
* <--P_OBJ nº de idoc
*----------------------------------------------------------------------*
form seleccionar_idoc changing p_obj.
data: fecha like sy-datum, d_cont type i. "Para usar la fecha
fecha = sy-datum.
clear d_cont.
do.
select single docnum into p_obj from edidc
where credat eq sy-datum.
if sy-subrc eq 0 or d_cont = 30.
"encontró un idoc O llegó a 30 días sin encontrar nada
exit.
endif.
****RESTAMOS UN DÍA
call function 'SUBTRACT_TIME_FROM_DATE'
exporting
i_idate = fecha
i_time = 1
i_iprkz = 'D'
importing
o_idate = fecha.
add 1 to d_cont.
enddo.
endform. " seleccionar_idoc
*&---------------------------------------------------------------------*&
*& Form llamada_submit
*&---------------------------------------------------------------------
**& Llamada con la sentencia submit
*----------------------------------------------------------------------*
form llamada_submit .
ranges ndocc for edidc-docnum.
clear: ndocc.
move:
'I' to ndocc-sign,
'EQ' to ndocc-option,
obj to ndocc-low.
append ndocc.

submit rseidoc2 with docnum in ndocc
and return.

endform. " llamada_submit
*&---------------------------------------------------------------------*
*& Form llamada_parametros
*&---------------------------------------------------------------------*
Llamada con call transaction y parámetros
*----------------------------------------------------------------------*
form llamada_parametros .
set parameter id 'DCN' field obj.
call transaction 'WE05'.
endform. " llamada_parametros
*&---------------------------------------------------------------------*
*& Form llamada_bdcdata
*&---------------------------------------------------------------------*
Llamada con call transaction y bdc_data
*----------------------------------------------------------------------*

form llamada_bdcdata .

*Llenamos la tabla
refresh i_bdc_data.
i_bdc_data-program = 'RSEIDOC2'.
i_bdc_data-dynpro = '1000'.
i_bdc_data-dynbegin = 'X'.
append i_bdc_data. clear i_bdc_data.


i_bdc_data-fnam = 'DOCNUM-LOW'.
i_bdc_data-fval = obj.
append i_bdc_data. clear i_bdc_data.

call transaction 'WE05' using i_bdc_data.

endform. " llamada_bdcdata

jueves, 9 de agosto de 2007

z_ordenes

El siguiente report modifica el de Álvaro Tejada, porque lo copié tal cual y no me compilaba. Le metes un programa o transacción, y te dice las órdenes de transporte que afectan a dicho programa; muy útil si tienes que hacer un listado de las órdenes que has liberado y no tienes ni idea, sobre todo en empresas donde el usuario de desarrollo es para varias personas.

report z_ordenes.
*-----------------------------------------------------------------*
* Lista las órdenes de transporte de un programa o transacción *
* p_tcode --> transacción *
* p_pgmna --> programa *
*-----------------------------------------------------------------*
* Alberto García de Haro, 09/08/2007 *
*-----------------------------------------------------------------*


*-----------------------------------------------------------------*
* DECLARACION DE TYPES *
*-----------------------------------------------------------------*
types: begin of ty_e071,
trkorr type e071-trkorr,
object type e071-object,
obj_name type e071-obj_name,
end of ty_e071.

types: begin of ty_e071_entry,
trkorr type e071-trkorr,
end of ty_e071_entry.

types: begin of ty_e070,
trkorr type e070-trkorr,
trstatus type e070-trstatus,
tarsystem type e070-tarsystem,
as4user type e070-as4user,
as4date type e070-as4date,
as4time type e070-as4time,
as4text type e07t-as4text,
end of ty_e070.

types: begin of ctslg_action,
date like tstrfcofil-trdate,
time like tstrfcofil-trtime,
rc like tstrfcofil-retcode,
end of ctslg_action,

ctslg_actions type sorted table of ctslg_action
with unique key date time
initial size 2,

begin of ctslg_step,
clientid like tstrfcofil-tarclient,
stepid like tstrfcofil-function,
rc like tstrfcofil-retcode,
actions type ctslg_actions,
end of ctslg_step,

ctslg_steps type ctslg_step occurs 10,

begin of ctslg_system,
systemid like tstrfcofil-tarsystem,
rc like tstrfcofil-retcode,
steps type ctslg_steps,
end of ctslg_system,

ctslg_systems type ctslg_system occurs 10,

begin of ctslg_mergeline,
trkorr type trkorr,
rc like tstrfcofil-retcode,
end of ctslg_mergeline,

ctslg_mergelines type ctslg_mergeline occurs 0,

begin of ctslg_cofile,
exists type c,
imported type c,
del_lines_only type c,
systems type ctslg_systems,
merges type ctslg_mergelines,
rc type i,
end of ctslg_cofile.

*-----------------------------------------------------------------*
* DECLARACION DE TABLAS INTERNAS *
*-----------------------------------------------------------------*
data: t_e071 type standard table of ty_e071 with header line,
t_e070 type standard table of ty_e070 with header line,
t_e071_entry type standard table of ty_e071_entry
with header line,
doma_values type standard table of rpy_dval
with header line,
es_cofile type standard table of ctslg_cofile
with header line,
es_systems type standard table of ctslg_system,
wa_systems type ctslg_systems with header line,
es_steps type ctslg_steps,
wa_steps type ctslg_steps with header line,
es_actions type ctslg_actions,
wa_actions type ctslg_actions with header line.

*-----------------------------------------------------------------*
* DECLARACION DE VARIABLES *
*-----------------------------------------------------------------*
data: w_pgmna type tstc-pgmna,
w_name(41) type c,
w_flag type c.

*-----------------------------------------------------------------*
* DECLARACION DE FIELD-SYMBOLS *
*-----------------------------------------------------------------*
field-symbols: like line of t_e071,
like line of t_e070.

*-----------------------------------------------------------------*
* SELECTION-SCREEN *
*-----------------------------------------------------------------*
selection-screen begin of block data.
parameters:
p_tcode like tstc-tcode,
p_pgmna like tstc-pgmna.
selection-screen end of block data.

*-----------------------------------------------------------------*
* START-OF-SELECTION *
*-----------------------------------------------------------------*
start-of-selection.

perform validar_entrada.
if w_flag eq space.
perform obtener_ordenes.
perform imprimir_ordenes.
endif.

*&----------------------------------------------------------------*
*& Form VALIDAR_ENTRADA *
*&----------------------------------------------------------------*
form validar_entrada.

if p_tcode ne space.
select single pgmna
into w_pgmna
from tstc
where tcode eq p_tcode.
if sy-subrc eq 0.
w_flag = space.
else.
message s368(00) with 'La transacción solicitada no existe'.
w_flag = 'X'.
endif.
elseif p_pgmna ne space.
select single pgmna
into w_pgmna
from tstc
where pgmna eq p_pgmna.
if sy-subrc eq 0.
w_flag = space.
else.
message s368(00) with 'El programa solicitado no existe'.
w_flag = 'X'.
endif.
endif.

endform. " VALIDAR_ENTRADA

*&----------------------------------------------------------------*
*& Form OBTENER_ORDENES *
*&----------------------------------------------------------------*
form obtener_ordenes.

call function 'RPY_DOMAIN_READ'
exporting
doma_name = 'TRSTATUS'
language = sy-langu
tables
doma_values = doma_values
exceptions
cancelled = 1
not_found = 2
permission_error = 3
illegal_type = 4
others = 5.
if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.


concatenate w_pgmna '%'
into w_name.

select trkorr object obj_name
into table t_e071
from e071
where obj_name like w_name
and object eq 'REPS'.

if not t_e071[] is initial.
loop at t_e071 assigning .
move to t_e071_entry.
append t_e071_entry.
endloop.

sort t_e071_entry.
delete adjacent duplicates from t_e071_entry.

if not t_e071_entry[] is initial.
select e070~trkorr trstatus tarsystem
as4user as4date as4time
as4text
into table t_e070
from ( e070 inner join e07t
on e070~trkorr eq e07t~trkorr )
for all entries in t_e071_entry
where e070~trkorr eq t_e071_entry-trkorr
and langu eq sy-langu.

sort t_e070 by as4date as4time descending.

endif.
endif.

endform. " OBTENER_ORDENES

*&----------------------------------------------------------------*
*& Form IMPRIMIR_ORDENES *
*&----------------------------------------------------------------*
form imprimir_ordenes.

data: w_trkorr type e070-trkorr.

write:
1 'Orden' ,12 'Estado',
22 'Destino', 31 'Nombre',92 'Fecha',104 'Hora'.

loop at t_e070 assigning .

clear: es_cofile.
refresh: es_cofile.

call function 'TR_READ_GLOBAL_INFO_OF_REQUEST'
exporting
iv_trkorr = -trkorr
iv_dir_type = 'T'
importing
es_cofile = es_cofile.

append es_cofile.
read table es_cofile index 1.
move es_cofile-systems to es_systems.
loop at es_systems into wa_systems.
move wa_systems-steps to es_steps.
loop at es_steps into wa_steps. "WHERE STEPID EQ 'G'.
move wa_steps-actions to es_actions.
loop at es_actions into wa_actions.
endloop.
read table doma_values
with key domvalue_l = -trstatus.

if w_trkorr ne -trkorr.
w_trkorr = -trkorr.
skip 1.
endif.

write:/1 -trkorr,12 doma_values-ddtext,
22 wa_systems-systemid,31 -as4text,
92 wa_actions-date,104 wa_actions-time.
endloop.
endloop.

endloop.
endform. " IMPRIMIR_ORDENES

lunes, 11 de junio de 2007

ALV Jerárquico

REPORT zalv_jerarquico.
* Por: Jorge Serra (AbapLife)
http://abaplife.bitacoras.com
* Se trata de una ejemplo de listado ALV jerarquico.
* Propósito:

* ---------
* Voy mostrar un listado de pedidos de compras (datos de cabecera)
* y sus posiciones (datos de posicion)
* Pasos esenciales (Buscar el simbolo '§')

* ----------------
* 1. Definición estructuras y tablas necesarias
* 2. Definimos las tablas con los datos de salida
* 3. Toma de datos
* 4. Definición estructura y formato de salida
* 5. Mostrar listado
*<-- § Paso 1. Definicion estructuras y tablas necesarias
* Type Pool donde vienen definidas todas las estructuras y tablas

TYPE-POOLS: slis.
* Catálogo de campos: contiene la descripción de los campos de salida
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE,
* Especificaciones de la disposición de la lista: descripción de la
* estructura de salida
gs_layout TYPE slis_layout_alv,
* Relacion entre los datos de cabecera y posicion
gs_key TYPE slis_keyinfo_alv,
* Nombre del programa g_repid LIKE sy-repid.
*<-- § Paso 2. Definimos las tablas con los datos de salida

TYPES: BEGIN OF st_header.
INCLUDE STRUCTURE ekko.
TYPES: END OF st_header.
TYPES: BEGIN OF st_item.

INCLUDE STRUCTURE ekpo.
TYPES: END OF st_item.
DATA:

gt_header TYPE STANDARD TABLE OF st_header WITH HEADER LINE,
gt_item TYPE STANDARD TABLE OF st_item WITH HEADER LINE.
INITIALIZATION.
g_repid = sy-repid.
START-OF-SELECTION.
*<-- § Paso 3. Toma de datos

PERFORM toma_datos.
*<-- § Paso 4. Estructura y formato de salida

PERFORM init_fieldcat.
PERFORM init_layout.
PERFORM init_key.
*<-- § Paso 5. Mostrar listado

PERFORM listado.
*&&-----------------------------------------------------------------&&*

* SUBRUTINAS DEL PROGRAMA *
*&&-----------------------------------------------------------------&&*
*---------------------------------------------------------------------*

* FORM INIT_FIELDCAT *
*---------------------------------------------------------------------*
FORM init_fieldcat.
* Mediante esta tabla vamos a definir los campos que queremos mostrar

* en el listado de salida.
gt_fieldcat-fieldname = 'EBELN'.

gt_fieldcat-tabname = 'GT_HEADER'.
gt_fieldcat-ref_tabname = 'EKKO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'EBELN'.

gt_fieldcat-tabname = 'GT_ITEM'.
gt_fieldcat-ref_tabname = 'EKPO'.
gt_fieldcat-no_out = 'X'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'EBELP'.

gt_fieldcat-tabname = 'GT_ITEM'.
gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'MATNR'.

gt_fieldcat-tabname = 'GT_ITEM'.
gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'WERKS'.

gt_fieldcat-tabname = 'GT_ITEM'.
gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'MENGE'.

gt_fieldcat-tabname = 'GT_ITEM'.
gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'MEINS'.

gt_fieldcat-tabname = 'GT_ITEM'.
gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
ENDFORM.
*---------------------------------------------------------------------*

* FORM INIT_LAYOUT *
*---------------------------------------------------------------------*
FORM init_layout.
* Mediante esta estructura podemos definir el formato de salida

gs_layout-zebra = 'X'.
gs_layout-f2code = '&ETA'.
gs_layout-detail_popup = 'X'.
ENDFORM.
*---------------------------------------------------------------------*

* FORM TOMA_DATOS *
*---------------------------------------------------------------------*
FORM toma_datos.
* Los datos deben guardarse en la tabla interna de salida

SELECT * FROM ekko
UP TO 100 ROWS
INTO TABLE gt_header.
SELECT * FROM ekpo

INTO TABLE gt_item
FOR ALL ENTRIES IN gt_header
WHERE ebeln = gt_header-ebeln.
ENDFORM. " TOMA_DATOS
*---------------------------------------------------------------------*

* FORM LISTADO *
*---------------------------------------------------------------------*
FORM listado.
CALL FUNCTION 'REUSE_ALV_HIERSEQ_LIST_DISPLAY'

EXPORTING
* I_INTERFACE_CHECK = ' '
i_callback_program = g_repid
* I_CALLBACK_PF_STATUS_SET = ' '
* I_CALLBACK_USER_COMMAND = ' '
is_layout = gs_layout
it_fieldcat = gt_fieldcat[]
* IT_EXCLUDING =
* IT_SPECIAL_GROUPS =
* IT_SORT =
* IT_FILTER =
* IS_SEL_HIDE =
* I_SCREEN_START_COLUMN = 0
* I_SCREEN_START_LINE = 0
* I_SCREEN_END_COLUMN = 0
* I_SCREEN_END_LINE = 0
* I_DEFAULT = 'X'
* I_SAVE = ' '
* IS_VARIANT =
* IT_EVENTS =
* IT_EVENT_EXIT =
i_tabname_header = 'GT_HEADER'
i_tabname_item = 'GT_ITEM'
* I_STRUCTURE_NAME_HEADER =
* I_STRUCTURE_NAME_ITEM =
is_keyinfo = gs_key
* IS_PRINT =
* IS_REPREP_ID =
* I_BUFFER_ACTIVE =
* I_BYPASSING_BUFFER =
* IMPORTING
* E_EXIT_CAUSED_BY_CALLER =
* ES_EXIT_CAUSED_BY_USER =
TABLES
t_outtab_header = gt_header[]
t_outtab_item = gt_item[]
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2 .
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM. " LISTADO
*---------------------------------------------------------------------*

* FORM INIT_KEY *
*---------------------------------------------------------------------*
FORM init_key.
* Relacion entre los campos de cabecera y los de posicion

gs_key-header01 = 'EBELN'.
gs_key-item01 = 'EBELN'.
ENDFORM. " INIT_KEY

ALV Simple

REPORT zalv_simple.
* Jorge Serra (AbapLife) http://abaplife.bitacoras.com
* Se trata de un pequeño ejemplo de listado ALV para aquellos que nunca
* han creado uno. Por supuesto, a los que ya sepáis algo de ALV, no
* creo que os sirva de mucho
* Propósito:

* ---------
* Voy mostrar un listado de posiciones de pedidos de compras
* Pasos esenciales (Buscar el simbolo '§')
* ----------------
* 1. Definición estructuras y tablas necesarias
* 2. Definimos la tabla con los datos de salida
* 3. Toma de datos
* 4. Definición estructura y formato de salida
* 5. Mostrar listado
*<-- § Paso 1. Definicion estructuras y tablas necesarias
* Type Pool donde vienen definidas todas las estructuras y tablas
TYPE-POOLS: slis.
* Catálogo de campos: contiene la descripción de los campos de salida
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE,
* Especificaciones de la disposición de la lista: descripción de la
* estructura de salida
gs_layout TYPE slis_layout_alv,
* Nombre del programa g_repid LIKE sy-repid.
*<-- § Paso 2. Definimos la tabla con los datos de salida
TYPES: BEGIN OF st_output.
INCLUDE STRUCTURE ekpo.
TYPES: END OF st_output.
DATA: gt_output TYPE STANDARD TABLE OF st_output WITH HEADER LINE.
INITIALIZATION. g_repid = sy-repid.
START-OF-SELECTION.
*<-- § Paso 3. Toma de datos
PERFORM toma_datos.
*<-- § Paso 4. Estructura y formato de salida
PERFORM init_fieldcat.
PERFORM init_layout.
*<-- § Paso 5. Mostrar listado
PERFORM listado.
*&&-----------------------------------------------------------------&&*
* SUBRUTINAS DEL PROGRAMA*
*&&-----------------------------------------------------------------&& *
*---------------------------------------------------------------------*
* FORM INIT_FIELDCAT *
*---------------------------------------------------------------------*
FORM init_fieldcat.
* Mediante esta tabla vamos a definir los campos que queremos mostrar
* en el listado de salida.
gt_fieldcat-fieldname = 'EBELN'.
gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'EBELP'.
gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'MATNR'. gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'WERKS'. gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat.
gt_fieldcat-fieldname = 'MENGE'. gt_fieldcat-ref_tabname = 'EKPO'.
APPEND gt_fieldcat. CLEAR gt_fieldcat. gt_fieldcat-fieldname = 'MEINS'.
gt_fieldcat-ref_tabname = 'EKPO'. APPEND gt_fieldcat. CLEAR gt_fieldcat.
ENDFORM.
*---------------------------------------------------------------------*
* FORM INIT_LAYOUT *
*---------------------------------------------------------------------*
FORM init_layout.
* Mediante esta estructura podemos definir el formato de salida
gs_layout-zebra = 'X'.
gs_layout-f2code = '&ETA'.
gs_layout-detail_popup = 'X'.
ENDFORM.
*---------------------------------------------------------------------*
* FORM TOMA_DATOS *
*---------------------------------------------------------------------*
FORM toma_datos.
* Los datos deben guardarse en la tabla interna de salida
SELECT * FROM ekpo UP TO 100 ROWS INTO TABLE gt_output.
ENDFORM. " TOMA_DATOS
*---------------------------------------------------------------------*
* FORM LISTADO *
*---------------------------------------------------------------------*
FORM listado.
CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'
EXPORTING
i_callback_program = g_repid
is_layout = gs_layout
it_fieldcat = gt_fieldcat[]
TABLES t_outtab = gt_output
EXCEPTIONS program_error = 1
OTHERS = 2 .
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM. " LISTADO



lunes, 28 de mayo de 2007

Segunda Parte

Curioso que a un informático le roben sus cuentas de yahoo, hotmail y gmail. Para acabar el chiste, me robaron mis blogs (este, y otro que tenía más personal). El lado bueno, si es que lo hay, es que puedo crearlos de nuevo (ya que los han borrado), aunque eso sí, desde cero. Qué se le va a hacer, como decimos en España, más se perdió en Cuba.
Las ganas que tengo de ponerme a escribir entradas son mínimas, pero por lo menos tengo mis blogs. Vacíos, eso sí, pero los tengo. A ver qué puedo hacer...