Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring

_Créditos das imagens: ChatGPT_ ### LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring Resolver o problema do [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/description/) é um exercício clássico de programação, que desafia desenvolvedores a encontrar a maior substring palindrômica dentro de uma string. Recentemente, exploramos soluções tanto em Harbour quanto em TLPP (Total Language Protheus Programming). Neste artigo, comparamos as implementações nessas duas linguagens, destacando suas semelhanças, diferenças e funcionalidades específicas. #### Implementações em Harbour ##### Versão 5.1 Essa solução utiliza a técnica de expansão a partir do centro do palíndromo. Cada caractere ou par de caracteres consecutivos é considerado um possível "centro". O algoritmo expande em ambas as direções enquanto os caracteres forem iguais, retornando o maior palíndromo encontrado. ##### Versão 5....

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