1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

  2. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Ajuda]Lógica em relatório NF.

Discussão em 'Progress 4GL' iniciado por WolffTI, Fevereiro 6, 2012.

  1. WolffTI

    WolffTI Sem Pontuação

    E ae pessoal, tudo bom?
    Antes de mais nada gostaria de agradecer pois tenho aprendido bastante aqui no fórum. :D

    Tenho encontrado dificuldade para resolver uma questão de lógica em um programa que estou criando e gera relatório de Notas Fiscais.
    De forma resumida o programa recebe as entradas do usuário tais como data, numero da nota, ou então local que emitiu, e com esses dados ele efetua a busca e retorna os dados da(s) nota(s) fiscal(is) em questão.
    Foi-me pedido para acrescentar a este relatório o sub-total de peças por NOTA, o sub-total de valor por NOTA, o total de peças no RELATÓRIO e o total de volar no RELATÓRIO.
    A parte do total ficou fácil, foi só dar o display fora do FOR EACH.
    A questão que está travando pra mim, seriam os sub-totais, tanto de valor quanto de peças por NOTA.
    A pessoa que me passou está tarefa quer que eu de o display não linha a linha da nota, mas por nota, então o programa me traz algo mais ou menos assim:

    0000017196 1 Catalisador x 200 RS1.000,00
    0000017196 2 Catalisador y 100 R$1.000,00
    0000017196 3 Catalisador z 100 R$500,00

    Na lógica que eu havia criado o display vinha assim:

    sub-qtdade sub-valor
    0000017196 1 Catalisador x 200 RS1.000,00 200 R$1.000,00
    0000017196 2 Catalisador y 100 R$1.000,00 300 R$2.000,00
    0000017196 3 Catalisador z 100 R$500,00 400 R$2.500,00

    Mas a idéia de display precisa ser assim:

    0000017196 1 Catalisador x 200 RS1.000,00
    0000017196 2 Catalisador y 100 R$1.000,00
    0000017196 3 Catalisador z 100 R$500,00
    sub-qtdade: 400 sub-valor:R$2.500,00


    Eu pensei que se eu tivesse uma função next dentro do progress eu conseguiria resolver isso de maneira fácil, pois eu compararia a nota atual do for each com a próxima nota e caso fossem diferentes eu daria o display dessa nf atual já com os sub totais, e caso contrario daria o display sem os sub-totais. Segue o código já criado, se tiverem alguma idéia de como em ajudar, pois como não conheço todas as funções e suas utilidades, acabo ficando limitado.

    Código:
    /*
    Sistema..: Teste
    Programa.: relatorionf.p
    Autor....: Rodrigo Araujo
    Data.....: xx/xx/xxxx
    Descricao: Relatório de NF´s
    */
    
    {mfdtitle.i 2.0}
    
    DEF VAR v-typ-doc AS CHAR FORMAT "X(2)"         LABEL "Tipo Doc"     no-undo.
    DEF VAR site      like si_site                                       no-undo.
    DEF VAR site1     like si_site                                       no-undo.
    DEF VAR nf        AS CHAR FORMAT "X(15)"        LABEL "NF"           no-undo.
    DEF VAR nf1       AS CHAR FORMAT "X(15)"        LABEL "->"           no-undo.
    DEF VAR date-em   AS DATE FORMAT "99/99/9999"   LABEL "Data inicial" no-undo.
    DEF VAR date-em1  AS DATE FORMAT "99/99/9999"   LABEL "->"           no-undo.
    DEF VAR total_qty like znd_qty_item                                  no-undo.
    DEF VAR total_pri like znd_ext_price                                 no-undo.
    DEF VAR sub_qty   like znd_qty_item                                  no-undo.
    DEF VAR sub_pri   like znd_ext_price                                 no-undo.
    DEF VAR teste     like zn_nbr                                        no-undo.
    
    ASSIGN v-typ-doc = "NF".
    
    form v-typ-doc colon 13
         site      colon 13
         site1     colon 40
         nf        colon 13
         nf1       colon 40
         date-em   colon 13
         date-em1  colon 40
         with width 80 side-labels frame a.
         setFrameLabels(frame a:handle).
    
    form
       zn_addr       colon 1
       zn_inv_date   colon 13
       znd_part      colon 23
       zn_nbr        colon 43
       znd_line      colon 57
       znd_desc      colon 62
       znd_um        colon 112
       znd_qty_item  colon 116
       znd_ext_price colon 133 skip
       sub_qty       colon 1  label "Itens por nota"
       sub_pri       colon 17 label "Valor nota"
       total_qty     colon 35 label "Qtdade total"
       total_pri     colon 52 label "Valor total"
       with width 250 frame b.
       setFrameLabels(frame b:handle).
    
    REPEAT:
    
        assign teste     = "".
       assign sub_qty   =  0.
       assign sub_pri   =  0.
       assign total_qty =  0.
       assign total_pri =  0.
    
       display
          v-typ-doc
          site
          site1
          nf
          nf1
          date-em
          date-em1
          with frame a.
    
       if site1    = hi_char  then assign site1    = "".
       if nf1      = hi_char  then assign nf1      = "".
       if date-em  = low_date then assign date-em  =  ?.
       if date-em1 = today    then assign date-em1 =  ?.
    
       update site
          help "Entre com o local emitente."
          validate ( can-find( first si_mstr where si_domain = global_domain and
                                                   si_site   = input site         ),
                 "ERRO: Entre com um local válido para a busca. Com dois digitos.")
              site1
          help "Entre com o local emitente."
          validate ( can-find( first si_mstr where si_domain = global_domain and
                                                   si_site   = input site1        ),
                 "ERRO: Entre com um local válido para a busca. Com dois digitos.")
              nf
          help "Entre com a nota fiscal."
          validate (  can-find( first zn_mstr where zn_domain = global_domain and
                                                    zn_nbr    = input nf          ),
                 "ERRO: Entre com uma nf válida para a busca.")
              nf1
          help "Entre com a nota fiscal."
          validate (  can-find( first zn_mstr where zn_domain = global_domain and
                                                    zn_nbr    = input nf1         ),
                 "ERRO: Entre com uma nf válida para a busca.")
              date-em
          help "Entre com a data para busca."
              date-em1
          help "Entre com a data para busca."
          validate ( input date-em1 >= input date-em ,
                 "ERRO: Entra com uma hora válida.")
          with frame a.
    
       {gpselout.i &printType                = "printer"
                   &printWidth               = 80
                   &pagedFlag                = " "
                   &stream                   = " "
                   &appendToFile             = " "
                   &streamedOutputToTerminal = " "
                   &withBatchOption          = "yes"
                   &displayStatementType     = 1
                   &withCancelMessage        = "yes"
                   &pageBottomMargin         = 6
                   &withEmail                = "yes"
                   &withWinprint             = "yes"
                   &defineVariables          = "yes"}
    
       {mfphead.i}
    
       if site1    = "" then assign site1    =  hi_char.
       if nf1      = "" then assign nf1      =  hi_char.
       if date-em  =  ? then assign date-em  = low_date.
       if date-em1 =  ? then assign date-em1 =    today.
    
       for each zn_mstr no-lock
          where
          zn_domain    = global_domain                     and
         (zn_addr     >= site     and zn_addr    <= site1) and
          zn_doc_type  = v-typ-doc                         and
         (zn_nbr      >= nf      and zn_nbr      <= nf1)   and
         (zn_inv_date >= date-em and zn_inv_date <= date-em1) ,
    
           each znd_det
          where
          znd_domain   = zn_domain    and
          znd_addr     = zn_addr      and
          znd_doc_type = zn_doc_type  and
          znd_nbr      = zn_nbr       and
          znd_ret_nbr  = zn_ret_nbr   and
          znd_line     = znd_line no-lock:
    
        /* Obtendo sub-totais por nota, qtdade e valor */
          if teste <> zn_nbr then do:
             assign sub_qty = 0.
             assign sub_pri = 0.
             if znd_qty_item < 0 then
                sub_qty = sub_qty - znd_qty_item.
             else
                sub_qty = sub_qty + znd_qty_item.
             if znd_ext_price < 0 then
                sub_pri = sub_pri - znd_ext_price.
             else
                sub_pri = sub_pri + znd_ext_price.
    
             assign teste = zn_nbr.
          end. /* if */
    
          else do:
    
             if znd_qty_item < 0 then
                sub_qty = sub_qty - znd_qty_item.
             else
                sub_qty = sub_qty + znd_qty_item.
             if znd_ext_price < 0 then
                sub_pri = sub_pri - znd_ext_price.
             else
                sub_pri = sub_pri + znd_ext_price.
    
          end. /* else */
        /* Obtendo total geral por qtdade e valor */
    
          if znd_qty_item < 0 then
             total_qty = total_qty - znd_qty_item.
          else
             total_qty = total_qty + znd_qty_item.
          if znd_ext_price < 0 then
             total_pri = total_pri - znd_ext_price.
          else
             total_pri = total_pri + znd_ext_price.
        
          if teste <> next (zn_mstr.zn_nbr)then
    
             display
                zn_addr
                zn_inv_date
                znd_part
                zn_nbr
                znd_line
                znd_desc
                znd_um
                znd_qty_item
                znd_ext_price
                sub_qty
                sub_pri
                with frame b.
    
          else
    
              display
                zn_addr
                zn_inv_date
                znd_part
                zn_nbr
                znd_line
                znd_desc
                znd_um
                znd_qty_item
                znd_ext_price
                with frame b.
    
       end. /* for each */
    
       display total_qty
               total_pri
               with frame b.
    
       if not available zn_mstr then
          display "Sem registros encontrados".
    
      {mfrtrail.i}
    
    end. /* repeat */
    
    
    

    Obrigado.
  2. eriutoncharles

    eriutoncharles Membro Participativo

    Meu caro, boa tarde!


    Você precisa pesquisar algo sobre ACCUM.
    Então deixa eu tentar te ajudar.

    Dentro do FOR EACH vc pode acumular valores de acordo com a ordem do For each.
    por exemplo.
    Código:
    FOR EACH ttNota BREAK BY ttNota.NUm_Doc.
         /* Aqui acumulando os subtotais.. devido ter declarado a ordem la no BREAK BY*/
            ACCUM ttNota.Total (TOTAL BY ttNota.NUm_Doc). 
    
            /* ACumulo do Total Geral */
             ACCUM   ttNota.Total (TOTAL). 
    
           IF LAST-OF(ttNota.Num_Doc) THEN DO.
                    /* MOstrando o SubTotal por Num_Doc definido no Break by */
                DISPLAY ACCUM TOTAL BY ttNota.NUm_Doc ttNota.Total.    
           END.
           IF LAST(ttNota.Num_Doc) THEN DO.
                     /* Mostrando o Total Geral */
                DISPLAY ACCUM TOTAL ttNota.Total.
          END.
    
    END. /*For Each*/
    
    Entao o ACCUM pra vc usar, tem que ser na Ordem do BREAK BY, e entao vc usa o Subtotal no LAst-OF(tabela.campo) e mostra o ACCUM TOTAL BY tabela.campo tabela.campodototal .(ACCUM TOTAL BY ttNota.Num_Doc ttNota.Total) por ex.
    Veja se lhe ajuda..
    qq coisa add ai
    eriutoncharles no skype ou msn que estes coisinhas mais simples eu posso te ajudar
  3. WolffTI

    WolffTI Sem Pontuação

    Amigo,

    Funcionou.
    Muito obrigado.

Compartilhe esta Página