Duda comparación en tablas

Hola a todos,

Estoy escribiendo mi primer código en abap 4 :partying_face: :partying_face: :partying_face: y lo llevo algo regular. Cómo concepto sencillo pero dónde curro no trabajan con objetos, y bueno que me han echado a los leones directamente haha.

El caso es que debo hacer un programa programa para comparar los precios de dos bases de datos y mostrar por ALV los que sean distintos para saber que descuadre hay de precios en la base de datos de terceros.

Básicamente el problema que he identificado que tengo con el programa es el siguiente: tengo un itab dónde varios registros vienen de una select previa:

DATA: BEGIN OF itab OCCURS 0,
    vbeln LIKE vbrk-vbeln,        " Factura
    fkdat LIKE vbrk-fkdat,        " Data
    spart LIKE vbrk-spart,        " Sector
    posnr LIKE vbrp-posnr,        " Pos factura
    matnr LIKE vbrp-matnr,        " Ref
    kunrg LIKE vbrk-kunrg,        " Cliente
    arktx LIKE vbrp-arktx,        " Desc
    fkimg LIKE vbrp-fkimg,        " Cant uni factura
    bukrs LIKE vbrk-bukrs,        " Org
    netwr LIKE vbrp-netwr,        " Valor neto de la factura
    kzwi1 LIKE vbrp-kzwi1,        " Subtotal
    kzwi5 LIKE vbrp-kzwi5,        " Subtotal / final
    kzwi6 LIKE vbrp-kzwi6,        " Subtotal
    vkorg LIKE vbrk-vkorg,        " Org
    mwsbp LIKE vbrp-mwsbp,        " IVA
    xblnr(20),                    " Ref tiket
    tipo_documento(1),            " tipo documento cm  1= cargo / 3= abono // Linia
    num_tiquet TYPE string,       " referencia tiquet cm
    linia LIKE vbrp-posnr,        " CM posición
    codart LIKE vbrp-matnr,       " CM codigo articulo
    cantid LIKE vbrp-fkimg,       " CM cant facturada
    desc LIKE vbrp-netwr,         " CM descuento
    precio LIKE vbrp-netwr,       " CM preu
    precio_total LIKE vbrp-netwr, " CM precio total
    importe LIKE vbrp-netwr,      " CM importe
    importe_total LIKE vbrp-netwr," CMZ importe total
 END OF itab.

Y esta es la select:

  SELECT  vbrk~vbeln vbrk~fkdat vbrk~spart vbrk~bukrs vbrk~vkorg vbrk~xblnr
            vbrp~vbeln vbrp~matnr vbrp~fkimg vbrp~netwr
            vbrp~kzwi1 vbrp~kzwi5 vbrp~kzwi6 vbrp~posnr vbrp~arktx
            vbrk~kunrg vbrk~xblnr
          INTO CORRESPONDING FIELDS OF TABLE itab
            FROM vbrk AS vbrk INNER JOIN vbrp AS vbrp
              ON vbrk~vbeln = vbrp~vbeln
            WHERE vbrk~vbeln IN s_vbeln   AND
                  vbrk~kunrg IN s_kunrg   AND
                  vbrp~matnr IN s_matnr   AND
                  vbrk~fkdat IN s_data    AND
                  vbrk~bukrs IN s_bukrs   AND
                  vbrk~vkorg IN s_vkorg   AND
                  vbrk~spart IN s_spart.

Seguidamente hago un sólo loop para iterar en la ITAB que me he definido, para ir imputándole los datos necesarios para hacer la distinción:


  DATA con_name LIKE dbcon-con_name.

  LOOP AT itab.

    CLEAR itab-num_tiquet.                 

    itab-tipo_documento = itab-xblnr+2(1). " Linea

** Aquí me creo un tiquet que no puedo recuperar de la db en la que me conecto para comparar precios a partir de los datos que obtengo de la db de la que si que tenía acceso antes

    tiquet = itab-xblnr+9(7).
    anycreacio = itab-fkdat+0(4).
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' 
      EXPORTING
        input  = tiquet
      IMPORTING
        output = tiquet.

    CONCATENATE anocreacion '/' itab-vkorg itab-xblnr+7(2) '/' tiquet INTO itab-num_tiquet. 

    CLEAR posicion.
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
      EXPORTING
        input  = itab-posnr
      IMPORTING
        output = posicion.

** INICIO extraccion

    CLEAR wa_con.

    IF sy-sysid = XXXXXXXXXXX.
      con_name = XXXXXXXXXXXXXXX.
    ELSE.
      con_name = XXXXXXXXXXXXXX.
    ENDIF.

    EXEC SQL.
      connect to :con_name
    ENDEXEC.

** Select a la db de externa para imputar en su línea con la ref correspondiente
    EXEC SQL.

      OPEN dbcur for

      SELECT C.COD_ALBARAN, P.LINEA, P.CODART, P.CANTIDAD, P.DESCUENTO, P.PRECIO, P.PRECIO_TOTAL, P.IMPORTE, P.IMPORTE_TOTAL
      FROM [cm].[D_CLIE_ALBARANES_CAB_TBL] AS C
      INNER JOIN [cm].[D_CLIE_ALBARANES_DET_TBL] AS P ON C.ID_CLIE_ALBARAN = P.ID_CLIE_ALBARAN
      WHERE (C.ID_TIPO_DOCUMENTO = :itab-tipo_documento) AND (C.COD_ALBARAN = :itab-num_tiquet)

    ENDEXEC.

*AND (P.CODART = :itab-codart)

    DO.

      EXEC SQL.
        FETCH NEXT dbcur INTO     :wa_con-codalb,
                                  :wa_con-linia,
                                  :wa_con-codart,
                                  :wa_con-cantid,
                                  :wa_con-desc,
                                  :wa_con-precio,
                                  :wa_con-precio_total,
                                  :wa_con-importe,
                                  :wa_con-importe_total
      ENDEXEC.

** Aquí después de seleccionar la línea por cada iteración y ponerla en la wa correspondiente después se la enchufo a las líneas vacías del itab que necesito rellenar

      IF sy-subrc <> 0.
        EXIT.
      ELSE.
        itab-linia = wa_con-linia.
        itab-codart = wa_con-codart.
        itab-cantid = wa_con-cantid.
        itab-desc = wa_con-desc.
        itab-precio = wa_con-precio.
        itab-precio_total = wa_con-precio_total.
        itab-importe = wa_con-importe.
        itab-importe_total = wa_con-importe_total.

        MODIFY itab .

      ENDIF.

    ENDDO.

    EXEC SQL.
      CLOSE dbcur
    ENDEXEC.


** Por último simplemente hago un append a una itab resultado con los datos resultantes de la diferencia enrte los dos campos que se ve
    IF itab-importe_total <> itab-kzwi5.
      APPEND itab TO result_itab.
    ENDIF.

* FIN extracción
  ENDLOOP.

Cómo concepto es correcto, el problema es que de la primera SELECT saco entre 200 y 300 resultados, que son las iteraciones del loop, del cual después saco por cada iteración en el loop de la db externa unos 20000 resultados, por lo que cómo podeis ver es inviable.

El caso es que he leído por ahí que debo usar cabeceras y redefinir mis tablas y usar tablas hashed, pero no tengo mucha idea de cómo usarlo cómo concepto no me ha quedado muy claro.

Básicamente necesito un ejemplo de dos tablas con índices secundarios hashed o sorted con la imputación/append del row actual a otra tabla filtrado en un condicional, que se mostrará en el alv… Creo que es entendible por lo mal que me he explicado!

Si logro sacarlo os paso el código cómo recurso :slight_smile:

¡¡Muchísimas gracias y un saludo!!

Hola.
Te refieres a la necesidad de mejoras en términos de rendimiento pero te devuelve lo que necesitas?
Como recomendación general, sería mejor evitar el select dentro del loop, haciéndolo antes del bucle usando un for all entries.

Este tema se cerró automáticamente 30 días después de la última publicación. No se permiten nuevas respuestas.