Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: Como Criar Relatórios de Cotações com Dados Agrupados Usando SQL

img: DALL·E 2024-08-09 07.00.00 - A high-quality image showcasing a detailed SQL query being written in a code editor, such as VS Code, on a dark theme background. ... ## Como Criar Relatórios de Cotações com Dados Agrupados Usando SQL Quando trabalhamos com sistemas ERP e precisamos gerar relatórios de cotações que apresentam dados de múltiplos fornecedores, é comum encontrarmos a necessidade de pivotar registros que, originalmente, são apresentados de forma vertical. Isso é especialmente útil quando o objetivo é comparar preços ou condições de diferentes fornecedores para um mesmo produto em uma única linha do relatório. Neste artigo, vamos explorar uma abordagem para transformar registros verticais em colunas, facilitando a impressão de relatórios que consolidam informações de vários fornecedores em uma única linha. Vamos utilizar SQL com técnicas de pivotagem, e ao final, mostraremos como estender essa técnica para um número variável de fornecedores. ### Estrutura do Relatór

Protheus :: Tratamento de Erro :: Simulando Try/Catch


Sabemos que para tratamento de erros/exceções em Advpl devemos trabalhar com as funções ErrorBlock() e/ou SysErrorBlock() e BEGIN SEGUENCE/RECOVER/END como no exemplo abaixo:


Function TrySample1()

//Salvando o bloco de erro do sistema e Atribuindo tratamento personalizado Local bError := ErrorBlock( { |oError| MyError( oError ) } )

BEGIN SEQUENCE

//Forçando um erro para avalia-lo.
__EXCEPTION__->ERROR := "__EXCEPTION__"
RECOVER
//"Se ocorreu erro, após o BREAK, venho para cá"
MsgInfo( "Peguei o Desvio do BREAK" )
END SEQUENCE

MsgInfo( "Continuo após o tratamento de erro" )

//Restaurando bloco de erro do sistema
ErrorBlock( bError )

Return( NIL )

Static Function MyError( oError )
MsgInfo( oError:Description , "Deu Erro" )
BREAK
Return( NIL )

Para Simular o mesmo tratamento acima, usando agora try/catch, que no nosso exemplo estará como TRYEXCEPTION, CATCHEXCEPTION e ENDEXCEPTION, proceda da seguinte forma:

Baixe o arquivo tryexception.ch clicando aqui. Inclua-o no cabeçalho do seu programa utilizando a seguine sintaxe: #include "tryexception.ch"

e, repetindo o exemplo anterior, teremos:


#include "tryexception.ch"

Static Function TrySample2()

Local bError := { |oError| MyError( oError ) }
Local oError

TRYEXCEPTION USING bError
//Forçando um erro para avalia-lo.
__EXCEPTION__->ERROR := "__EXCEPTION__"
CATCHEXCEPTION USING oError
//"Se ocorreu erro, após o BREAK, venho para cá"
MsgInfo( oError:Description , "Peguei o Desvio do BREAK" )
ENDEXCEPTION

MsgInfo( "Continuo após o tratamento de erro" )

Return( NIL )

Function TrySample3()

Local aParamX := {"Serei Alterado",2,3,4}
Local bError := { |oError,aParam| Error( oError , @aParam ) }
Local oMyError

TRY EXCEPTION USING bError PARAMETERS aParamX
__EXCEPTION__->EXCEPTION := "__EXCEPTION__"
CATCH EXCEPTION USING oMyError
MsgInfo( aParamX[1] , "Changed in Error" )
MsgInfo( oMyError:Description )
END EXCEPTION

Return( NIL )

Function TrySample4()

Local cAliasTmp := GetNextAlias()
Local cLike := "APT%"
Local oError
Local oException

BEGINSQL ALIAS cAliasTmp
SELECT
MAX(RC1.RC1_NUMTIT) RC1_NUMTIT
FROM
%table:RC1% RC1
WHERE
RC1.RC1_FILIAL = %exp:xFilial("RC1")% AND
RC1.RC1_NUMTIT LIKE %exp:cLike% AND
RC1.%NotDel%
ENDSQL

TRY EXCEPTION
IF ( cAliasTmp )->( Eof() .or. Empty( RC1_NUMTIT ) )
UserException("No Data")
TRYEXCEPTION
MsgInfo( ( cAliasTmp )->RC1_NUMTIT )
UserException("Data Found")
CATCHEXCEPTION
MsgInfo( oException:Description )
ENDEXCEPTION
EndIF
CATCH EXCEPTION USING oError
MsgInfo( oError:Description )
END TRY

Return( NIL )

Function Error( oError , aParameters )

IF !Empty( aParameters ) .and. ( Len( aParameters ) > 1 )
MsgInfo( AllToChar( aParameters[1] ) , "Call Stack: " + ProcName() ) aParameters[1] := "ProcName: " + ProcName() + " :: ProcLine: " + AllTrim( AllToChar( ProcLine() -1 ) ) + " ::Alterou o Conteúdo desse elemento do Array"
EndIF

Break

Return( NIL )


Se desejar baixar o arquivo de exemplo u_tsttrycatch.prg, clique aqui.

Para baixar todos os arquivos de exemplo usados neste "post" clique aqui.

[]s иαldσ dj



Comentários

  1. Naldo,

    Parabéns pelo Blog!
    Tenho uma situação que gostaria de sua opinião a respeito. Tenho a necessidade de automatizar a rotina de cadastramento de novos colaboradores no Exchange 2007. Sempre que informar um e-mail de novo colaborador e confirmar o cadastro deverá ser executada alguma rotina que efetue o cadastro básico no exchange deste. Quando ocorrer a rescisão deverá ser bloqueado seu a acesso no exchange. Acha que isso pode ser viável? Obrigado. Meu email é a.noel75@gmail.com

    ResponderExcluir
  2. Allan,

    Isso é possivel sim. Usando a combinação do Windows PowerShell e o protheus.

    Para exemplo de como executar o Windows PowerShell através do Protheus consulte:

    http://naldodjblogs.blogspot.com/2010/08/protheus-powershell-e-script-para.html

    Para informações de como Administrar o Exchange 2007 via PowerShell consulte:


    Exchange Server 2007 e Windows PowerShell:

    http://www.andersonpatricio.org/Artigos/Artigos.asp?Artigo=19


    User Administration in Exchange 2007 using Powershell CmdLets:

    http://www.msexchange.org/articles-tutorials/exchange-server-2007/management-administration/user-administration-exchange-2007-powershell-cmdlets.html

    Exchange Management Shell:
    http://technet.microsoft.com/en-us/library/bb123778.aspx

    ResponderExcluir
  3. Parabéns pelo Blog!
    Tambem tenho uma situação que gostaria de sua opinião. Estou consumindo pelo protheus um WS de um programa externo já pronto. No DotNet já tinha implantado o mesmo WS e nele fazia o tratamento dos erros em um bloco TryCatch. No protheus foi gerado o arquivo do WS pelo ADVPL WSDL Client 1.120703, e no programa que chama o metodo do WS quando acontece um erro não retorna nada, a variavel do metodo está totalmente vazia. Tentei colocar a chamada dentro do TRY que li acima, mas na execução do WS ele não gera uma exceção e não envia o erro. Gostaria de saber se já passou por isso?
    Obrigado.
    wendell.gt@pop.com.br

    ResponderExcluir
  4. Bom dia a todos!!!

    Tentei usar o segundo exemplo o que utiliza o #include "tryexception.ch", mas em uma rotina automática, e o que eu acabei descobrindo, que se o erro ocorre na rotina que esta montando o ExecAuto o Exception captura o erro e mostra na tela, porém se o erro ocorre na rotina acionada via ExecAuto, o Exception consegue impedir o INTERNAL SERVER ERROR, porém, retorna a variável padrão lMsErroAuto como true, como se não houvesse um erro.
    Eu acredito que o Exception não consegue capturar o erro ocorrido em outra thread, tem alguma solução para isso?

    Se precisar de um exemplo eu monto um e envio.

    Att

    ResponderExcluir

Postar um comentário

Postagens mais visitadas