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 :: Diretivas do Pré-Processador, Constantes Simbólicas e outros Bichos

Pré-Processador:

O protheus, bem como todos os compiladores derivados do CA-Clipper, possuem um recurso chamado de "Pré-Processador" (Outros compiladores também possuem como C, C++, Assembler, etc).

É o "pré-processador" quem prepara o código fonte para a compilação. Ele tem a finalidade de efetuar busca e substituição das "diretivas de pré-processamento" de forma a evitar erros durante a compilação e ou execução do código.

Podemos elencar os seguintes recursos de "pré-processamento":

  • - Constantes Simbólicas
  • - Arquivos include
  • - Macros do compilador
  • - Compilação condicional
  • - Comandos Definidos pelo Usuário

Constantes Simbólicas:

As constantes simbólicas são definidas com a diretiva do "pré-processador" #DEFINE. O "pré-processador" procura todas as constantes simbólicas definidas por essa diretiva substituindo-as pelo seu real valor.
Por exemplo:


#DEFINE FO_READ         0 //Open for reading (default)
#DEFINE FO_WRITE        1 //Open for writing
#DEFINE FO_READWRITE    2 //Open for reading or writing
#DEFINE FO_SHARED      64 //Allow others to read or write

nHandle := FOPEN("Temp.txt", FO_READWRITE + FO_SHARED)
IF FERROR() != 0
  ConOut( "Cannot open file, DOS error " , FERROR() )
ENDIF


O "pré-processador" irá traduzir para


[linha em branco]
[linha em branco]
[linha em branco]
[linha em branco]

nHandle := FOPEN("Temp.txt", 2 + 64 )
IF FERROR() != 0
  ConOut( "Cannot open file, DOS error " , FERROR() )
ENDIF


O "pré-processador", no arquivo de saída, remove a diretiva #DEFINE deixando linhas em branco para preservar a numeração das linhas e substitui os nomes das constantes pelos seus valores.

A diretiva #DEFINE, para o pré-processador, é sensivel ao contexto. Então devemos usá-las da forma que foram declaradas, se tentarmos usa-la como:

nHandle := FOPEN("Temp.txt", fo_readwrite + fo_shared)

O "pré-processador não irá subsituir as constantes pelos seus reais valores e obteremos um erro em tempo de execução. O sistema tentará interpretar fo_readwrite e fo_shared como variáveis e gerará uma exceção.

Então, vale salientar, que a tradução de #DEFINE feita pelo "pré-processador" é sensivel a letras maiúsculas e minúsculas.

Arquivos Include:

A grande maioria das diretivas de "pré-processamento" do protheus são definidas em arquivos de cabeçalho, que normalmente possuem a extensão .CH (Clipper Header) Para fazer uso delas faz-se necessário usar a diretiva #INCLUDE. Então, para que o pré-processador possa buscar e substituir o valor real para a constante FO_READWRITE devemos incluir o arquivo de cabeçalho "FILEIO.CH" no inicio do programa como:

#INCLUDE "FILEIO.CH"

e, durante o "pré-processamento" todas as referencias a FO_READWRITE serão substituidas pelo seu valor real que no arquivo "FILEIO.CH" está definido como 2. Os arquivos de cabeçalho são muito usados para padronizar os valores das constantes simbólicas, macros do compilador e comandos definidos pelo usuário.

Macros do Compilador:

As "macros do compilador" poderão ser usadas para simular o uso de "funções in line" no protheus. Use-as quando necessitar repetir uma pequena sequencia de codificação várias vezes mas que tornaria o processo custoso se uma função real fosse utilizada. Por Exemplo: Para que criar a função Max( nVal1 , nVal2 ) ou Min( nVal1 , nVal2 ) se podemos criar uma macro para esse fim:

Ex.:


#DEFINE Max( a , b ) IIF( a > b , a , b )
#DEFINE Min( a , b ) IIF( a < b , a , b )
E usa-las como:

nMax := Max( 1 , 2 )
nMin := Min( 1 , 2 )
que o "pré-processador" substituirá por:

nMax := IIF( 1 > 2 , 1 , 2 )
nMin := IIF( 1 < 2 , 1 , 2 )
A vantagem de usar as macros do compilador é que elas não precisam ser empilhadas, não precisa passar pelo complexo processo que as funções passam. A desvantagem de usar as macros do compilador para simular "funções inline" no protheus, é que a diretiva #DEFINE é sensível a maiúsculas e minúsculas. Então, para evitarmos erro durante a execução, teriamos que prever todas as possibilidades para a macro como em:

#DEFINE Max( a , b ) IIF( a > b , a , b )
#DEFINE MAx( a , b ) IIF( a > b , a , b )
#DEFINE MAX( a , b ) IIF( a > b , a , b )
#DEFINE mAX( a , b ) IIF( a > b , a , b )
#DEFINE maX( a , b ) IIF( a > b , a , b )
#DEFINE max( a , b ) IIF( a > b , a , b )
#DEFINE MaX( a , b ) IIF( a > b , a , b )
#DEFINE mAx( a , b ) IIF( a > b , a , b )
...

#DEFINE Min( a , b ) IIF( a > b , a , b )
#DEFINE MIn( a , b ) IIF( a > b , a , b )
#DEFINE MIN( a , b ) IIF( a > b , a , b )
#DEFINE mIN( a , b ) IIF( a > b , a , b )
#DEFINE miN( a , b ) IIF( a > b , a , b )
#DEFINE min( a , b ) IIF( a > b , a , b )
#DEFINE MiN( a , b ) IIF( a > b , a , b )
#DEFINE mIn( a , b ) IIF( a > b , a , b )
...
Isso seria muito trabalhoso, então, podemos abrir mão de outra diretiva do pré-processador para simular funções "in line", a diretiva #TRANSLATE ou #XTRANSLATE como:

#TRANSLATE Max( <a> , <b> ) => IIF( <a> \> <b> , <a> , <b> )
#XTRANSLATE Min( <a> , <b> ) => IIF( <a> \< <b> , <a> , <b> )
E poderemos chama-la de qualquer forma, ex:

nMax := Max( 1 , 2 )
nMax := MAx( 4 , 3 )
nMax := MAX( 10 , 20 )
nMax := mAX( 45 , 3 )
ou

nMin := Min( 1 , 2 )
nMin := MIn( 15 , 12 )
nMin := MIN( 1970 , 10 )
nMin := mIN( 3 , 1 )
que serão traduzidas corretamente pelo pré-processador para

nMax := IIF( 1 > 2 , 1 , 2 )
nMax := IIF( 4 > 3 , 4 , 3 )
nMax := IIF( 10 > 20 , 10 , 20 )
nMax := IIF( 45 > 3 , 45 , 3 )

ou 

nMin := IIF( 1 < 2  , 1 , 2)
nMin := IIF( 15 < 12 , 15 , 12 )
nMin := IIF( 1970 < 10 , 1970 , 10 )
nMin := IIF( 3 < 1 , 3 , 1 )


Compilação condicional:

O pré-processador trata a compilação condicional incluindo ou excluindo partes do código para a real compilação de acordo com uma condição. As diretivas para a compilação condicional são:

#IFDEF - Verifica se um símbolo está definido
#IFNDEF - Verifica se um símbolo não está definido
#ELSE - Incluir algo se um #IFDEF ou #IFNDEF "falhar"
#ENDIF - Indica o final da codificação controlada pelas diretivas #IFDEF, #IFNDEF e #ELSE.
Podemos definir um símbolo sem abrituir um valor a ele. Podemos escrever #DEFINE DEBUG e testá-lo em seguida:

#IFDEF DEBUG
 ConOut( "Estou em processo de depuração" )
#ENDIF
Podemos definir simbolos, também, à partir da IDE do Protheus, nos parâmtros para compilação passando-os da seguinte forma D/DEBUG cria o símbolo DEBUG que poderá ser verficado da mesma forma (um exemplo poderá ser obtido em: "Protheus IDE:: Compilação Condicional", ou ainda em "Sudoku :: Tutorial"). Existem vários simbolos condicionais definidos no protheus, o principal e mais usado é o TOP, para verificar se o RPO a ser utilizado é TOPCONNECT ou não.

#IFDEF TOP
 cQuery := "SELECT * FROM " + RetSqlName( "SA1" )
#ENDIF

Essa parte do código só será incluida na versão definitiva do código a ser compilado se o símbolo TOP estiver definido.

Vou deixar os comandos definidos pelo usuário para os próximos "posts".

[]s
иαldσ dj

Baseado no original de Rick Spence (Spence, Rick - Clipper 5.2 / Rick Spence - Makron Books, 1994)

Comentários

  1. Desafio.

    Decriptar os novos INCLUDES do P10.

    Já tentei várias funções,
    Abrir o arquivo com FOPEN()
    Usar;
    Encript()
    TarDecomp()
    MSDecomp()
    GZDecomp()

    Ao abrir o arquivo com Notepad++
    aparece a string #zip como parte de um cabeçalho.

    Por hoje eu parei minhas tentativas,
    pq sinto a necessidade de amar a minha mulher!

    Fica ai entao um desafio.
    vc que é um cara esperto, que veio do ninho microsiga,rs!

    Ah, tenho visto seus fontes antigos da epoca de microsiga, vc deve conhecer o pessoal da antiga lá, como o riera o pai do PCO.

    Abs!


    MS

    ResponderExcluir

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" // ---------------

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

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ã