VF31: Impresión masiva de facturas por folio legal?
Si bien la transacción VF31 se ejecuta para visualizar o imprimir una sola factura/boleta al cliente o para imprimir varias facturas/boletas a la vez...
Sucede el caso que deseamos imprimir por número de folio legal(número correlativo) pero al ingresar a la transacción VF31 en la pantalla de selección observamos que no considera la búsqueda por número de folio legal...
Entonces lo que hacemos por lo general es ingresar a la transacción VF03 visualizar la factura y obtener el nro de folio legal o también ingresar a la tabla VBRK(Factura: Datos de cabecera) ingresar el nro de factura (doc. SAP) en el campo VBRK-VBELN y obtener el dato del 'nro de folio legal' del campo VBRK-XBLNR (Número de documento de referencia).
Entonces lo que hacemos por lo general es ingresar a la transacción VF03 visualizar la factura y obtener el nro de folio legal o también ingresar a la tabla VBRK(Factura: Datos de cabecera) ingresar el nro de factura (doc. SAP) en el campo VBRK-VBELN y obtener el dato del 'nro de folio legal' del campo VBRK-XBLNR (Número de documento de referencia).
Bueno en esta oportunidad voy a presentar un desarrollo Z en la cual simula la máscara (pantalla de selección) de la VF31 con el plus que ahora si considerará la búsqueda por nro de folio legal(número correlativo) y como las facturas que podemos obtener de la búsqueda consideran varias clases de mensaje diferentes inclusive para un mismo correlativo (folio legal) haremos que luego de ejecutar la VF31 en el ALV se muestre la columna REFERENCIA (folio legal) para de esta manera corroborar lo que se va imprimir en forma masiva sin ya tener que ingresar el documento SAP de la factura para verificar su correspondiente folio legal.
La pantalla de selección TCODE: VF31 tiene la siguiente presentación:
Simularemos ingresar algunos datos:
Y si ejecutamos el ALV nos presenta de la siguiente forma:
Como podemos observar en la pantalla de selección no aparece la búsqueda por folio legal ni tampoco en el ALV se visualiza el campo Referencia, por tanto plantearemos lo siguiente:
Objetivos técnicos:
- Ajustar la pantalla de selección, agregando búsqueda de selección múltiple por folio legal
- Añadir una columna en el ALV donde se mostrará el valor del folio legal
Demo de la visualización de la pantalla de Selección:
Demo de la visualización del ALV con la nueva columna 'Referencia':
En cuanto al desarrollo (código ABAP) recuerden que cada caso es diferente y recomiendo siempre antes ver la viabilidad de cuál más nos conviene utilizar para dar solución al escenario que nos presentan.
Les comento por ejemplo que para algunos consultores SAP al tener este escenario rápidamente se les puede venir la idea de utilizar un Batch Input y que este llame a la transacción VF31.
En particular para dar solución a este escenario no fue necesario el uso de un Batch Input mas bien reutilizaremos gran parte del mismo código del programa: SD70AV3A (TCODE: VF31) e iremos ajustando el código para cumplir con los objetivos ya mencionados.
El programa SD70AV3A para visualizar el ALV su catálogo de campos es en base a la estructura estándar NALIV3
Ahora como queremos que también se visualice el valor del folio legar hemos creado una estructura Z con nombre: ZSSD_ZNALIV3 la cual contiene al nuevo campo XBLNR para tener en cuenta el valor del nro de folio legal.
Aqui les presento el código fuente:
En mi caso he creado el programa con nombre: ZSDP027
*&---------------------------------------------------------------------*
*& Include ZSDP027_TOP
*&---------------------------------------------------------------------*
* constants*&---------------------------------------------------------------------*
*& Include ZSDP027_TOP
*&---------------------------------------------------------------------*
CONSTANTS: appl(2) VALUE 'V3',
actvt(2) VALUE '04', " activity for output processing
true VALUE 'X',
false VALUE ' '.
CONSTANTS: parvw_ag LIKE vrkpa-parvw VALUE 'AG', "Auftraggeber
parvw_rg LIKE vrkpa-parvw VALUE 'RG'. "Regulierer
* tables
TABLES: nase, vbrk, kna1, tpart.
* Mod Hans
TABLES: vrkpa.
*INIaa +AALCANTARA +@aaq 20140919
TYPES: BEGIN OF gty_vbrk,
vbeln TYPE vbeln_vf,
xblnr TYPE xblnr_v1,
END OF gty_vbrk.
*FINaa +AALCANTARA +@aaq 20140919
DATA: BEGIN OF lt_vrkpa OCCURS 50.
INCLUDE STRUCTURE vrkpa.
DATA: END OF lt_vrkpa.
DATA: BEGIN OF lt_vbrk OCCURS 50.
INCLUDE STRUCTURE vbrk.
DATA: END OF lt_vbrk.
* Mod Hans
* inttabs
DATA: msgs LIKE msg0 OCCURS 100 WITH HEADER LINE,
disp LIKE naliv3 OCCURS 100 WITH HEADER LINE.
DATA: BEGIN OF auth OCCURS 100,
vkorg LIKE vbrk-vkorg,
aflag TYPE c,
END OF auth.
DATA: BEGIN OF autf OCCURS 100,
fkart LIKE vbrk-fkart,
aflag TYPE c,
END OF autf.
DATA: gt_znaliv3 TYPE TABLE OF zssd_znaliv3, "+@aaq 20140919
gt_vbrk TYPE TABLE OF gty_vbrk."+@aaq 20140919
* field-symbols
FIELD-SYMBOLS: <gt_znaliv3> LIKE LINE OF gt_znaliv3,"+@aaq 20140919
<gt_vbrk> LIKE LINE OF gt_vbrk."+@aaq 20140919
* fields
DATA: repid LIKE sy-repid,
nodia TYPE c.
* range (for conversion of parameter
RANGES: rg_objky FOR nast-objky,
rg_fktyp FOR vbrk-fktyp,
rg_land1 FOR vbrk-land1,
rg_spart FOR vbrk-spart,
rg_vkorg FOR vbrk-vkorg,
rg_vtweg FOR vbrk-vtweg.
Explicación del código ZSDP027_TOP
Dentro del include ZSDP027_TOP he añadido la declaración del tipo global GTY_VBRK la cual contiene 2 campos: VBELN y XBLNR para factura SAP y folio legal respectivamente:
En las líneas 50 y 51 se ha declarado 2 tablas internas:
GT_ZNALIV3 para que el catálogo de campos del alv sea según la estructura ZSSD_ZNALIV3
GT_VBRK para tener los valores de las 'facturas doc. SAP' (VBELN) y su folio legal (XBLNR)
En las líneas 55 y 56 se ha declarado 2 field-symbols que apuntará a las tablas internas GT_ZNALIV3 y GT_VBRK respectivamente.
*&---------------------------------------------------------------------*
*& Include ZSDP027_SEL
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
* A. selection screen *
*----------------------------------------------------------------------*
* restricted F4-help to message (output) types of the application
INITIALIZATION.
nase-kappl = appl.
SELECTION-SCREEN BEGIN OF BLOCK message WITH FRAME TITLE text-001.
SELECT-OPTIONS:
rg_kschl FOR nase-kschl MEMORY ID nac,
rg_nacha FOR nase-nacha.
PARAMETERS:
pm_nsort LIKE nase-sorv3 DEFAULT '01' OBLIGATORY,
pm_vermo TYPE na_vermo_new DEFAULT '1' OBLIGATORY,
pm_verdi LIKE nase-verdi NO-DISPLAY.
SELECTION-SCREEN END OF BLOCK message.
SELECTION-SCREEN SKIP.
* A2. billing
SELECTION-SCREEN BEGIN OF BLOCK application WITH FRAME TITLE text-002.
*INIaa +@aaq 20140919
PARAMETERS: rb_xblnr RADIOBUTTON GROUP rb1 DEFAULT 'X' USER-COMMAND uc1,
rb_vbeln RADIOBUTTON GROUP rb1.
*FINaa +@aaq 20140919
SELECT-OPTIONS:
rg_bukrs FOR vbrk-bukrs MODIF ID gp2,
rg_gjahr FOR vbrk-gjahr MODIF ID gp2,
rg_poper FOR vbrk-poper MODIF ID gp2,
rg_vbeln FOR vbrk-vbeln MEMORY ID vf MODIF ID gp1,
rg_xblnr FOR vbrk-xblnr MODIF ID gp2, "+@aaq 20140919
rg_fkdat FOR vbrk-fkdat MEMORY ID dvo.
PARAMETERS:
pm_allel LIKE vbco7-allel DEFAULT true,
pm_allea LIKE vbco7-allea DEFAULT true,
pm_alleb LIKE vbco7-alleb,
pm_allei LIKE vbco7-allei,
pm_allef LIKE vbco7-allef,
pm_alled LIKE vbco7-allef.
PARAMETERS:
pm_vkorg LIKE vbrk-vkorg MEMORY ID vko,
pm_vtweg LIKE vbrk-vtweg MEMORY ID vtw,
pm_spart LIKE vbrk-spart MEMORY ID spa.
SELECT-OPTIONS:
rg_kunag FOR vbrk-kunag MATCHCODE OBJECT debi,
rg_kunrg FOR vbrk-kunag MATCHCODE OBJECT debi.
PARAMETERS:
pm_land1 LIKE vbrk-land1 MEMORY ID vll.
SELECTION-SCREEN END OF BLOCK application.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN BEGIN OF BLOCK selection WITH FRAME TITLE text-003.
PARAMETERS:
n_select TYPE na_sel_nast RADIOBUTTON GROUP slct,
f_select TYPE na_sel_vbrk RADIOBUTTON GROUP slct.
SELECTION-SCREEN END OF BLOCK selection
.
* It's difficult to transfer billing numbers to objectkeys in order
* to get position messages too. Therfore only a single value or an
* intervall is allowed.
AT SELECTION-SCREEN ON rg_vbeln.
LOOP AT rg_vbeln.
IF ( rg_vbeln = 'E' ) OR
( ( rg_vbeln-option <> 'EQ' ) AND ( rg_vbeln-option <> 'BT' ) ).
MESSAGE e076(vn).
ENDIF.
ENDLOOP.
Explicación del código ZSDP027_SEL
En la definición de los parámetros para la pantalla de selección se ha añadido la opción de búsqueda por factura SAP y por Folio Legal de manera que en pantalla tengamos 2 radios buttons a elegir sólo uno de ellos:
- RB_XBLNR (Buscar por Folio Legal)
- RB_VBELN (Buscar por Factura Doc. SAP)
También se ha añadido como parámetro de selección múltiple la declaración de: RG_XBLNR que es donde se almacenará los valores de los folios legales que se ingrese por pantalla.
*& Include ZSDP027_MAI
*&---------------------------------------------------------------------*
**----------------------------------------------------------------------*
** AT SELECTION-SCREEN OUTPUT.
**----------------------------------------------------------------------*
AT SELECTION-SCREEN OUTPUT.
IF rb_vbeln = 'X'."Imprimir Facturas por Documento SAP
LOOP AT SCREEN.
IF screen-group1 = 'GP1'.
screen-active = '1'. "Visualiza la selección múltiple de Documento de facturación
MODIFY SCREEN.
ELSEIF screen-group1 = 'GP2'.
"Oculta todos los parámetros del grupo G2 (RG_BUKRS, RG_GJAHR, RG_POPER y RG_XBLNR
"Oculta todos los parámetros del grupo G2 (RG_BUKRS, RG_GJAHR, RG_POPER y RG_XBLNR
screen-active = '0'.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ELSEIF rb_xblnr EQ 'X'."Imprimir Facturas por Folio Legal
LOOP AT SCREEN.
IF screen-group1 = 'GP1'.
screen-active = '0'. "Oculta la selección múltiple de Documento de facturación
MODIFY SCREEN.
ELSEIF screen-group1 = 'GP2'.
"Visualiza todos los parámetros del grupo G2 (RG_BUKRS, RG_GJAHR, RG_POPER y RG_XBLNR
"Visualiza todos los parámetros del grupo G2 (RG_BUKRS, RG_GJAHR, RG_POPER y RG_XBLNR
screen-active = '1'.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ENDIF.
*FINIaa +@aaq 20140919* B. main program *
*----------------------------------------------------------------------*
START-OF-SELECTION.
DATA: lv_vermo TYPE na_vermo_new,
lv_error TYPE flag.
*INIaa +@aaq 20140919
IF rb_xblnr EQ 'X'. "Si se seleccionó la opción: 'Buscar por Folio Legal'
PERFORM load_folios. "Obtenemos todos los folios legales y sus respectivas facturas doc. SAP
ENDIF.
IF NOT rg_vbeln[] IS INITIAL.
PERFORM parameter_convert.
ELSE.
MESSAGE 'No se encontraron datos' TYPE 'S' DISPLAY LIKE 'E'.
lv_error = 'X'.
ENDIF.
CHECK lv_error NE 'X'.
*FINaa +@aaq 20140919
IF f_select = true.
PERFORM messages_invoic.
ENDIF.
IF pm_vermo = 3.
CALL FUNCTION 'WFMC_MESSAGES_SELECT_ALL_FALSE'
EXPORTING
pi_application = appl
pi_vsztp = ' '
TABLES
ri_medium = rg_nacha
ri_type = rg_kschl
ri_object = rg_objky
tx_messages = msgs.
ELSE.
IF pm_vermo = 4.
lv_vermo = 3.
ELSE.
lv_vermo = pm_vermo.
ENDIF.
CALL FUNCTION 'WFMC_MESSAGES_SELECT'
EXPORTING
pi_application = appl
pi_processing = lv_vermo
TABLES
ri_medium = rg_nacha
ri_type = rg_kschl
ri_object = rg_objky
tx_messages = msgs.
ENDIF.
IF f_select = false.
PERFORM messages_filter.
ENDIF.
CALL FUNCTION 'WFMC_MESSAGES_EXTEND'
TABLES
tx_messages = msgs.
PERFORM display_prepare.
IF NOT sy-batch IS INITIAL.
pm_verdi = true.
ENDIF.
"Ajustamos para que la tabla interna GT_ZNALIV3 contenga los folios legales (XBLNR)
PERFORM get_folios_msgs TABLES gt_znaliv3. "+@aaq 20140919
CALL FUNCTION 'WFMC_MESSAGES_PROCESS'
EXPORTING
* pi_display_id = 'NALIV3' "-@aaq 20140919
"Indicamos nuestra estructura la cual contiene al campo XBLNR (folio legal)
pi_display_id = 'ZSSD_ZNALIV3'"+@aaq 20140919
pi_no_dialog = pm_verdi
pi_vermo = pm_vermo
TABLES
tx_messages = msgs
* tx_display = disp. "-@aaq 20140919
"Indicamos nuestra la tabla interna GT_ZNALIV3 la cual contiene los valores en la columna del folio legal en la columna XBLNR
tx_display = gt_znaliv3. "-@aaq 20140919
*&---------------------------------------------------------------------*
*& Include ZSDP027_F01
*&---------------------------------------------------------------------*
*---------------------------------------------------------------------*
* FORM MESSAGES_FILTER *
*---------------------------------------------------------------------*
* filter messages *
*---------------------------------------------------------------------*
FORM messages_filter.
DATA: flag TYPE c,
lt_msgs_sort TYPE SORTED TABLE OF msg0
WITH NON-UNIQUE KEY objky kschl.
FIELD-SYMBOLS:
<fs_msgs> TYPE msg0.
SORT msgs BY objky kschl.
lt_msgs_sort = msgs[].
LOOP AT lt_msgs_sort ASSIGNING <fs_msgs>.
*--- only check new ones due to mass deletion
CHECK <fs_msgs>-objky(10) NE vbrk-vbeln.
flag = true.
*--- select from VBRK
SELECT SINGLE * FROM vbrk
WHERE vbeln = <fs_msgs>-objky(10) AND
fktyp IN rg_fktyp AND
fkdat IN rg_fkdat AND
vkorg IN rg_vkorg AND
vtweg IN rg_vtweg AND
spart IN rg_spart AND
kunag IN rg_kunag AND
kunrg IN rg_kunrg AND
land1 IN rg_land1.
IF sy-subrc <> 0.
flag = false.
ENDIF.
*--- check authorization concerning VKORG
IF flag NE false.
READ TABLE auth WITH KEY vkorg = vbrk-vkorg BINARY SEARCH.
IF sy-subrc <> 0.
auth-vkorg = vbrk-vkorg.
AUTHORITY-CHECK OBJECT 'V_VBRK_VKO'
ID 'VKORG' FIELD auth-vkorg
ID 'ACTVT' FIELD actvt.
IF sy-subrc = 0.
auth-aflag = true.
ELSE.
auth-aflag = false.
flag = false.
ENDIF.
INSERT auth INDEX sy-tabix.
ELSEIF auth-aflag = false.
flag = false.
ENDIF.
ENDIF.
*--- check authorization concerning FKART
IF flag NE false.
READ TABLE autf WITH KEY fkart = vbrk-fkart BINARY SEARCH.
IF sy-subrc <> 0.
autf-fkart = vbrk-fkart.
AUTHORITY-CHECK OBJECT 'V_VBRK_FKA'
ID 'FKART' FIELD autf-fkart
ID 'ACTVT' FIELD actvt.
IF sy-subrc = 0.
autf-aflag = true.
ELSE.
autf-aflag = false.
flag = false.
ENDIF.
INSERT autf INDEX sy-tabix.
ELSEIF autf-aflag = false.
flag = false.
ENDIF.
ENDIF.
*--- delete all messages for the key
IF flag = false.
DELETE lt_msgs_sort WHERE objky(10) = <fs_msgs>-objky(10).
ENDIF.
ENDLOOP.
msgs[] = lt_msgs_sort.
ENDFORM. "MESSAGES_FILTER
*---------------------------------------------------------------------*
* FORM MESSAGES_PREPARE *
*---------------------------------------------------------------------*
* sort messages and create display table *
*---------------------------------------------------------------------*
FORM display_prepare.
* sort messages
CASE pm_nsort.
WHEN '01'.
SORT msgs BY objky kschl.
WHEN '02'.
SORT msgs BY kschl objky.
WHEN '03'.
SORT msgs BY parnr kschl.
WHEN '04'.
SORT msgs BY sort1 sort2 sort3.
WHEN '05'.
SORT msgs BY kschl sort1 sort2 sort3.
WHEN OTHERS.
SORT msgs BY objky.
ENDCASE.
* create display
LOOP AT msgs.
msgs-tabix = sy-tabix.
MODIFY msgs.
MOVE-CORRESPONDING msgs TO disp.
disp-vbeln = msgs-objky+00(10).
disp-posnr = msgs-objky+10(06).
disp-tabix = sy-tabix.
APPEND disp.
ENDLOOP.
ENDFORM. "DISPLAY_PREPARE
*---------------------------------------------------------------------*
* FORM MESSAGES_INVOIC *
*---------------------------------------------------------------------*
* filter invoices *
*---------------------------------------------------------------------*
FORM messages_invoic.
DATA: ld_next_vbeln TYPE vbrk-vbeln.
DATA: ld_tabix TYPE sy-tabix.
DATA: flag TYPE c.
REFRESH rg_objky.
IF NOT rg_kunrg IS INITIAL.
SELECT * FROM vrkpa INTO TABLE lt_vrkpa
WHERE kunde IN rg_kunrg
AND parvw EQ parvw_rg
AND vkorg IN rg_vkorg
AND fkdat IN rg_fkdat
AND vtweg IN rg_vtweg
AND kunag IN rg_kunag
AND vbeln IN rg_vbeln
AND fktyp IN rg_fktyp.
ELSEIF NOT rg_kunag IS INITIAL.
SELECT * FROM vrkpa INTO TABLE lt_vrkpa
WHERE kunde IN rg_kunag
AND parvw EQ parvw_ag
AND vkorg IN rg_vkorg
AND fkdat IN rg_fkdat
AND vtweg IN rg_vtweg
AND kunnr IN rg_kunrg
AND vbeln IN rg_vbeln
AND fktyp IN rg_fktyp.
ENDIF.
IF NOT lt_vrkpa[] IS INITIAL.
SELECT * FROM vbrk INTO TABLE lt_vbrk
FOR ALL ENTRIES IN lt_vrkpa
WHERE vbeln EQ lt_vrkpa-vbeln
AND spart IN rg_spart
AND land1 IN rg_land1.
ELSE.
SELECT * FROM vbrk INTO TABLE lt_vbrk
WHERE vbeln IN rg_vbeln AND
fktyp IN rg_fktyp AND
fkdat IN rg_fkdat AND
vkorg IN rg_vkorg AND
vtweg IN rg_vtweg AND
spart IN rg_spart AND
kunag IN rg_kunag AND
kunrg IN rg_kunrg AND
land1 IN rg_land1.
ENDIF.
LOOP AT lt_vbrk.
flag = true.
*--- check authorization concerning VKORG
READ TABLE auth WITH KEY vkorg = lt_vbrk-vkorg BINARY SEARCH.
IF sy-subrc <> 0.
auth-vkorg = lt_vbrk-vkorg.
AUTHORITY-CHECK OBJECT 'V_VBRK_VKO'
ID 'VKORG' FIELD auth-vkorg
ID 'ACTVT' FIELD actvt.
IF sy-subrc = 0.
auth-aflag = true.
ELSE.
auth-aflag = false.
flag = false.
ENDIF.
INSERT auth INDEX sy-tabix.
ELSEIF auth-aflag = false.
flag = false.
ENDIF.
*--- check authorization concerning FKART
IF flag NE false.
READ TABLE autf WITH KEY fkart = lt_vbrk-fkart BINARY SEARCH.
IF sy-subrc <> 0.
autf-fkart = lt_vbrk-fkart.
AUTHORITY-CHECK OBJECT 'V_VBRK_FKA'
ID 'FKART' FIELD autf-fkart
ID 'ACTVT' FIELD actvt.
IF sy-subrc = 0.
autf-aflag = true.
ELSE.
autf-aflag = false.
flag = false.
ENDIF.
INSERT autf INDEX sy-tabix.
ELSEIF autf-aflag = false.
flag = false.
ENDIF.
ENDIF.
IF flag NE false.
CLEAR rg_objky.
*--- Should invoice lists be considered?
IF pm_allef IS INITIAL.
IF ld_next_vbeln = lt_vbrk-vbeln.
READ TABLE rg_objky INDEX ld_tabix.
rg_objky-option = 'BT'.
rg_objky-high = lt_vbrk-vbeln.
MODIFY rg_objky INDEX ld_tabix.
ELSE.
rg_objky-sign = 'I'.
rg_objky-option = 'EQ'.
rg_objky-low = lt_vbrk-vbeln.
APPEND rg_objky.
ld_tabix = sy-tabix.
ENDIF.
ld_next_vbeln = lt_vbrk-vbeln + '1'.
SHIFT ld_next_vbeln RIGHT.
OVERLAY ld_next_vbeln WITH '0000000000'.
ELSE.
*--- if the document is an invoice list
IF lt_vbrk-fktyp EQ 'R'.
rg_objky-sign = 'I'.
rg_objky-option = 'CP'.
rg_objky-low = lt_vbrk-vbeln.
rg_objky-low+10 = '*'.
APPEND rg_objky.
ELSE.
rg_objky-sign = 'I'.
rg_objky-option = 'EQ'.
rg_objky-low = lt_vbrk-vbeln.
APPEND rg_objky.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
IF rg_objky[] IS INITIAL.
rg_objky-sign = 'I'.
rg_objky-option = 'EQ'.
CLEAR: rg_objky-low, rg_objky-high.
APPEND rg_objky.
ENDIF.
ENDFORM. "MESSAGES_INVOIC
*---------------------------------------------------------------------*
* FORM PARAMETER_CONVERT *
*---------------------------------------------------------------------*
* convert selection parameter *
*---------------------------------------------------------------------*
FORM parameter_convert.
* read billing type (category?)
REFRESH rg_fktyp.
rg_fktyp-sign = 'I'.
rg_fktyp-option = 'EQ'.
IF pm_allel = true.
rg_fktyp-low = 'L'.
APPEND rg_fktyp.
rg_fktyp-low = 'X'.
APPEND rg_fktyp.
ENDIF.
IF pm_allea = true.
rg_fktyp-low = 'A'.
APPEND rg_fktyp.
rg_fktyp-low = 'P'.
APPEND rg_fktyp.
* check double entry
IF pm_allel = false.
rg_fktyp-low = 'X'.
APPEND rg_fktyp.
ENDIF.
ENDIF.
IF pm_alleb = true.
rg_fktyp-low = 'B'.
APPEND rg_fktyp.
rg_fktyp-low = 'C'.
APPEND rg_fktyp.
rg_fktyp-low = 'K'.
APPEND rg_fktyp.
ENDIF.
IF pm_allei = true.
rg_fktyp-low = 'I'.
APPEND rg_fktyp.
ENDIF.
IF pm_allef = true.
rg_fktyp-low = 'R'.
APPEND rg_fktyp.
ENDIF.
IF pm_alled = true.
rg_fktyp-low = 'D'.
APPEND rg_fktyp.
ENDIF.
* read sales organization
REFRESH rg_vkorg.
IF NOT pm_vkorg IS INITIAL.
rg_vkorg-sign = 'I'.
rg_vkorg-option = 'EQ'.
rg_vkorg-low = pm_vkorg.
APPEND rg_vkorg.
ENDIF.
* read distribution channel
REFRESH rg_vtweg.
IF NOT pm_vtweg IS INITIAL.
rg_vtweg-sign = 'I'.
rg_vtweg-option = 'EQ'.
rg_vtweg-low = pm_vtweg.
APPEND rg_vtweg.
ENDIF.
* read division
REFRESH rg_spart.
IF NOT pm_spart IS INITIAL.
rg_spart-sign = 'I'.
rg_spart-option = 'EQ'.
rg_spart-low = pm_spart.
APPEND rg_spart.
ENDIF.
* read country
REFRESH rg_land1.
IF NOT pm_land1 IS INITIAL.
rg_land1-sign = 'I'.
rg_land1-option = 'EQ'.
rg_land1-low = pm_land1.
APPEND rg_land1.
ENDIF.
* transfer document numbers as object keys
REFRESH rg_objky.
IF pm_allef = 'X'. "invoice list
LOOP AT rg_vbeln.
CLEAR rg_objky.
CASE rg_vbeln-option.
WHEN 'EQ'.
rg_objky-sign = rg_vbeln-sign.
rg_objky-option = 'CP'.
rg_objky-low = rg_vbeln-low.
rg_objky-low+10 = '*'.
APPEND rg_objky.
WHEN 'BT'.
rg_objky-sign = rg_vbeln-sign.
rg_objky-option = 'BT'.
rg_objky-low = rg_vbeln-low.
rg_objky-high = rg_vbeln-high.
APPEND rg_objky.
IF NOT rg_vbeln-low IS INITIAL.
rg_objky-low+10 = '0000000000000000'.
ENDIF.
IF NOT rg_vbeln-high IS INITIAL.
rg_objky-high+10 = '9999999999999999'.
ENDIF.
APPEND rg_objky.
ENDCASE.
ENDLOOP.
ELSE.
LOOP AT rg_vbeln.
CLEAR rg_objky.
MOVE-CORRESPONDING rg_vbeln TO rg_objky.
APPEND rg_objky.
ENDLOOP.
ENDIF.
ENDFORM. "PARAMETER_CONVERT
*& Include ZSDP027_F01
*&---------------------------------------------------------------------*
*---------------------------------------------------------------------*
* FORM MESSAGES_FILTER *
*---------------------------------------------------------------------*
* filter messages *
*---------------------------------------------------------------------*
FORM messages_filter.
DATA: flag TYPE c,
lt_msgs_sort TYPE SORTED TABLE OF msg0
WITH NON-UNIQUE KEY objky kschl.
FIELD-SYMBOLS:
<fs_msgs> TYPE msg0.
SORT msgs BY objky kschl.
lt_msgs_sort = msgs[].
LOOP AT lt_msgs_sort ASSIGNING <fs_msgs>.
*--- only check new ones due to mass deletion
CHECK <fs_msgs>-objky(10) NE vbrk-vbeln.
flag = true.
*--- select from VBRK
SELECT SINGLE * FROM vbrk
WHERE vbeln = <fs_msgs>-objky(10) AND
fktyp IN rg_fktyp AND
fkdat IN rg_fkdat AND
vkorg IN rg_vkorg AND
vtweg IN rg_vtweg AND
spart IN rg_spart AND
kunag IN rg_kunag AND
kunrg IN rg_kunrg AND
land1 IN rg_land1.
IF sy-subrc <> 0.
flag = false.
ENDIF.
*--- check authorization concerning VKORG
IF flag NE false.
READ TABLE auth WITH KEY vkorg = vbrk-vkorg BINARY SEARCH.
IF sy-subrc <> 0.
auth-vkorg = vbrk-vkorg.
AUTHORITY-CHECK OBJECT 'V_VBRK_VKO'
ID 'VKORG' FIELD auth-vkorg
ID 'ACTVT' FIELD actvt.
IF sy-subrc = 0.
auth-aflag = true.
ELSE.
auth-aflag = false.
flag = false.
ENDIF.
INSERT auth INDEX sy-tabix.
ELSEIF auth-aflag = false.
flag = false.
ENDIF.
ENDIF.
*--- check authorization concerning FKART
IF flag NE false.
READ TABLE autf WITH KEY fkart = vbrk-fkart BINARY SEARCH.
IF sy-subrc <> 0.
autf-fkart = vbrk-fkart.
AUTHORITY-CHECK OBJECT 'V_VBRK_FKA'
ID 'FKART' FIELD autf-fkart
ID 'ACTVT' FIELD actvt.
IF sy-subrc = 0.
autf-aflag = true.
ELSE.
autf-aflag = false.
flag = false.
ENDIF.
INSERT autf INDEX sy-tabix.
ELSEIF autf-aflag = false.
flag = false.
ENDIF.
ENDIF.
*--- delete all messages for the key
IF flag = false.
DELETE lt_msgs_sort WHERE objky(10) = <fs_msgs>-objky(10).
ENDIF.
ENDLOOP.
msgs[] = lt_msgs_sort.
ENDFORM. "MESSAGES_FILTER
*---------------------------------------------------------------------*
* FORM MESSAGES_PREPARE *
*---------------------------------------------------------------------*
* sort messages and create display table *
*---------------------------------------------------------------------*
FORM display_prepare.
* sort messages
CASE pm_nsort.
WHEN '01'.
SORT msgs BY objky kschl.
WHEN '02'.
SORT msgs BY kschl objky.
WHEN '03'.
SORT msgs BY parnr kschl.
WHEN '04'.
SORT msgs BY sort1 sort2 sort3.
WHEN '05'.
SORT msgs BY kschl sort1 sort2 sort3.
WHEN OTHERS.
SORT msgs BY objky.
ENDCASE.
* create display
LOOP AT msgs.
msgs-tabix = sy-tabix.
MODIFY msgs.
MOVE-CORRESPONDING msgs TO disp.
disp-vbeln = msgs-objky+00(10).
disp-posnr = msgs-objky+10(06).
disp-tabix = sy-tabix.
APPEND disp.
ENDLOOP.
ENDFORM. "DISPLAY_PREPARE
*---------------------------------------------------------------------*
* FORM MESSAGES_INVOIC *
*---------------------------------------------------------------------*
* filter invoices *
*---------------------------------------------------------------------*
FORM messages_invoic.
DATA: ld_next_vbeln TYPE vbrk-vbeln.
DATA: ld_tabix TYPE sy-tabix.
DATA: flag TYPE c.
REFRESH rg_objky.
IF NOT rg_kunrg IS INITIAL.
SELECT * FROM vrkpa INTO TABLE lt_vrkpa
WHERE kunde IN rg_kunrg
AND parvw EQ parvw_rg
AND vkorg IN rg_vkorg
AND fkdat IN rg_fkdat
AND vtweg IN rg_vtweg
AND kunag IN rg_kunag
AND vbeln IN rg_vbeln
AND fktyp IN rg_fktyp.
ELSEIF NOT rg_kunag IS INITIAL.
SELECT * FROM vrkpa INTO TABLE lt_vrkpa
WHERE kunde IN rg_kunag
AND parvw EQ parvw_ag
AND vkorg IN rg_vkorg
AND fkdat IN rg_fkdat
AND vtweg IN rg_vtweg
AND kunnr IN rg_kunrg
AND vbeln IN rg_vbeln
AND fktyp IN rg_fktyp.
ENDIF.
IF NOT lt_vrkpa[] IS INITIAL.
SELECT * FROM vbrk INTO TABLE lt_vbrk
FOR ALL ENTRIES IN lt_vrkpa
WHERE vbeln EQ lt_vrkpa-vbeln
AND spart IN rg_spart
AND land1 IN rg_land1.
ELSE.
SELECT * FROM vbrk INTO TABLE lt_vbrk
WHERE vbeln IN rg_vbeln AND
fktyp IN rg_fktyp AND
fkdat IN rg_fkdat AND
vkorg IN rg_vkorg AND
vtweg IN rg_vtweg AND
spart IN rg_spart AND
kunag IN rg_kunag AND
kunrg IN rg_kunrg AND
land1 IN rg_land1.
ENDIF.
LOOP AT lt_vbrk.
flag = true.
*--- check authorization concerning VKORG
READ TABLE auth WITH KEY vkorg = lt_vbrk-vkorg BINARY SEARCH.
IF sy-subrc <> 0.
auth-vkorg = lt_vbrk-vkorg.
AUTHORITY-CHECK OBJECT 'V_VBRK_VKO'
ID 'VKORG' FIELD auth-vkorg
ID 'ACTVT' FIELD actvt.
IF sy-subrc = 0.
auth-aflag = true.
ELSE.
auth-aflag = false.
flag = false.
ENDIF.
INSERT auth INDEX sy-tabix.
ELSEIF auth-aflag = false.
flag = false.
ENDIF.
*--- check authorization concerning FKART
IF flag NE false.
READ TABLE autf WITH KEY fkart = lt_vbrk-fkart BINARY SEARCH.
IF sy-subrc <> 0.
autf-fkart = lt_vbrk-fkart.
AUTHORITY-CHECK OBJECT 'V_VBRK_FKA'
ID 'FKART' FIELD autf-fkart
ID 'ACTVT' FIELD actvt.
IF sy-subrc = 0.
autf-aflag = true.
ELSE.
autf-aflag = false.
flag = false.
ENDIF.
INSERT autf INDEX sy-tabix.
ELSEIF autf-aflag = false.
flag = false.
ENDIF.
ENDIF.
IF flag NE false.
CLEAR rg_objky.
*--- Should invoice lists be considered?
IF pm_allef IS INITIAL.
IF ld_next_vbeln = lt_vbrk-vbeln.
READ TABLE rg_objky INDEX ld_tabix.
rg_objky-option = 'BT'.
rg_objky-high = lt_vbrk-vbeln.
MODIFY rg_objky INDEX ld_tabix.
ELSE.
rg_objky-sign = 'I'.
rg_objky-option = 'EQ'.
rg_objky-low = lt_vbrk-vbeln.
APPEND rg_objky.
ld_tabix = sy-tabix.
ENDIF.
ld_next_vbeln = lt_vbrk-vbeln + '1'.
SHIFT ld_next_vbeln RIGHT.
OVERLAY ld_next_vbeln WITH '0000000000'.
ELSE.
*--- if the document is an invoice list
IF lt_vbrk-fktyp EQ 'R'.
rg_objky-sign = 'I'.
rg_objky-option = 'CP'.
rg_objky-low = lt_vbrk-vbeln.
rg_objky-low+10 = '*'.
APPEND rg_objky.
ELSE.
rg_objky-sign = 'I'.
rg_objky-option = 'EQ'.
rg_objky-low = lt_vbrk-vbeln.
APPEND rg_objky.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
IF rg_objky[] IS INITIAL.
rg_objky-sign = 'I'.
rg_objky-option = 'EQ'.
CLEAR: rg_objky-low, rg_objky-high.
APPEND rg_objky.
ENDIF.
ENDFORM. "MESSAGES_INVOIC
*---------------------------------------------------------------------*
* FORM PARAMETER_CONVERT *
*---------------------------------------------------------------------*
* convert selection parameter *
*---------------------------------------------------------------------*
FORM parameter_convert.
* read billing type (category?)
REFRESH rg_fktyp.
rg_fktyp-sign = 'I'.
rg_fktyp-option = 'EQ'.
IF pm_allel = true.
rg_fktyp-low = 'L'.
APPEND rg_fktyp.
rg_fktyp-low = 'X'.
APPEND rg_fktyp.
ENDIF.
IF pm_allea = true.
rg_fktyp-low = 'A'.
APPEND rg_fktyp.
rg_fktyp-low = 'P'.
APPEND rg_fktyp.
* check double entry
IF pm_allel = false.
rg_fktyp-low = 'X'.
APPEND rg_fktyp.
ENDIF.
ENDIF.
IF pm_alleb = true.
rg_fktyp-low = 'B'.
APPEND rg_fktyp.
rg_fktyp-low = 'C'.
APPEND rg_fktyp.
rg_fktyp-low = 'K'.
APPEND rg_fktyp.
ENDIF.
IF pm_allei = true.
rg_fktyp-low = 'I'.
APPEND rg_fktyp.
ENDIF.
IF pm_allef = true.
rg_fktyp-low = 'R'.
APPEND rg_fktyp.
ENDIF.
IF pm_alled = true.
rg_fktyp-low = 'D'.
APPEND rg_fktyp.
ENDIF.
* read sales organization
REFRESH rg_vkorg.
IF NOT pm_vkorg IS INITIAL.
rg_vkorg-sign = 'I'.
rg_vkorg-option = 'EQ'.
rg_vkorg-low = pm_vkorg.
APPEND rg_vkorg.
ENDIF.
* read distribution channel
REFRESH rg_vtweg.
IF NOT pm_vtweg IS INITIAL.
rg_vtweg-sign = 'I'.
rg_vtweg-option = 'EQ'.
rg_vtweg-low = pm_vtweg.
APPEND rg_vtweg.
ENDIF.
* read division
REFRESH rg_spart.
IF NOT pm_spart IS INITIAL.
rg_spart-sign = 'I'.
rg_spart-option = 'EQ'.
rg_spart-low = pm_spart.
APPEND rg_spart.
ENDIF.
* read country
REFRESH rg_land1.
IF NOT pm_land1 IS INITIAL.
rg_land1-sign = 'I'.
rg_land1-option = 'EQ'.
rg_land1-low = pm_land1.
APPEND rg_land1.
ENDIF.
* transfer document numbers as object keys
REFRESH rg_objky.
IF pm_allef = 'X'. "invoice list
LOOP AT rg_vbeln.
CLEAR rg_objky.
CASE rg_vbeln-option.
WHEN 'EQ'.
rg_objky-sign = rg_vbeln-sign.
rg_objky-option = 'CP'.
rg_objky-low = rg_vbeln-low.
rg_objky-low+10 = '*'.
APPEND rg_objky.
WHEN 'BT'.
rg_objky-sign = rg_vbeln-sign.
rg_objky-option = 'BT'.
rg_objky-low = rg_vbeln-low.
rg_objky-high = rg_vbeln-high.
APPEND rg_objky.
IF NOT rg_vbeln-low IS INITIAL.
rg_objky-low+10 = '0000000000000000'.
ENDIF.
IF NOT rg_vbeln-high IS INITIAL.
rg_objky-high+10 = '9999999999999999'.
ENDIF.
APPEND rg_objky.
ENDCASE.
ENDLOOP.
ELSE.
LOOP AT rg_vbeln.
CLEAR rg_objky.
MOVE-CORRESPONDING rg_vbeln TO rg_objky.
APPEND rg_objky.
ENDLOOP.
ENDIF.
ENDFORM. "PARAMETER_CONVERT
*&---------------------------------------------------------------------*
*& Form LOAD_FOLIOS @aaq
*&---------------------------------------------------------------------*
*A partir del 'Folio Legal'(XBLNR) obtenemos las 'Facturas SAP' (VBELN)
*----------------------------------------------------------------------*
FORM load_folios.
SELECT vbeln xblnr
INTO TABLE gt_vbrk
FROM vbrk
WHERE xblnr IN rg_xblnr
AND bukrs IN rg_bukrs
AND gjahr IN rg_gjahr.
IF sy-subrc EQ 0 AND gt_vbrk[] IS NOT INITIAL.
LOOP AT gt_vbrk ASSIGNING <gt_vbrk>.
rg_vbeln-low = <gt_vbrk>-vbeln.
rg_vbeln-sign = 'I'.
rg_vbeln-option = 'EQ'.
APPEND rg_vbeln.
ENDLOOP.
ENDIF.
ENDFORM. " LOAD_FOLIOS
*& Form LOAD_FOLIOS @aaq
*&---------------------------------------------------------------------*
*A partir del 'Folio Legal'(XBLNR) obtenemos las 'Facturas SAP' (VBELN)
*----------------------------------------------------------------------*
FORM load_folios.
SELECT vbeln xblnr
INTO TABLE gt_vbrk
FROM vbrk
WHERE xblnr IN rg_xblnr
AND bukrs IN rg_bukrs
AND gjahr IN rg_gjahr.
IF sy-subrc EQ 0 AND gt_vbrk[] IS NOT INITIAL.
LOOP AT gt_vbrk ASSIGNING <gt_vbrk>.
rg_vbeln-low = <gt_vbrk>-vbeln.
rg_vbeln-sign = 'I'.
rg_vbeln-option = 'EQ'.
APPEND rg_vbeln.
ENDLOOP.
ENDIF.
ENDFORM. " LOAD_FOLIOS
*&--------------------------------------------------------------------------*
*& Form GET_FOLIOS_MSGS @aaq
*&--------------------------------------------------------------------------* *En base a los mensajes existentes traeremos también el valor del folio legal
*&--------------------------------------------------------------------------*
FORM get_folios_msgs TABLES pt_znaliv3 STRUCTURE zssd_znaliv3.
REFRESH pt_znaliv3[].
LOOP AT disp.
APPEND INITIAL LINE TO pt_znaliv3 ASSIGNING <gt_znaliv3>.
MOVE-CORRESPONDING disp TO <gt_znaliv3>.
READ TABLE gt_vbrk ASSIGNING <gt_vbrk> WITH KEY vbeln = disp-vbeln.
IF sy-subrc EQ 0.
<gt_znaliv3>-xblnr = <gt_vbrk>-xblnr.
ENDIF.
ENDLOOP.
SORT pt_znaliv3 BY xblnr.
ENDFORM. " GET_FOLIOS_MSGS
DEBUGEANDO:
Dentro del evento START-OF-SELECTION se invoca a la fucnión: WFMC_MESSAGES_PROCESS donde dentro del parámetro de EXPORTING en el valor PI_DISPLAY_ID se indica el nombre de nuestra esctructura; ZSSD_ZNALIV3 esto es importante indicar ya que de acuerdo a la estructura se definirá el catálogo de campos
En la sección TABLES al parámetro TX_DISPLAY se le pasa la tabla interna GT_ZNALIV3 la cual contiene los valores del folio legal en el campo XBLNR
Ingresando más adentro, veremos que en la rutina MESSAGES_DISPLAY se llama a la función REUSE_ALV_FIELDCATALOG_MERGE para definir el catálogo de campos del ALV de acuerdo a la estructura ZSSD_ZNALIV3
Luego de ejecutar la función: REUSE_ALV_FIELDCATALOG_MERGE nos devuelve llena la tabla interna T_FIELDCAT donde se encuentran todos los campos (de las columnas) que se visualizarán en el ALV
Veamos el contenido del catálogo de campos:
Ahí podemos observar que se muestra el campo XBLNR
Finalmente se llama a la función REUSE_ALV_LIST_DISPLAY para visualizar el ALV con la data que se encuentra en la tabla interna TX_DISPLAY
Demo del Resultado:
Similar lógica que hemos aplicado para la impresión masiva de facturas por folio legal, te animo a que desarrolles un programa Z para la impresión masiva de entregas por folio legal.
Reutilizarías el código del programa: SD70AV2A, transacción: VL71 (Impresión masiva de Entregas) e irías depurando y ajustando el código para lograr el objetivo, éxitos!!!
Nos vemos en el siguiente Blog ;)
MAGALEX
Comentarios
Publicar un comentario