optimizar mi programa

Colapsar
X
 
  • Tiempo
  • Mostrar
Limpiar Todo
nuevos mensajes
  • Yessica Suarez
    Junior Member
    • jun
    • 1

    #1

    optimizar mi programa

    Tengo estas dos rutinas me gustaria mejorarlas ya que duran ucho en la ejecucion, me podrian ayudar?



    FORM buscar_datos.

    SELECT banfn bnfpo sakto kostl lstar
    INTO CORRESPONDING FIELDS OF TABLE t_ebkn FROM ebkn
    WHERE kostl IN p_ceco.

    SORT t_ebkn.
    DESCRIBE TABLE t_ebkn LINES v_cont.
    CHECK v_cont NE 0. CLEAR v_cont.

    SELECT banfn bnfpo loekz txz01 menge badat lfdat preis ebeln ebelp
    bedat waers
    INTO CORRESPONDING FIELDS OF TABLE t_eban FROM eban
    FOR ALL ENTRIES IN t_ebkn
    WHERE banfn = t_ebkn-banfn AND
    bnfpo = t_ebkn-bnfpo AND
    BADAT IN p_fech.
    * lfdat IN p_fech.

    *
    SORT t_eban.
    DESCRIBE TABLE t_eban LINES v_cont.
    CHECK v_cont NE 0. CLEAR v_cont.
    *
    SORT t_ebkn BY banfn bnfpo.
    LOOP AT t_ebkn.
    CLEAR t_eban.
    READ TABLE t_eban WITH KEY banfn = t_ebkn-banfn
    bnfpo = t_ebkn-bnfpo.
    IF sy-subrc EQ 0.
    PERFORM blanquea.
    IF NOT t_eban-ebeln IS INITIAL.
    PERFORM buscar_pedido.
    IF w_ent EQ 0.
    PERFORM validar_partidas.
    ENDIF.
    ELSE.
    PERFORM validar_partidas.
    ENDIF.
    ENDIF.
    ENDLOOP.
    ENDFORM. " BUSCAR_DATOS






    FORM buscar_pedido.


    SELECT * FROM eket WHERE ebeln = t_eban-ebeln AND
    ebelp = t_eban-ebelp AND
    banfn = t_eban-banfn AND
    bnfpo = t_eban-bnfpo.
    MOVE eket-eindt TO w_eindt.
    EXIT.
    ENDSELECT.

    SELECT SINGLE * FROM ekpo WHERE ebeln = t_eban-ebeln AND
    ebelp = t_eban-ebelp.
    IF sy-subrc EQ 0.
    MOVE ekpo-ebeln TO w_ebeln.
    MOVE ekpo-ebelp TO w_ebelp.
    MOVE ekpo-txz01 TO w_txz01.
    MOVE ekpo-netwr TO w_netwr.
    MOVE ekpo-loekz TO w_loekz.
    SELECT SINGLE * FROM ekko WHERE ebeln = ekpo-ebeln.
    IF sy-subrc EQ 0.
    MOVE ekko-waers TO w_waers.
    SELECT SINGLE * FROM lfa1 WHERE lifnr = ekko-lifnr.
    IF sy-subrc EQ 0.
    MOVE ekko-lifnr TO w_lifnr.
    MOVE lfa1-name1 TO w_name1.
    ENDIF.
    ENDIF.
    ENDIF.

    SELECT * FROM ekkn WHERE ebeln = t_eban-ebeln AND
    ebelp = t_eban-ebelp.
    MOVE ekkn-loekz TO w_loekz1.
    IF t_eban-ebeln+0(2) EQ '51'.
    MOVE t_eban-bedat TO w_aedat.
    ELSE.
    MOVE ekkn-aedat TO w_aedat.
    ENDIF.
    EXIT.
    ENDSELECT.

    REFRESH: t_ekbe,
    t_ekbe1,
    t_ekbe2,
    t_ekbe3.

    CLEAR: t_ekbe,
    t_ekbe1,
    t_ekbe2,
    t_ekbe3.

    SELECT ebeln ebelp vgabe gjahr belnr buzei bwart
    budat wrbtr waers lfbnr
    INTO CORRESPONDING FIELDS OF TABLE t_ekbe2 FROM ekbe
    WHERE ebeln = t_eban-ebeln AND
    ebelp = t_eban-ebelp AND
    vgabe = '1' AND
    bwart = '101' AND
    wrbtr <> 0.

    SELECT ebeln ebelp vgabe gjahr belnr buzei bwart
    budat wrbtr waers lfbnr
    INTO CORRESPONDING FIELDS OF TABLE t_ekbe3 FROM ekbe
    WHERE ebeln = t_eban-ebeln AND
    ebelp = t_eban-ebelp AND
    vgabe = '1' AND
    bwart = '102' AND
    wrbtr <> 0.
    .
    MOVE 1 TO w_index.
    LOOP AT t_ekbe2.
    READ TABLE t_ekbe3 INDEX w_index.
    IF sy-subrc NE 0.
    MOVE-CORRESPONDING t_ekbe2 TO t_ekbe.
    APPEND t_ekbe.
    ENDIF.
    ADD 1 TO w_index.
    ENDLOOP.

    DESCRIBE TABLE t_ekbe LINES v_cont1.

    SELECT ebeln ebelp vgabe gjahr belnr buzei bwart
    budat wrbtr waers lfbnr
    INTO CORRESPONDING FIELDS OF TABLE t_ekbe1 FROM ekbe
    WHERE ebeln = t_eban-ebeln AND
    ebelp = t_eban-ebelp AND
    ( vgabe = '2' OR
    vgabe = 'P' ).

    DESCRIBE TABLE t_ekbe1 LINES v_cont2.

    LOOP AT t_ekbe1.
    SELECT SINGLE * FROM rbkp WHERE gjahr = t_ekbe1-gjahr AND
    belnr = t_ekbe1-belnr.
    IF sy-subrc EQ 0.
    IF rbkp-stblg NE space.
    DELETE t_ekbe1.
    ENDIF.
    ENDIF.
    ENDLOOP.

    SORT t_ekbe BY lfbnr.
    MOVE 1 TO w_index.
    LOOP AT t_ekbe.
    MOVE space TO w_belnr.
    MOVE 0 TO w_wrbtr1.
    MOVE 0 TO w_dif.
    LOOP AT t_ekbe1 WHERE lfbnr = t_ekbe-lfbnr.
    IF t_ekbe-wrbtr GT t_ekbe1-wrbtr.
    w_dif = t_ekbe-wrbtr - t_ekbe1-wrbtr.
    ELSE.
    IF t_ekbe-wrbtr LT t_ekbe1-wrbtr.
    w_dif = t_ekbe1-wrbtr - t_ekbe-wrbtr.
    ELSE.
    w_dif = t_ekbe1-wrbtr - t_ekbe-wrbtr.
    ENDIF.
    ENDIF.
    IF w_dif GE 0 AND
    w_dif LE 1.
    MOVE t_ekbe1-belnr TO w_belnr.
    MOVE t_ekbe1-wrbtr TO w_wrbtr1.
    PERFORM buscar_doccont.
    EXIT.
    ENDIF.
    ENDLOOP.
    ** MOVE t_ekbe-lfbnr TO w_lfbnr.
    MOVE t_ekbe-belnr TO w_belnr1.
    MOVE t_ekbe-budat TO w_budat.
    MOVE t_ekbe-waers TO w_waers1.
    MOVE t_ekbe-wrbtr TO w_wrbtr.
    MOVE 1 TO w_ent.
    PERFORM validar_partidas.
    ADD 1 TO w_index.
    ENDLOOP.
    IF v_cont1 EQ 0 AND v_cont2 NE 0.
    LOOP AT t_ekbe1.
    MOVE t_ekbe1-belnr TO w_belnr.
    MOVE t_ekbe1-wrbtr TO w_wrbtr1.
    PERFORM buscar_doccont.
    MOVE 1 TO w_ent.
    PERFORM validar_partidas.
    ENDLOOP.
    ENDIF.

    ENDFORM. " buscar_pedido
  • mysmb2
    Senior Member
    • ene
    • 406

    #2
    Hola,
    primero tenes que sacar los CORRESPONDING FIELDS OF TABLE ya que se consume tiempo buscando que campo seleccionado corresponde con con cada campo de la tabla interna.
    En cuanto a los FOR ALL ENTRIES IN t_tabla debes tener ordenada dicha tabla por los campos a comparar y borrar los duplicados si los puede haber.

    Tambien veo que en la segunda rutina tenes un Select dentro de un loop. aca deberias reemplazarlo por un FOR ALL ENTRIES a esa tabla que haces el loop.

    Por ultimo hay loops anidados, deberias tratar de evitarlo de ser posible.

    Espero te sirva de ayuda para mejorar el rendimiento.

    Saludos.
    Sebastián Chiavia
    http://www.programacionabap.com.ar

    Comentario

    • Fabian leonardo velasquez
      Member
      • sep
      • 62

      #3
      Premisas

      Programar es un arte. Compañero para tu experiencia, cuando se programa se hace mas o menos así:

      1. Definir lo elementos a utilizar
      2. Inicializar variables i son necesarias.
      3. CONSULTAS A LA BASE DE DATOS ( en tu ejemplo ), para esto debes utilizar areas de trabajo, tablas internas. el select *** end select consume mucho mas tiempo que hacer un FOR ALL Entries (Primero organiza las tablas por campos clave) para poderlos organizar en un area de trabajo, luego no tendras que acceder a la base de datos( ahorro de tiempo) , si requieres un dato ya esta en la TI. y para eso puedes aplicar read tables o loop los cuales tambien puedes anidar pero para manejar la eficiencia debes discriminar con sentencias where y/o check para evitar quedar inmerso en ciclos innecesarios.

      4. Luego de tener los datos listos y organizados ya puedes imprimir o hacer lo que requieras.
      Cordialmente
      Fabián Leonardo Velásquez P.
      Consultor SAP ABAP
      Bogota - Colombia

      Comentario

      • jarabas
        Senior Member
        • ene
        • 109

        #4
        evita los into corresponding field. create estructuras internas con los campos en el mismo orden en el que los pongas en la select.

        TYPES: BEGIN OF ty_ejemplo,
        campo1 TYPE el_que_sea,
        campo2 type el_que_sea,
        ....
        END OF ty_ejemplo.

        data: it_ejemplo type standard table of ty_ejemplo.

        select campo1 campo2 ...
        into table it_ejemplo
        from tabla
        where condicion.

        Evita las tablas con cabeceras, procura utilizar workings.

        no uses los Select ... endselect.


        tú código:
        SELECT *
        FROM eket
        WHERE ebeln = t_eban-ebeln AND
        ebelp = t_eban-ebelp AND
        banfn = t_eban-banfn AND
        bnfpo = t_eban-bnfpo.
        MOVE eket-eindt TO w_eindt.
        EXIT.
        ENDSELECT.

        si sólo quieres el campo "eindt", haz lo siguiente:
        SELECT eindt
        INTO w_eindt
        FROM eket
        WHERE ebeln = t_eban-ebeln AND
        ebelp = t_eban-ebelp AND
        banfn = t_eban-banfn AND
        bnfpo = t_eban-bnfpo.

        tú código:
        SELECT SINGLE * FROM ekpo WHERE ebeln = t_eban-ebeln AND
        ebelp = t_eban-ebelp.
        IF sy-subrc EQ 0.
        MOVE ekpo-ebeln TO w_ebeln.
        MOVE ekpo-ebelp TO w_ebelp.
        MOVE ekpo-txz01 TO w_txz01.
        MOVE ekpo-netwr TO w_netwr.
        MOVE ekpo-loekz TO w_loekz.

        Mejor así:
        TYPES: BEGIN OF ty_ekpo,
        ebeln TYPE EBELN,
        ebelp TYPE EBELP,
        txz01 TYPE TXZ01,
        netwr TYPE BWERT,
        loekz TYPE eloek,
        END OF ty_ekpo.

        data: wa_ekpo type ty_ekpo.

        SELECT SINGLE ebeln ebelp txz01 netwr loekz
        INTO wa_ekpo
        FROM ekpo
        WHERE ebeln = t_eban-ebeln AND
        ebelp = t_eban-ebelp.

        IF sy-subrc EQ 0.
        ya tienes los datos en la working area (WA_EKPO)
        ENDIF.


        Espero haberte ayudado.
        Editado por última vez por jarabas; 23/07/2010, 10:07:12.

        Comentario

        • DavidXD_XD
          Moderator
          • ago
          • 1255

          #5
          Hola Yessica, aki he mejorado un poco el codigo ... con los tips que comentaron jarabas, Fabian y mysmb2 ademas algunos tips mas ...

          Primero: declarar bien las variables, asumi que t_ekbe, t_ekbe1, t_ekbe2 y t_ekbe3 tenian la misma estructura y todos se trabajaban para construir la informacion en t_ekbe
          Código:
          TYPES: BEGIN OF ty_ebkn,
                   banfn TYPE ebkn-banfn,
                   bnfpo TYPE ebkn-bnfpo,
                   sakto TYPE ebkn-sakto,
                   kostl TYPE ebkn-kostl,
                   lstar TYPE ebkn-lstar,
                   ...        Otros campos a trabajar
                 END OF ty_ebkn.
          
          TYPES: BEGIN OF ty_eban,
                   banfn TYPE
                   bnfpo
                   loekz
                   txz01
                   menge
                   badat
                   lfdat
                   preis
                   ebeln
                   ebelp
                   bedat
                   waers
                   ...    Otros campos a trabajar
                 END OF ty_eban.
          
          TYPES: BEGIN OF ty_ekbe,
                   ebeln TYPE ekbe-ebeln,
                   ebelp TYPE ekbe-ebelp,
                   vgabe TYPE ekbe-vgabe,
                   gjahr TYPE ekbe-gjahr,
                   belnr TYPE ekbe-belnr,
                   buzei TYPE ekbe-buzei,
                   bwart TYPE ekbe-bwart,
                   budat TYPE ekbe-budat,
                   wrbtr TYPE ekbe-wrbtr,
                   waers TYPE ekbe-waers,
                   lfbnr TYPE ekbe-lfbnr,
                   ... otros campos ...
                 END OF ty_ekbe.
          
          DATA: t_ebkn  TYPE STANDARD TABLE OF ty_ebkn,
                t_eban  TYPE STANDARD TABLE OF ty_eban,
                t_ekbe  TYPE STANDARD TABLE OF ty_ekbe,
                t_ekbe1 TYPE STANDARD TABLE OF ty_ekbe,
                t_ekbe2 TYPE STANDARD TABLE OF ty_ekbe,
                t_ekbe3 TYPE STANDARD TABLE OF ty_ekbe,
          
          FIELD-SYMBOLS: <fs_ebkn> TYPE ty_ebkn,
                         <fs_eban> TYPE ty_eban.
          Segundo: ahi va la modificacion de las subrutinas, como te aconsejaron les quite los CORRESPONDING FIELDS y uni las tablas EKKO, EKPO, LFA1 ya que esas 3 tablas estan relacionadas directamente a excepcion de la tabla EKKN porque una orden de compra no necesariamente tiene datos de imputacion

          Primera Subrutina
          Código:
          FORM buscar_datos.
          
            SELECT banfn bnfpo sakto kostl lstar
              INTO TABLE t_ebkn
                FROM ebkn
                  WHERE kostl IN p_ceco.
          
            CHECK sy-subrc = 0.
          
            SORT t_ebkn BY (campos).
          
            SELECT banfn bnfpo loekz txz01 menge badat lfdat
                   preis ebeln ebelp bedat waers
              INTO TABLE t_eban
                FROM eban
                  FOR ALL ENTRIES IN t_ebkn
                    WHERE banfn = t_ebkn-banfn
                      AND bnfpo = t_ebkn-bnfpo
                      AND badat IN p_fech.
          
            CHECK sy-subrc = 0.
          
            SORT t_eban BY (campos).
            SORT t_ebkn BY banfn bnfpo.
          
            LOOP AT t_ebkn ASSIGNIGN <fs_ebkn>.
              CLEAR t_eban.
              READ TABLE t_eban ASSIGNING <fs_eban> WITH KEY banfn = t_ebkn-banfn
                                                             bnfpo = t_ebkn-bnfpo
                                                    BINARY SEARCH.
              IF sy-subrc EQ 0.
                PERFORM blanquea.
                IF NOT <fs_eban>-ebeln IS INITIAL.
                  PERFORM buscar_pedido USING <fs_eban>.
                  IF w_ent EQ 0.
                    PERFORM validar_partidas.
                  ENDIF.
                ELSE.
                  PERFORM validar_partidas.
                ENDIF.
              ENDIF.
            ENDLOOP.
          
          ENDFORM. " BUSCAR_DATOS
          Segunda Subrutina
          Código:
          FORM buscar_pedido USING ps_eban TYPE ty_eban.
          [COLOR="Blue"]* Variables Locales[/COLOR]
            DATA: lt_ekbe TYPE STANDARD TABLE OF ty_ekbe.
          
            FIELD-SYMBOLS: <fs_ekbe>  TYPE ty_ekbe,
                           <fs_ekbe1> TYPE ty_ekbe.
          
            SELECT SINGLE eindt
              INTO w_eindt
                FROM eket
                  WHERE ebeln = ps_eban-ebeln
                    AND ebelp = ps_eban-ebelp
                    AND banfn = ps_eban-banfn
                    AND bnfpo = ps_eban-bnfpo.
          
            SELECT SINGLE a~ebeln b~ebelp b~txz01 b~netwr
                          b~loekz b~waers a~lifnr c~name1 d~loekz d~bedat
              INTO (w_ebeln,w_ebelp,w_txz01,w_netwr,w_loekz,
                    w_waers,w_lifnr,w_name1,w_loekz1,w_aedat)
                FROM ekko AS a INNER JOIN ekpo AS b ON a~ebeln = b~ebeln
                               INNER JOIN lfa1 AS c ON a~lifnr = c~lifnr
                               LEFT  JOIN ekkn AS d ON b~ebeln = d~ebeln
                                                   AND b~ebelp = d~ebelp
                  WHERE b~ebeln = ps_eban-ebeln
                    AND b~ebelp = ps_eban-ebelp.
          [COLOR="blue"]* Si los 2 primeros digitos no son 51 se limpia el campo fecha recuperado[/COLOR]
          [COLOR="blue"]* de la tabla EKKN, sino se mantiene el valor recuperado[/COLOR]
            IF ps_eban-ebeln(2) EQ '51'.
              MOVE ps_eban-bedat TO w_aedat.
              CLEAR w_aedat.
            ENDIF.
          
            REFRESH: t_ekbe, t_ekbe1, t_ekbe2, t_ekbe3.
            CLEAR: t_ekbe, t_ekbe1, t_ekbe2, t_ekbe3.
          [COLOR="blue"]* Listar todos los registros con clase de movimimento 102 y 101[/COLOR]
            SELECT ebeln ebelp vgabe gjahr belnr buzei
                   bwart budat wrbtr waers lfbnr
              INTO TABLE lt_ekbe
                FROM ekbe
                  WHERE ebeln = ps_eban-ebeln
                    AND ebelp = ps_eban-ebelp
                    AND vgabe = '1'
                    AND ( bwart = '101' OR bwart = '102' )
                    AND wrbtr <> 0.
          
            LOOP AT lt_ekbe ASSIGNING <fs_ekbe>.
              CASE <fs_ekbe>-bwart.
                WHEN '101'.
                  APPEND <fs_ekbe> TO t_ekbe2.
                WHEN '102'.
                  APPEND <fs_ekbe> TO t_ekbe3.
              ENDCASE.
            ENDLOOP.
          
            MOVE 1 TO w_index.
          
            LOOP AT t_ekbe2 ASSIGNING <fs_ekbe>.
              READ TABLE t_ekbe3 TRANSPORTING NO FIELDS INDEX w_index.
          
              IF sy-subrc NE 0.
          [COLOR="blue"]* Si t_ekbe y t_ekbe2 tienen los mismos campos[/COLOR]
                APPEND <fs_ekbe> TO t_ekbe2.
          [COLOR="blue"]* Si tienen por lo menos un campo diferente, descomentar las 2 lineas
          *      MOVE-CORRESPONDING t_ekbe2 TO t_ekbe.
          *      APPEND t_ekbe.[/COLOR]
              ENDIF.
              ADD 1 TO w_index.
            ENDLOOP.
          
            DESCRIBE TABLE t_ekbe LINES v_cont1.
          
            SELECT ebeln ebelp vgabe gjahr belnr buzei
                   bwart budat wrbtr waers lfbnr
              INTO TABLE t_ekbe1
                FROM ekbe
                  WHERE ebeln = ps_eban-ebeln
                    AND ebelp = ps_eban-ebelp
                    AND ( vgabe = '2' OR vgabe = 'P' ).
          
            DESCRIBE TABLE t_ekbe1 LINES v_cont2.
          
            LOOP AT t_ekbe1 ASSIGNING <fs_ekbe>.
              SELECT COUNT( * )
                FROM rbkp
                  WHERE gjahr = <fs_ekbe>-gjahr
                    AND belnr = <fs_ekbe>-belnr
                    AND stblg <> space.
          
              IF sy-subrc EQ 0.
                DELETE t_ekbe1 INDEX sy-tabix.
              ENDIF.
            ENDLOOP.
          
            SORT t_ekbe BY lfbnr.
            MOVE 1 TO w_index.
          
            LOOP AT t_ekbe ASSIGNING <fs_ekbe>.
              CLEAR: w_belnr, w_wrbtr1, w_dif.
          
              LOOP AT t_ekbe1 ASSIGNING <fs_ekbe1> WHERE lfbnr = <fs_ekbe>-lfbnr.
                IF <fs_ekbe>-wrbtr GT <fs_ekbe1>-wrbtr.
                  w_dif = <fs_ekbe>-wrbtr - <fs_ekbe1>-wrbtr.
                ELSE.
                  IF <fs_ekbe>-wrbtr LT <fs_ekbe1>-wrbtr.
                    w_dif = <fs_ekbe1>-wrbtr - <fs_ekbe>-wrbtr.
                  ELSE.
                    w_dif = <fs_ekbe1>-wrbtr - <fs_ekbe>-wrbtr.
                  ENDIF.
                ENDIF.
                IF w_dif GE 0 AND w_dif LE 1.
                  MOVE <fs_ekbe1>-belnr TO w_belnr.
                  MOVE <fs_ekbe1>-wrbtr TO w_wrbtr1.
                  PERFORM buscar_doccont.
                  EXIT.
                ENDIF.
              ENDLOOP.
          [COLOR="blue"]** MOVE t_ekbe-lfbnr TO w_lfbnr.[/COLOR]
              MOVE: <fs_ekbe>-belnr TO w_belnr1,
                    <fs_ekbe>-budat TO w_budat,
                    <fs_ekbe>-waers TO w_waers1,
                    <fs_ekbe>-wrbtr TO w_wrbtr.
          
              MOVE 1 TO w_ent.
              PERFORM validar_partidas.
              ADD 1 TO w_index.
            ENDLOOP.
          
            IF v_cont1 EQ 0 AND v_cont2 NE 0.
              LOOP AT t_ekbe1 ASSIGNING <fs_ekbe>.
                MOVE: <fs_ekbe>-belnr TO w_belnr,
                      <fs_ekbe>-wrbtr TO w_wrbtr1.
                PERFORM buscar_doccont.
                MOVE 1 TO w_ent.
                PERFORM validar_partidas.
              ENDLOOP.
            ENDIF.
          
          ENDFORM. " buscar_pedido
          Espero te pueda ayudar
          David Carballido Córdova

          Comentario

          • Karla V.
            Senior Member
            • may
            • 100

            #6
            -_-

            Hola, todo el mundo dice que no usen "into corresponding fields of table" yo lo uso todo el tiempo porque no se que otra cosa usar, ¿me pueden dar un ejemplo de un codigo que sustituya al "into corresponding fields of table" ?

            Comentario

            Trabajando...