PDA

Ver la Versión Completa : bucle loop q no funciona


romario2
21/02/09, 07:56:09
Hola,

En mi código vamos a tabla de cabecera con vbeln y obtenemos el kunmv, vamos a la de posiciones y obtenemos los posnr y sincronizamos


** comentarios
*Type KONV si KSCHL = SHIM o DHIM o MHIM,entonces "IVA" y MWSK1 <> *RB, RX o RY, si MWSK1 = RB, RX o RY entonces "IGIC" VBRK KNUMV

LOOP AT it_konv
WHERE kposn = vbrp-posnr AND knumv = vbrk-knumv.
IF kposn_aux <> it_konv-kposn.
kposn_aux = it_konv-kposn.

Debugando he comprobado que en la tabla interna it_konv
tenemos por ej:

KNUMV KPOSN
4567777 01
4567777 01
4567777 02
4567777 02

Debido a que Kposn no es único, no corre bien el loop por todos los registros
Alguien me puede dar una solución?

Saludos

Jonathan Barrio Rodriguez
22/02/09, 18:13:46
Justo antes del LOOP:

*Borramos los registros duplicados.
ORDER it_konv BY knumv kpon ASCENDING.
DELETE ADJACENT DUPLICATES FROM it_konv.

El tema de las Condiciones es un pelín complicado, si tienes incidencias no dudes en escribir.

Saludos.

bisonye
23/02/09, 06:43:50
¿que es lo que tienes que hacer? Si lo que quieres es ver las posiciones para el registro de condición es lo que comenta yoni si lo que quieres es ver las condiciones aplicadas a las líneas tienes que recorrer sin poner el if.

Saludos

romario2
23/02/09, 08:28:33
Hola,

quiero recorrer registro a registro la tabla interna y verificar el valor de los campos kschl y mwsk1.
Entonces meter estas condiciones en el LOOP.

( ( kschl = 'SHIM' ) OR ( kschl = 'DHIM' ) OR ( kschl = 'MHIM' ) ) AND
( ( mwsk1 <> 'RB') OR ( mwsk1 <> 'RX' ) OR ( mwsk1 <> 'RY' ) ).
v_taxtype = 'IVA'.
v_taxtypeli = 'IVA'.
v_supclient = 'IVA'.

*si KONV-KSCHL = SHIM o DHIM o MHIM,MWSK1 = RB, RX o RY ----> entonces "IGIC"
IF ( ( it_konv-kschl = 'SHIM' ) OR ( it_konv-kschl = 'DHIM' ) OR ( it_konv-kschl = 'MHIM' ) ) AND
( ( it_konv-mwsk1 = 'RB') OR ( it_konv-mwsk1 = 'RX' ) OR ( it_konv-mwsk1 = 'RY' ) ).
v_taxtype = 'IGIC'.
v_taxtypeli = 'IGIC'.
v_supclient = 'IGIC'.
ELSE.
v_taxtype = ''.
v_taxtypeli = ''.
v_supclient = ''.

ENDIF.

IF ( ( it_konv-kschl = 'SHIM' ) OR ( it_konv-kschl = 'DHIM' ) OR ( it_konv-kschl = 'MHIM' ) ) .
CLEAR v_impli.
v_impli = 10.
IF it_konv-kbetr <> 0 AND v_impli <> 0.
v_ratetaxli = it_konv-kbetr / v_impli.
ENDIF.
*IU
ELSE.
v_ratetaxli = ''.
ENDIF.

IF it_konv-kbetr <> 0 AND v_imp <> 0.
CLEAR v_imp.
v_imp = 10.
v_ratetax = it_konv-kbetr / v_imp.
*IU
ELSE.
v_ratetax = ''.
ENDIF.

OJO, porque konv no es unico, y quiero recorrer registro a registro

bisonye
23/02/09, 08:49:17
Los registros normalmente son únicos para knumv posición y KSCHL. Para cada condición línea hay una línea por registro de condición. Lo que puedes hacer es recorrer todas las condiciones y cuando hayas encontrado la que te sirve poner la condición para que no siga recorriendo ese knumv.

Saludos

Jonathan Barrio Rodriguez
23/02/09, 18:45:14
Mira este código:

SELECT *
INTO CORRESPONDING FIELDS OF TABLE konv_h
FROM konv AS v
FOR ALL ENTRIES IN tabla_alv
WHERE v~knumv = tabla_alv-knumv
AND kinak <> flag_x
AND kntyp <> 'D'. "IVA
* AND KSCHL(2) = 'ZX'.

Cuando he recuperado los datos me he fijado solo en el
KNTYP
para verificar que no fuera IVA. Osea en tu caso KNTYP = 'D'.
Pero esto es variable según la casuistica de la empresa. Hablalo con tu consultor o analista.

Por otro lado, te recomendaría crear una tabla Z customaizing con vista de actualización (se11, se30) para evitar los literales como 'D' o en tu caso KSCHL = 'SHIM'.

DE todos modos hay un campo uniquivoco para cada registro de la condición, osea, por cada KNUMV, encuentras varios KNUMH en la KONV. Todos los KNUMH están recogidos en la tabal KONH.

Suelo trabajar haciendome una tabla interna que contenga como mínimo

VBELN | KNUMV | KNUMH | KSCHL |

De todos modos como te comentaba, consultalo con tu superior.
Comenta si quieres cual es el fin de este rporte a ver si se puede dar una orientación ´más concreta.

Saludos

romario2
24/02/09, 11:28:20
Hola ,

tengo que hacer varios tratamientos strings:

Quitar los decimales de los campos de:

- un campo me piden que lo muestre sin decimales

- otro campo únicamente con 2 decimales


- Formatos de las fechas: AAAA-MM-DD, es decir con el guión intercalado.

Otra cosa que debo tratar en mi ALV es
Mi función es la 'REUSE_ALV_GRID_DISPLAY'


- que quieren que muestre los registros
con pincho o " check-box" en una columna.

-a mi la botonera standard, añadir 2 botones custom.( las pongo a pelo y no funcionan)

Muchísimas gracias por vuestra ayuda!

romario2
24/02/09, 11:29:44
Gracias yonixx por tu respuesta!

Como ves voy super atareado!:p

Jonathan Barrio Rodriguez
25/02/09, 03:57:52
Para los strings, declararía variables o campos auxiliares con el formato deseado:

DATA: VARIABLE_2DECIMALES(LONGITUD DEL CAMPO ORIGINAL CON 2 DECIMALES) TYPE I.
DATA: VARIABLE_SINDECIMALES(LONGITUD DEL CAMPO ORIGINAL SIN Nº DE DECIMALES) TYPE I.
DATA: NUEVA_FECHA(10).

Y luego, al hacer el LOOP, les pasaría el offset que nos interesara del campo original.

LOOP AT i_konv.

VARIABLE_2DECIMALES = i_konv-Campo1(LONGITUD DEL CAMPO ORIGINAL CON DOS DECIMALES).

VARIABLE_SINDECIMALES = i_konv-Campo2(LONGITUD DEL CAMPO ORIGINAL SIN Nº DE DECIMALES).

*LA FECHA CON LA SENTENCIA CONCATENATE.
CONCATENATE i_konv-fecha(4) '-' i_konv-fecha+4(2) '-' i_konv-fecha+4(2)
INTO nueva_fecha.

ENDLOOP.

*Es un poco chapucero pero así lo puedes hacer, puedes estudiar más a fondo las sentencia concatenate. También existe (si usas un write )
* SET DATE MASK = 'DD-MM-YYYY'
aunque creo que esto es exclusivo para los formularios SAPSCRIPT.

*Para el tema de los decimales, si usas WRITE, tienes la opcion "DECIMALS <nº decimales>", que puedes darle el número de decimales a escribir o "USING EDIT MASK <mascara ej: ______.__>".

*Para el check box en el ALV, tienes que declarar en la tabla interna un campo type flag.
Luego construir el catálogo (FILEDCAT ) qué finalmente se le pasará a función del ALV indicando que ese campo es tipo flag (y también edit, para que puedas marcarlo y desmarcarlo ):
FIJATE EN LA LINEA EN ROJO:

*&---------------------------------------------------------------------*
*& Form BUILD_FIELDCAT
*&---------------------------------------------------------------------*
* *Este Form viene del Form construir catálogo donde se le dan los
* datos de la tabla interna.
*----------------------------------------------------------------------*

fieldcat_ln-ref_tabname = "nombre de la tabla tabname.
fieldcat_ln-fieldname = "nombre del campo fieldname.
fieldcat_ln-ref_tabname = ref_tabname. "Tabla de Referencia
fieldcat_ln-ref_fieldname = ref_fieldname. "campo referencia
fieldcat_ln-key = key. "si es clave lo marca
fieldcat_ln-col_pos = col_pos. "Dice donde se pondrá esta columna
fieldcat_ln-no_out = no_out. "si=x no lo muestra
fieldcat_ln-hotspot = hotspot. "NAVEGABLE
fieldcat_ln-do_sum = do_sum. "Hace totales de la columna
fieldcat_ln-ddictxt = ddictxt.


fieldcat_ln-just = just.
fieldcat_ln-fix_column = fix_column.
fieldcat_ln-seltext_l = seltext_l.

* fieldcat_ln-row_pos = row_pos.
fieldcat_ln-outputlen = outputlen. " longitud de la columna
fieldcat_ln-checkbox = 'X'.
fieldcat_ln-edit = edit.
APPEND fieldcat_ln TO fieldcat.
CLEAR fieldcat_ln.

ENDFORM. " BUILD_FIELDCAT


*El tema de la botonera supongo que quieres decir del ALV, no??

declara la variables:
data:
status LIKE sy-pfkey, "PARA PERFORM STATUS Y CONSTRUIR_CATALOGO
rt_extab TYPE slis_t_extab. "<-Para Perform STATUS

En la llamada a la función :

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = g_repid "Nombre del programa
i_callback_pf_status_set = 'STATUS'

Y POR ULTIMO TIENES QUE DECLARAR UN FORM EN TU PROGRAMA CON EL NOMBRE PUESTO EN EN EL EXPORTING DEL ALV "i_callback_pf_status_set = 'STATUS'"

*&---------------------------------------------------------------------*
*& Form status
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->RT_EXTAB text
*----------------------------------------------------------------------*
FORM status USING rt_extab TYPE slis_t_extab.
DATA: lt_extab TYPE slis_t_extab.
* CASE L_OKCODE.


* when 'RENOVAR' or 'GRABAR'.
IF sy-ucomm = '&F03' OR sy-ucomm = 'BACK'
OR sy-ucomm = 'VOLVER'.
status = '9000'.
* ELSEIF SY-UCOMM = 'VOLVER'.
* LEAVE SCREEN.
*
ENDIF.
CASE status.
WHEN '9001'.


SET PF-STATUS '9001'." EXCLUDING lt_extab.
SET TITLEBAR 'RENOVACION CONTRATOS DE VENTAS PRORROGABLES'.


WHEN OTHERS.
* else.

SET PF-STATUS '9000'." EXCLUDING lt_extab.
SET TITLEBAR 'CONTRATOS DE VENTAS PRORROGABALES'.
* endif.
ENDCASE.
ENDFORM. "status


Abres el programa por la transacción SE80, TE fijas en el navegador de la izquierda de la pantalla donde venga la carpeta de status y clickas sobre el que quieras modificar, se te abrirá una pantalla con los iconos y los códigos de funciones asignadas a cada boton, también pudiendo crear nuevos.

Parece un poco complicado, es más sencillo de lo que parece.

AL LORITO (atención) con las fechas que quieres mostrar... si son del documento (vbeln) no hay inconveniente, sin embargo si son las de las condiciones de precio, a lo mejor no te sirven las de KONV ó KONH y debes ir a las tablas de clientes "Annn" especificada en cada registr de la KONH.

Consulta lo que necesites.

Jonathan Barrio Rodriguez
25/02/09, 04:46:49
SORRY, por repetir las cosas... :p

Ya he visto que te repondían en otro post... nome había fijado:rolleyes:

romario2
25/02/09, 08:29:06
Gracias Jonathan por esta respuesta tan detallada!:p

Son cosas que sabría encontrar pero que seguro que demorarían un tiempo del cual ahora no preciso... muchas gracias, eres un crack!:D

Es increible lo buena que es la comunidad sapera:cool: