Pular para o conteúdo principal

Postagem em destaque

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️ Olá pessoal, Espero que este post encontre todos vocês bem! É com grande entusiasmo que compartilho que estou expandindo meus serviços como Desenvolvedor AdvPL para novos desafios e colaborações. Com mais de duas décadas de experiência sólida, minha jornada profissional tem sido enriquecedora, com a oportunidade de participar de projetos empolgantes ao longo dos anos. Agora, estou ansioso para trazer minha experiência e habilidades para novas equipes e projetos, trabalhando de forma remota. Minha expertise abrange não apenas AdvPL, mas também outras tecnologias-chave, incluindo JS, SQL, Infraestrutura e Otimização de Processos. Acredito que essa combinação de conhecimentos me permite oferecer soluções abrangentes e eficazes para uma variedade de necessidades de desenvolvimento. Acredito que a tecnologia tem o poder de transformar negócios e impulsionar o sucesso, e estou comprometido em ajudar meus clientes a alcançar seu

Protheus :: Advpl :: Otimizando o Filtro de Browse com @

Na dica anterior, Protheus :: Advpl :: Usando cExprFilTop Para Filtrar o Cadastro de Fornecedores de Acordo com Documento de Entrada na mBrowse, Vimos como utilizar o parâmetro cExprFilTop para criar um Filtro Relacional e, na função MATA103NFE usamos FilBrowse() para filtrar a segunda mBrowse. A questão é que FilBrowse() é, de uma certa forma lenta, e, para otimiza-la poderemos utilizar o denominado ‘Fitro “@”’ para que a expressão de filtro seja resolvida diretamente no SGBD.

Sendo assim, a expressão de filtro definida como:

cFiltra       := "F1_FORNECE+F1_LOJA$'" + SA2->( A2_COD+A2_LOJA ) + "'"

será otimizada se for reescrita e prefixada com o símbolo “@”.

cFiltra        := SA2->( "@F1_FORNECE='"+A2_COD+"' AND F1_LOJA='"+A2_LOJA+ "'" )

Na primeira forma, o filtro será avaliado registro a registro tornando-o lento, já na segunda, usamos uma expressão SQL que será resolvida diretamente pelo SGBD deixando o retorno do filtro muito, mas muito,  rápido.

A versão completa do Código com a otimização do filtro ficaria assim:

#INCLUDE "PROTHEUS.CH"
#IFDEF __TRYEXCEPTION__
    #INCLUDE "TRYEXCEPTION.CH"
#ENDIF   

/*/
    Function:    U_MATA103F
    Autor:       Marinaldo de Jesus
    Data:        18/01/2011
    Descricao:   Cadastro de Fornecedores/Doc.Entrada
    Sintaxe:     U_MATA103F
/*/
User Function MATA103F()

    Local aArea        := GetArea()
    Local aSA2Area     := SA2->( GetArea() )
    Local aSF1Area     := SF1->( GetArea() )
    Local cExprFilTop  := ""

    BEGIN SEQUENCE

   Private aRotina     := {;
                             { "Pesquisar" , "PesqBrw", 0 , 01 } ,;
                             { "Doc. de Entrada","StaticCall(U_MATA103F,MATA103NFE,'SA2',SA2->(Recno()),2)",0,02};
                          }

        Private aTela        := {}
        Private aGets        := {}

        Private cCadastro    := OemToAnsi( "Cadastro de Fornecedores vs Contratos" )
        Private bFiltraBrw   := { || .F. }

        cExprFilTop    := "A2_COD+A2_LOJA "
        cExprFilTop    += "IN "
        cExprFilTop    += "("
        cExprFilTop    += "SELECT DISTINCT "
        cExprFilTop    +=         "SA2.A2_COD+SA2.A2_LOJA "
        cExprFilTop    += "FROM "
        cExprFilTop    +=         RetSqlName( "SA2" ) + " SA2, "
        cExprFilTop    +=        RetSqlName( "SF1" ) + " SF1 "
        cExprFilTop    += "WHERE "
        cExprFilTop    +=         "SA2.D_E_L_E_T_<>'*' "
        cExprFilTop    +=    " AND "
        cExprFilTop    +=         "SF1.D_E_L_E_T_<>'*' "
        cExprFilTop    +=    " AND "
        cExprFilTop    +=         "SA2.A2_FILIAL='" + xFilial( "SA2" ) + "'"
        cExprFilTop    +=    " AND "
        cExprFilTop    +=         "SF1.F1_FILIAL='" + xFilial( "SF1" ) + "'"
        cExprFilTop    +=    " AND "
        cExprFilTop    +=         "SA2.A2_COD=SF1.F1_FORNECE "
        cExprFilTop    +=    " AND "
        cExprFilTop    +=         "SA2.A2_LOJA=SF1.F1_LOJA "
        cExprFilTop    += ")"

        MBrowse(6,1,22,75,"SA2",NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,cExprFilTop)

    END SEQUENCE

    RestArea( aSF1Area )
    RestArea( aSA2Area )
    RestArea( aArea )

Return( NIL )

/*/
    Function:    MATA103NFE
    Autor:       Marinaldo de Jesus
    Data:        18/01/2011
    Descricao:   Chamada a Rotina de Nota Fiscal de Entrada
    Sintaxe:     StaticCall(U_MATA103F,MATA103NFE,cAlias,nReg,nOpc)
/*/
Static Function MATA103NFE( cAlias , nReg , nOpc )

    Local aArea         := GetArea()
    Local aIndex        := {}
    Local aSF1Area      := SF1->( GetArea() )
    Local aModuloReSet  := SetModulo( "SIGACOM" , "COM" )
    Local bSvFilBrw     := bFiltraBrw
    Local cFiltra       := ""
    Local cSF1Alias     := "SF1"
    Local cSF1KeySeek

    Local nSF1Reg
    Local nSF1Order     := RetOrder( cSF1Alias , "F1_FILIAL+F1_FORNECE+F1_LOJA+F1_DOC" )

    Local uRet

    Private aTela       := {}
    Private aGets       := {}

    #IFDEF __TRYEXCEPTION__
        TRYEXCEPTION
    #ENDIF   

        ( cAlias )->( MsGoto( nReg ) )

        cFiltra        := SA2->( "@F1_FORNECE='"+A2_COD+"' AND F1_LOJA='"+A2_LOJA+ "'" )

        bFiltraBrw    := { || FilBrowse( "SF1" , @aIndex , @cFiltra ) }

        SF1->( dbSetOrder( nSF1Order ) )
        SF1->( Eval( bFiltraBrw ) )       

        uRet := __Execute( "MATA103()" , "xxxxxxxxxxxxxxxxxxxx" , "MATA103" , AllTrim(Str(nModulo)) , "" , 1 , .T. )

        SF1->( EndFilBrw( "SF1" , aIndex ) )

    #IFDEF __TRYEXCEPTION__

        CATCHEXCEPTION USING oException
            IF ( ValType( oException ) == "O" )
                Help( "" , 1 , ProcName() , NIL , OemToAnsi( oException:Description ) , 1 , 0 )
                ConOut( CaptureError() )
            EndIF
        ENDEXCEPTION

    #ENDIF

    bFiltraBrw    := bSvFilBrw
    SA2->( Eval( bFiltraBrw ) )

    ReSetModulo( aModuloReSet )

    RestArea( aSF1Area )
    RestArea( aArea )

Return( uRet )

Static Function __Dummy( lRecursa )
    #IFDEF __TRYEXCEPTION__
        Local oException
        TRYEXCEPTION
    #ENDIF
            DEFAULT lRecursa := .F.
            IF !( lRecursa )
                BREAK
            EndIF
            MATA103NFE()
            lRecursa := __Dummy( .F. )
    #IFDEF __TRYEXCEPTION__
        CATCHEXCEPTION USING oException
        ENDEXCEPTION
    #ENDIF  
Return( lRecursa )

Procure, sempre que possível utilizar o filtro “@” em suas consultas da mBrowse ou na chamada a Funções de Filtro, como por exemplo, a FilBrowse().

Para baixar , o novo e otimizado exemplo, clique aqui

[]s

иαldσ dj

Comentários

  1. Fala naldo, bão cara?

    Esse caso da imagem em uma tabela SXB de consultas padrao se refere ao mesmo caso.
    https://lh4.googleusercontent.com/-6Id7qI8cC1k/Toxg9OSTn9I/AAAAAAAAAjY/nc28dqPINkE/s800/filtro%252520na%252520consulta%252520padrao.jpg

    Isso caracteriza filtro de otimizacao via SQL?

    Vlw

    ResponderExcluir
  2. Isso mesmo Sérgio... Os Filtros das Consultas Padrões (SXB) também podem ser beneficiadas com o "Filtro @" de forma a "otimizar" o processo de montagem da consulta. O espaço aqui é pequeno para explanar sobre o assunto que merece um "post".

    []s

    иαldσ dj

    ResponderExcluir
  3. Naldo, boa tarde,

    Cara vc já usou o essa rotina __Execute no Protheus11? Aqui da um erro na lib muito bizarro...

    Eu criei uma outra rotina chamando somente essa função e estourou o mesmo erro, sabe se existe alguma coisa a ser feita antes de chamar esta função?

    Segue erro:

    THREAD ERROR (rodrigo, STO-IPD-N10) 18/10/2012 14:52:59
    invalid property OMSGBAR on BEGINFLATMODE(APLIB000.PRW) 27/02/2012 16:36:07 line : 1347

    [TOTVS build: 7.00.111010P-20120120]
    Called from __EXECUTE(APLIB090.PRW) 10/07/2012 17:12:06 line : 214
    Called from U_MATA103F(U_MATA103F.PRG) 18/10/2012 14:51:11 line : 33
    Called from SIGAIXB(APLIB190.PRW) 14/12/2011 18:31:10 line : 226
    Called from __EXECUTE(APLIB090.PRW) 10/07/2012 17:12:06 line : 487
    Called from FWPREEXECUTE(FWPREEXECUTE.PRW) 17/08/2011 18:06:36 line : 65
    Called from {|| FWPreExecute('Fornecedor / Doc. Entrada', 'MATA103F()', 3, '02', 'xxxxxxxxxx') } line : 247
    Called from ::TWINDOW:ACTIVATE
    Called from MSAPP:ACTIVATE(FWAPP.PRW) 17/07/2012 16:33:17 line : 519
    Called from SIGAADV(APLIB000.PRW) 27/02/2012 16:36:07 line : 54

    ResponderExcluir
  4. Naldo, boa tarde,

    Cara vc já usou o essa rotina __Execute no Protheus11? Aqui da um erro na lib muito bizarro...

    Eu criei uma outra rotina chamando somente essa função e estourou o mesmo erro, sabe se existe alguma coisa a ser feita antes de chamar esta função?

    Segue erro:

    THREAD ERROR (rodrigo, STO-IPD-N10) 18/10/2012 14:52:59
    invalid property OMSGBAR on BEGINFLATMODE(APLIB000.PRW) 27/02/2012 16:36:07 line : 1347

    [TOTVS build: 7.00.111010P-20120120]
    Called from __EXECUTE(APLIB090.PRW) 10/07/2012 17:12:06 line : 214
    Called from U_MATA103F(U_MATA103F.PRG) 18/10/2012 14:51:11 line : 33
    Called from SIGAIXB(APLIB190.PRW) 14/12/2011 18:31:10 line : 226
    Called from __EXECUTE(APLIB090.PRW) 10/07/2012 17:12:06 line : 487
    Called from FWPREEXECUTE(FWPREEXECUTE.PRW) 17/08/2011 18:06:36 line : 65
    Called from {|| FWPreExecute('Fornecedor / Doc. Entrada', 'MATA103F()', 3, '02', 'xxxxxxxxxx') } line : 247
    Called from ::TWINDOW:ACTIVATE
    Called from MSAPP:ACTIVATE(FWAPP.PRW) 17/07/2012 16:33:17 line : 519
    Called from SIGAADV(APLIB000.PRW) 27/02/2012 16:36:07 line : 54

    ResponderExcluir
    Respostas
    1. Vou ser se consigo reproduzir o erro e publico a solução.

      Excluir
    2. Bom Dia.

      Fiz uma customização e me ocorreu o mesmo erro mostrado no comentario acima do RSGomes.

      Alguem sabe como resolver?

      Desde já agradeço a ajuda.

      Jefferson Moreira

      Excluir
    3. Bom Dia.

      Fiz uma customização e me ocorreu o mesmo erro mostrado no comentario acima do RSGomes.

      Alguem sabe como resolver?

      Desde já agradeço a ajuda.

      Jefferson Moreira

      Excluir
  5. Boa tarde...

    Consegui rodar a rotina aqui!!!!! O bizarro foi como... Eu simplesmente mudei o tema do Protheus 11 do Standard para o Clássico...

    Agora o que eu não consegui foi utilizar o "@" para filtra o SF1. Na verdade o SF1 até é filtrado (verifiquei debugando a rotina antes da chamada da função MATA103). Mas quando o MATA103 é executado os registro não aparecem filtrados.

    De qualquer forma não é um problema já que a performance do filtro sem o "@" está muito bom aqui.

    P.S.: Detalhe: Quando o tema estava no Standard o filtro sem o "@" ficou extremamente lento... Vai entender...

    Abraços

    ResponderExcluir
  6. Boa tarde Naldo,

    Sou novo por aqui(BlackTdn), mas um curioso na programação em ADVPL há mais de 5 anos.
    Estou desenvolvendo um software de TimeSheet pra executar todo em Prepare Environment. Estou na versão 10 do Protheus e gostaria de saber se já conseguiu criar uma tela modelo 2 em tela cheia, por exemplo chamada via Mbrowse.

    Detalhe: Estou executando via Prepare Environment, comando __Execute

    Agradeço a atenção.

    Bruno Abrigo

    ResponderExcluir
    Respostas
    1. Bruno,

      Isso que você está querendo fazer é bem simples, observe os parâmetros da Modelo2.

      Modelo2(cTitulo,aC,aR,aCGD,nOpcx,cLineOk,cAllOk,aGetsGD,bF4,cIniCpos,nMax,aCordW,lDelGetD,lMaximized, aButtons)


      Dentre eles aCordW e lMaximized irão resolver o seu problema.

      aCordW -> espera as coordenadas da janela que poderão ser obtidas com MsAdvSize()
      lMaximized -> Com .T. fará com que o Dialog seja montado de forma Maximizaa.

      No seu caso aCordW ficaria como

      aCordW := MsAdvSize( NIL , .F. )
      e
      lMaximized := .T.

      []s
      Naldo

      Excluir
    2. "Bruno Abrigo
      2:36 PM (9 minutes ago)

      to me
      Pow Naldo!
      Que legal falar com vc, tú é real mermo! Rs

      Cara veja como estou preenchendo os parâmetros:

      aR:={}
      aCGD := {44,5,118,315}
      aCordW := MsAdvSize( NIL , .F. )
      lRetMod2:=Modelo2(cTitulo,aC,aR,aCGD,nOpcx,cLinhaOk,cTudoOk,aGetSD, ,, , aCordW ,,.T.)//GetmBrowse())

      Ainda não consegui abrir em tela inteira. O que esta falantando?

      Vlww!"

      Resposta:

      Bruno,

      Falha minha. as Coordenadas de aCordW não são equivalentes as retornadas pela MsAdvSize() então o seguinte ajuste se faz necessário:

      aAdvSize := MsAdvSize( NIL ,.F. )
      aCordW := Array(Len(aAdvSize))

      aCordW[1] := aAdvSize[7]
      aCordW[2] := 0
      aCordW[3] := aAdvSize[6]
      aCordW[4] := aAdvSize[5]

      []s
      Naldo

      Excluir
    3. Ou, para manter aCordW com o Tamanho Esprado:

      aAdvSize := MsAdvSize( NIL ,.F. )
      aCordW := Array(4)

      aCordW[1] := aAdvSize[7]
      aCordW[2] := 0
      aCordW[3] := aAdvSize[6]
      aCordW[4] := aAdvSize[5]

      []s
      Naldo

      Read more: http://www.blacktdn.com.br/2011/09/protheus-advpl-otimizando-o-filtro-de.html#ixzz2VMhoq9fn

      Excluir
    4. Bruno Abrigo
      3:06 PM (12 minutes ago)

      to me
      Valeu naldo, fiz alguns acertos pra chegar no meu objetivo mas era essa ajuda que eu precisava.

      Parabéns!

      Bruno

      Excluir

Postar um comentário

Postagens mais visitadas deste blog

BlackTDN :: RLeg ~ Desvendando a Função ParamBox

Para quem precisar desenvolver uma interface de entrada de dados, coisa rápida, e não quer ter aquele trabalhão danado que todos já sabemos, o Protheus tem uma função que ajuda muito, é uma interface semelhante a função Pergunte, porém com muito mais opção de objeto de entrada de dados, alias até colocar o scrollbox desta interface com todos os objetos em outra MsDialog ou Wizard é simples. Vejam o exemplo abaixo, boa sorte! Rleg. //---------------------------------------------------------- // Função exemplo utilizando a função ParamBox() //---------------------------------------------------------- User Function xParamBox() Local aRet := {} Local aParamBox := {} Local aCombo := {"Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"} Local i := 0 Private cCadastro := "xParambox" // ---------------

BlackTDN :: Customizando a interface de Login no Protheus e by You

A publicação “ BlackTDN :: By You e sua nova tela de login ”  de nosso amigo OBona deu o que falar e, em função disso, esse que a muito não vos escreve resolveu criar uma versão onde será possível personalizar, “por completo”, a tela de login no Protheus/by You. Considerando que OBona já havia “mapeado, identificado e customizado” as imagens peguei-as emprestadas para o exemplo que se segue: O primeiro passo para a customização “total” da interface de login do Protheus/by You será implementar o “Ponto de Entrada” ChgPrDir (Diretório de impressão) . Usaremos esse PE juntamente como programa U_FindMsObject.prg (apresentado pela primeira vez em: Protheus :: ADVPL : The Container : Presents Pandora's box ). Diferente do exemplo proposto por OBona, que substitui, durante o processo de compilação, as imagens padrões do sistema (excluindo-as) por imagens customizadas (com o mesmo nome) este novo exemplo mantém, no RPO, as imagens padrões adicionando novas imagens customizadas que serã

Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login

Ferne$ perguntou: "...é possível abrir alguma rotina do sistema sem solicitar login ao usuário, como por exemplo a rotina MATA010..." Sim Ferne$, é possível sim. Abaixo um Exemplo para a Chamada à função MATA010 sem a necessidade de Login no sistema. #INCLUDE "PROTHEUS.CH" #INCLUDE "TBICONN.CH" /*/ Funcao: MATA010Ex Data: 30/04/2011 Autor: Marinaldo de Jesus Descricao: Executar a Funcao MATA010 diretamente sem a necessidade de LOGIN no Protheus Sintaxe: 1 ) U_MATA010Ex ( Chamada diretamente na Tela de Entrada do Sistema ) ; ou 2 ) totvsclient.exe -q -p=u_MATA010Ex -a=01;01 -c=rnp_local -e=rnp -m -l ( Chamada Via Linha de Comando ) /*/ User Function MATA010Ex( cEmpFil ) Local aEmpFil Local bWindowInit := { || __Execute( "MATA010()" , "xxxxxxxxxxxxxxxxxxxx" , "MATA010" , "SIGAFAT" , "SIGAFAT", 1 , .T. ) } Local cEmp Local cFil Local cMod Local cModName := "SIGAFAT" DEFA