Ajuda codigo progress relacionamento tabelas

Discussão em 'Progress 4GL' iniciado por diegocf, Setembro 28, 2010.

  1. diegocf

    diegocf Membro Participativo

    Boa tarde galera,

    To tentando criar aqui um programinha que exporta alguns dados via csv, no entanto ja to relacionando tantas tabelas atraves do EACH que acho que ta ficando pesado, agora ainda preciso relacionar a tabela it-nota-fisc para pegar o valor liquido dos itens e soma-los para calcular uma comissao, mas quando tento relaciona-la o relatorio ja nem gera mais, algum poderia me ajudar falando como poderia ficar meu codigo com a tabela it-nota-fisc relacionada.

    DEF VAR h-prog AS HANDLE NO-UNDO.
    DEF VAR icms AS DEC.
    DEF VAR vl-comis-calc AS DEC .
    DEF VAR vl-liq-calc as dec.
    DEF VAR vl-tot-it-calc as dec.
    DEF VAR vl-comiss-calc as dec.
    DEF VAR sit-aval as char.
    DEF VAR vl-tot-item-calc as dec.

    RUN utp/ut-utils.p PERSISTENT SET h-prog.


    OUTPUT TO "C:\TEMP\EXPORTA_NOTAS.CSV".


    PUT UNFORMATTED "REPRESENTANTE" ";"
    "ESTABEL" ";"
    "PED-CLIENTE" ";"
    "PEDIDO" ";"
    "EMISSAO" ";"
    "EMITENTE" ";"
    "NOME-ABREV" ";"
    "VL PEDIDO" ";"
    "% COMISSAO" ";"
    "VALOR COMISS" ";"
    "STATUS CRED" ";"
    SKIP.

    PUT UNFORMATTED "Item" ";"
    "Qtd Atend" ";"
    "VL Orig" ";"
    "VL Bruto" ";"
    "% Desc." ";"
    "VL Tot" ";"




    SKIP(02).

    assign vl-liq-calc = 0.
    assign vl-tot-item-calc = 0.


    FOR EACH ped-venda where ped-venda.no-ab-reppri = "ALLAN GOMES"
    AND ped-venda.dt-cancela = ?
    /* AND ped-venda.nr-pedcli = "AFV000380.1"*/
    and ped-venda.dt-emissao >= 02/01/2010
    and ped-venda.dt-emissao <= 09/30/2010,
    each ped-repre where ped-repre.nome-ab-rep = ped-venda.no-ab-reppri
    and ped-repre.nr-pedido = ped-venda.nr-pedido,
    EACH nota-fiscal where nota-fiscal.nome-ab-cli = ped-venda.nome-abrev
    and nota-fiscal.nr-pedcli = ped-venda.nr-pedcli,
    each fat-repre use-index ch-fatrep where fat-repre.cod-estabel = nota-fiscal.cod-estabel
    and fat-repre.nr-fatura = nota-fiscal.nr-fatura
    and fat-repre.nome-ab-rep = nota-fiscal.no-ab-reppri









    break by ped-venda.dt-emissao:



    /*********** Verifica se o pedido esta em qual status *****************/

    if ped-venda.cod-sit-aval = 1 then

    assign sit-aval = "NAO AVALIADO".

    if ped-venda.cod-sit-aval = 2 then

    assign sit-aval = "AVALIADO".

    if ped-venda.cod-sit-aval = 3 then

    assign sit-aval = "APROVADO".

    if ped-venda.cod-sit-aval = 4 then

    assign sit-aval = "NAO APROVADO".

    if ped-venda.cod-sit-aval = 5 then

    assign sit-aval = "PENDENTE INFORM.".
    /*******************************************************/



    /* Calculo da comissão */


    assign vl-comiss-calc = (fat-repre.perc-comis * ped-venda.vl-tot-ped / 100).
    /*assign vl-tot-item-calc = (vl-tot-item-calc + ? ). */

    put unformatted

    ped-venda.no-ab-reppri ";"
    ped-venda.cod-estabel ";"
    ped-venda.nr-pedido ";"
    ped-venda.nr-pedcli ";"
    ped-venda.dt-emissao ";"
    ped-venda.cod-emitente ";"
    ped-venda.nome-abrev ";"
    ped-venda.vl-tot-ped ";"
    vl-tot-item-calc ";"
    fat-repre.perc-comis "%" ";"
    nota-fiscal.vl-comis-nota ";"
    sit-aval ";"

    skip.



    for each ped-item where ped-item.nome-abrev = ped-venda.nome-abrev and
    ped-item.nr-pedcli = ped-venda.nr-pedcli.

    /* Calculo do Valor Liquido do Item */

    assign vl-liq-calc = ( ped-item.qt-atendida * ped-item.vl-preori).


    /* Verifica se o item foi faturado */

    if ped-item.qt-atendida = 0 then

    do:
    vl-tot-it-calc = 0.
    end.
    else
    do:
    vl-tot-it-calc = ped-item.vl-tot-it.
    end.



    /*************************************/


    put unformatted

    ped-item.it-codigo ";"
    ped-item.qt-atendida ";"
    ped-item.vl-preori ";"
    vl-liq-calc ";"
    per-des-item "%" ";"
    vl-tot-it-calc ";"



    skip.


    end.
    end.


    /*******************************************************************************************************************/
    RUN EXECUTE IN h-prog(INPUT "excel.exe", INPUT "c:\temp\EXPORTA_NOTAS.csv").
    OUTPUT CLOSE.
  2. eduardo.leite

    eduardo.leite Equipe de Suporte Moderador Equipe de Suporte

    Informação em duplicidade... olhe o próximo tópico...
  3. eduardo.leite

    eduardo.leite Equipe de Suporte Moderador Equipe de Suporte

    Caro colega,

    Refiz o seu código, ajustando alguns detalhes para melhorar o desempenho da rotina e aplicar regras de negócio.

    Segue o novo código:

    Código:
    
    def var h-prog              as handle no-undo.
    def var h-acomp             as handle no-undo.
    
    def var icms                as dec.
    def var vl-comis-calc       as dec.
    def var vl-liq-calc         as dec.
    def var vl-tot-it-calc      as dec.
    def var vl-comiss-calc      as dec.
    def var sit-aval            as char.
    def var vl-tot-item-calc    as dec.
    
    run utp/ut-utils.p persistent set h-prog.
    
    run utp/ut-acomp.p persistent set h-acomp.  
    {utp/ut-liter.i "Aguarde..."}
    run pi-inicializar in h-acomp (input "Selecionando Pedidos de Venda..."). 
    
    output to "c:\temp\exporta_notas.csv" no-convert page-size 0.
    
    put unformatted 
        "Representante" ";"
        "Estabel"       ";"
        "Ped. Cliente"  ";"
        "Pedido"        ";"
        "Emissao"       ";"
        "Emitente"      ";"
        "Nome Abrev"    ";"
        "Vl Pedido"     ";" 
        "% Comissao"    ";"
        "Valor Comiss"  ";"
        "Status Cred"   ";"
        skip.
    
    put unformatted 
        "Item"          ";"
        "Qtd Atend"     ";"
        "Vl Orig"       ";"
        "Vl Bruto"      ";"
        "% Desc."       ";"
        "Vl Tot"        ";" 
        skip(2).
    
    assign  vl-liq-calc      = 0
            vl-tot-item-calc = 0.
    
    for each ped-venda no-lock
       where ped-venda.no-ab-reppri  = "<nome do representante>" 
         and ped-venda.dt-cancela    = ? 
         and ped-venda.dt-emissao   >= 01/01/2009
         and ped-venda.dt-emissao   <= today
          by ped-venda.dt-emissao:
        
        run pi-acompanhar  in h-acomp (input "Pedido Venda: " + string(ped-venda.nr-pedido)).
    
        process events.
        
        for each /*ped-repre no-lock 
           where ped-repre.nr-pedido     = ped-venda.nr-pedido
             and ped-repre.nome-ab-rep   = ped-venda.no-ab-reppri,
          each*/ nota-fiscal use-index ch-pedido no-lock 
           where nota-fiscal.nome-ab-cli = ped-venda.nome-abrev 
             and nota-fiscal.nr-pedcli   = ped-venda.nr-pedcli,
            each fat-repre use-index ch-fatrep no-lock
           where fat-repre.cod-estabel   = nota-fiscal.cod-estabel
             and fat-repre.serie         = nota-fiscal.serie
             and fat-repre.nr-fatura     = nota-fiscal.nr-fatura 
             and fat-repre.nome-ab-rep   = nota-fiscal.no-ab-rep
           break by nota-fiscal.nome-abrev 
                 by nota-fiscal.nr-pedcli:
        
            /*********** verifica se o pedido esta em qual status *****************/
        
    /*         if ped-venda.cod-sit-aval = 1 then                        */
    /*             assign sit-aval = "Nao Avaliado".                     */
    /*         else                                                      */
    /*             if ped-venda.cod-sit-aval = 2 then                    */
    /*                 assign sit-aval = "Avaliado".                     */
    /*             else                                                  */
    /*                 if ped-venda.cod-sit-aval = 3 then                */
    /*                     assign sit-aval = "Aprovado".                 */
    /*                 else                                              */
    /*                     if ped-venda.cod-sit-aval = 4 then            */
    /*                         assign sit-aval = "Nao Aprovado".         */
    /*                     else                                          */
    /*                         if ped-venda.cod-sit-aval = 5 then        */
    /*                             assign sit-aval = "Pendente Inform.". */
    /*                         else                                      */
    /*                             assign sit-aval = "".                 */
        
            case ped-venda.cod-sit-aval:
        
                when 1 then assign sit-aval = "Nao Avaliado".
                when 2 then assign sit-aval = "Avaliado".
                when 3 then assign sit-aval = "Aprovado".
                when 4 then assign sit-aval = "Nao Aprovado".
                when 5 then assign sit-aval = "Pendente Inform.".
                otherwise   assign sit-aval = "".
        
            end case.
        
            /*******************************************************/
        
            /* calculo da comissão */
        
            assign vl-comiss-calc = (fat-repre.perc-comis * ped-venda.vl-tot-ped / 100).
        
            put unformatted
                ped-venda.no-ab-reppri      ";"
                ped-venda.cod-estabel       ";"
                ped-venda.nr-pedido         ";"
                ped-venda.nr-pedcli         ";"
                ped-venda.dt-emissao        ";"
                ped-venda.cod-emitente      ";"
                ped-venda.nome-abrev        ";"
                ped-venda.vl-tot-ped        ";"
                vl-tot-item-calc            ";"
                fat-repre.perc-comis "%"    ";"
                nota-fiscal.vl-comis-nota   ";"
                sit-aval                    ";"
                skip.
    
            if last-of(nota-fiscal.nr-pedcli) then
                for each ped-item of ped-venda no-lock:
            
                    /* calculo do valor liquido do item */
            
                    assign vl-liq-calc = (ped-item.qt-atendida * ped-item.vl-preori).
            
                    /* verifica se o item foi faturado */
            
                    if ped-item.qt-atendida = 0 then
                        assign vl-tot-it-calc = 0.
                    else
                        assign vl-tot-it-calc = ped-item.vl-tot-it.
            
                    /*************************************/
            
                    put unformatted
                        ped-item.it-codigo   ";"
                        ped-item.qt-atendida ";"
                        ped-item.vl-preori   ";"
                        vl-liq-calc          ";"
                        per-des-item "%"     ";"
                        vl-tot-it-calc       ";"
                        skip.
            
                end.
        
        end.
    
    end.
    
    /*******************************************************************************************************************/ 
    
    output close.
    
    run execute in h-prog(input "excel.exe", input "c:\temp\exporta_notas.csv").
    
    run pi-finalizar in h-acomp.
    
    
    Agora vamos as dicas:

    01) Nem todas as vezes precisamos colocar todas as leituras no primeiro bloco do for each, na maioria das vezes colocamos somente as tabelas que faremos a seleção dos registros. No seu exemplo:

    a) Você fazendo uma seleção somente na tabela de ped-venda, sendo assim deixe neste primeiro bloco somente a tabela de ped-venda e a cada registro lido faremos em outros blocos as demais leitura;
    b) Você colocou BREAK-BY no for each, quanto mais tabelas você usar e quando menos indices forem usados, a leitura irá demorar mais, pois a rotina terá que rodar toda a base de dados para montar os registros e agrupar pelo campo informado no break by, como você não estava usando o FIRST-OF ou LAST-OF então não tem necessidade do BREAK BY e poderá ser usado somente o BY.

    02) Não esqueça está dica, se a sua rotina for somente para leitura, use SEMPRE o atributo NO-LOCK nos FOR e FIND, se não definir será usado SHARE-LOCK e este poderá impactar na perfomance e até travamentos de usuários (DAD-LOCK). Então não esqueça, sempre coloque NO-LOCK.

    03) Bloco de leitura das demais tabelas relacionadas a tabela de ped-venda:

    a) PED-REPRE: Em momento nenhum visualizei a utilização desta tabela, então não tem necessidade de leitura desta, eliminando uma leitura a base de dados;
    b) FAT-REPRE: Toda vez que for fazer uma leitura de relacionamentos diretos (indice primario) procure usar na seleção todos os campos do indice principal da tabela pai com a filha, neste caso o que temos:
    i. Você está lendo os pedidos de venda;
    ii. Você esta lendo todas as notas fiscais do pedido de venda e do representante do pedido de venda;
    iii. Para cada nota fiscal emitida, foi criado 01 ou mais registros nas faturas do representante, sendo assim teremos que ler somente as fatura de representantes da nota fiscal lida, então temos que usar a chave completa: ESTABELECIMENTO + SERIE + NR NOTA FISCAL, no seu código faltou a Série do Documento, com isto, além de pegar faturas de outra nota com mesmo número e serie diferente, a rotina fica muito lenta, pois vai ler a base toda para selecionar os registros.

    04) Função IF:

    a) Quando precisar validar um campo e setar uma descrição use a função CASE, pois tem menos impacto na perfomance, mas se usar o IF, não use separado, use utilizando o ELSE. Assim se a primeira afirmativa for verdadeira ele já para, caso contrário vai validando até verdadeiro. Sem o ELSE, ele passa por todos os IF´s.

    05) Leitura da Tabela PED-ITEM:

    a) Você colocou a leitura da tabela PED-ITEM dentro do bloco de NOTAS FISCAIS e FAT-REPRE, imagine você que seu pedido de venda tenha 10 Notas Fiscais e cada nota fiscal tem 5 Faturas de Representante, se isto ocorrer você terá 50 leituras da tabela ped-item, pois a cada fat-repre será feito a leitura no ped-item e impresso.

    Bom, as mais importantes foram estas dicas, qualquer dúvida entre em contato.
  4. diegocf

    diegocf Membro Participativo

    Obrigado Eduardo pelas dicas serão de grande valia, mesmo o relatorio ta sendo emitido em instantes, a unica questão que faltou era o seguinte
    O campo "ped-venda.vl-tot-ped" me traz o valor do pedido com total, eu precisava de algum campo que me trouxesse o valor desconsiderando o ICMS ou um campo que me de o ICMS para eu desocnsiderar do calculo da comissao, entendeu, por isso que eu tava querendo colocar a tabela ped-item em cima no primeiro bloco, pois o valor deveria sair em cima e nao nas linhas dos itens.


    [prog=]/* calculo da comissão */

    assign vl-comiss-calc = (fat-repre.perc-comis * ped-venda.vl-tot-ped / 100).

    put unformatted
    ped-venda.no-ab-reppri ";"
    ped-venda.cod-estabel ";"
    ped-venda.nr-pedido ";"
    ped-venda.nr-pedcli ";"
    ped-venda.dt-emissao ";"
    ped-venda.cod-emitente ";"
    ped-venda.nome-abrev ";"
    ped-venda.vl-tot-ped ";" vl-tot-item-calc ";"
    fat-repre.perc-comis "%" ";"
    nota-fiscal.vl-comis-nota ";"
    sit-aval ";"
    skip.

    if last-of(nota-fiscal.nr-pedcli) then
    for each ped-item of ped-venda no-lock:

    /* calculo do valor liquido do item */

    assign vl-liq-calc = (ped-item.qt-atendida * ped-item.vl-preori).

    /* verifica se o item foi faturado */

    if ped-item.qt-atendida = 0 then
    assign vl-tot-it-calc = 0.
    else
    assign vl-tot-it-calc = ped-item.vl-tot-it.

    /*************************************/

    put unformatted
    ped-item.it-codigo ";"
    ped-item.qt-atendida ";"
    ped-item.vl-preori ";"
    vl-liq-calc ";"
    per-des-item "%" ";"
    vl-tot-it-calc ";"
    skip.

    end.

    end.

    end.[/prog]
  5. eduardo.leite

    eduardo.leite Equipe de Suporte Moderador Equipe de Suporte

    Diego,

    Respondendo a questão acima e o e-mail enviado, fiz um código para você ter uma idéia do que precisa, adeque-o a sua necessidade.

    Código:
    def var h-prog              as handle no-undo.
    def var h-acomp             as handle no-undo.
    
    def var sit-aval            as char     format "x(16)".
    
    run utp/ut-utils.p persistent set h-prog.
    
    run utp/ut-acomp.p persistent set h-acomp.  
    {utp/ut-liter.i "Aguarde..."}
    run pi-inicializar in h-acomp (input "Selecionando Pedidos de Venda..."). 
    
    output to "c:\temp\exporta_notas.txt" no-convert page-size 0.
        
    put unformatted 
        "INFORMAÇÕES DO PEDIDO DE VENDA                                                                                                                  INFORMAÇÕES DO ITEM DO PEDIDO DE VENDA                                                              DADOS N.FISCAL   DADOS DO ITEM DA NOTA FISCAL                                     FATURA REPRE                                      " skip
        "----------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- ---------------- ---------------------------------------------------------------- ------------                                      " skip
        "Representant Est Ped. Cliente Pedido      Emissao    Emitente  Nome Abrev    Vl Tot Bruto PV  Vl Liq Bruto PV Vl Liq Aberto PV Status Credito   Seq It Item                  Qtd Item     Qtd Atend     Vl Tot Item     Vl Liq Item   Vl Liq Aberto Valor Comis NF   Qtde Faturada   Vl Total Fatur    Vl Total ICMS Vl Liquido Fatur   % Comissão Nota Fiscal (Estabel + Serie + Nr Nf " skip
        "------------ --- ------------ ----------- ---------- --------- ------------ ---------------- ---------------- ---------------- ---------------- ------ ---------------- ------------- ------------- --------------- --------------- --------------- ---------------- ------------- ---------------- ---------------- ---------------- ------------ -------------------------------------" skip.
    
    for each ped-venda no-lock
       where (ped-venda.no-ab-reppri >= "" 
         and  ped-venda.no-ab-reppri <= "ZZZZZZZZZZZZ")
         and ped-venda.dt-cancela     = ? 
         and (ped-venda.dt-emissao   >= 01/01/2009
         and  ped-venda.dt-emissao   <= today)
          by ped-venda.nr-pedido:
    
        run pi-acompanhar  in h-acomp (input "Pedido Venda: " + string(ped-venda.nr-pedido)).
    
        process events.
    
        case ped-venda.cod-sit-aval:
    
            when 1 then assign sit-aval = "Nao Avaliado".
            when 2 then assign sit-aval = "Avaliado".
            when 3 then assign sit-aval = "Aprovado".
            when 4 then assign sit-aval = "Nao Aprovado".
            when 5 then assign sit-aval = "Pendente Inform.".
            otherwise   assign sit-aval = "".
    
        end case.
    
        def var de-qtde-fat         like ped-item.qt-pedida     no-undo.
        def var de-vlr-fat-bru      like ped-venda.vl-tot-ped   no-undo.
        def var de-vlr-fat-icms     like ped-venda.vl-tot-ped   no-undo.
        def var de-vlr-fat-liq      like ped-venda.vl-tot-ped   no-undo.
        def var de-vlr-com-nota     like ped-venda.vl-tot-ped   no-undo.
        def var c-notas-fiscais     as character                no-undo.
    
        assign de-qtde-fat     = 0
               de-vlr-fat-bru  = 0
               de-vlr-fat-icms = 0
               de-vlr-fat-liq  = 0
               c-notas-fiscais = "".
    
        for each ped-item of ped-venda no-lock:
    
            for each it-nota-fisc
               where it-nota-fisc.nr-pedcli   = ped-venda.nr-pedcli
                 and it-nota-fisc.nome-ab-cli = ped-venda.nome-abrev
                 and it-nota-fisc.nr-seq-ped  = ped-item.nr-sequencia no-lock,
               first nota-fiscal of it-nota-fisc no-lock,
                each fat-repre use-index ch-fatrep no-lock
               where fat-repre.cod-estabel   = nota-fiscal.cod-estabel
                 and fat-repre.serie         = nota-fiscal.serie
                 and fat-repre.nr-fatura     = nota-fiscal.nr-fatura 
                 and fat-repre.nome-ab-rep   = nota-fiscal.no-ab-rep
               break by it-nota-fisc.nome-ab-cli
                     by fat-repre.perc-comis
                     by nota-fiscal.cod-estabel
                     by nota-fiscal.serie
                     by nota-fiscal.nr-nota-fis:
    
                if first-of(fat-repre.perc-comis) then
                    assign de-vlr-com-nota = 0
                           c-notas-fiscais = "".
    
                if first-of(nota-fiscal.nr-nota-fis) then
                    assign de-vlr-com-nota = de-vlr-com-nota + nota-fiscal.vl-comis-nota
                           c-notas-fiscais = c-notas-fiscais + 
                                             nota-fiscal.cod-estabel + "-" + 
                                             nota-fiscal.serie       + "-" + 
                                             nota-fiscal.nr-nota-fis + ", ".
    
                assign de-qtde-fat     = de-qtde-fat     + it-nota-fisc.qt-faturada[1]
                       de-vlr-fat-bru  = de-vlr-fat-bru  + it-nota-fisc.vl-merc-ori
                       de-vlr-fat-icms = de-vlr-fat-icms + it-nota-fisc.vl-icms-it
                       de-vlr-fat-liq  = de-vlr-fat-liq  + it-nota-fisc.vl-merc-sicm.
    
                if last-of(fat-repre.perc-comis) then do:
    
                    put ped-venda.no-ab-reppri              " "
                        ped-venda.cod-estabel               " "
                        ped-venda.nr-pedcli                 " "
                        ped-venda.nr-pedido                 " "
                        ped-venda.dt-implant                " "
                        ped-venda.cod-emitente              " "
                        ped-venda.nome-abrev                " "
                        ped-venda.vl-tot-ped                " "
                        ped-venda.vl-liq-ped                " "
                        ped-venda.vl-liq-abe                " "
                        sit-aval                            " " 
                        ped-item.nr-sequencia               " "
                        ped-item.it-codigo                  " "
                        ped-item.qt-pedida                  " "
                        ped-item.qt-atendida                " "
                        ped-item.vl-tot-it                  " "
                        ped-item.vl-liq-it                  " "
                        ped-item.vl-liq-abe                 " " 
                        de-vlr-com-nota                     " "
                        de-qtde-fat                         " "
                        de-vlr-fat-bru                      " "
                        de-vlr-fat-icms                     " "
                        de-vlr-fat-liq                      " "
                        fat-repre.perc-comis                " ".
    
                    put unformatted c-notas-fiscais skip.
    
                end.
                
            end.
    
        end.
    
    end.
    
    output close.
    
    run execute in h-prog(input "notepad.exe", input "c:\temp\exporta_notas.txt").
    
    run pi-finalizar in h-acomp.
    
  6. diegocf

    diegocf Membro Participativo

    Muito obrigado Eduardo,

    Deu certinho.

    Abraços

Compartilhe esta Página