Pular para o conteúdo principal

Postagens

Mostrando postagens de janeiro, 2009

Postagem em destaque

BlackTDN :: Social :: Rifa Festival da Arte Capoeira Projeto Eu Sou Ninja

Angariar fundos para cobrir os custos logísticos do "Festival da Arte Capoeira" e apoiar o projeto Eu Sou Ninja em sua missão de promover a integração social e cultural na comunidade de Jacaraípe. Com a criação da rifa, buscamos envolver a comunidade de forma ativa no financiamento do evento, permitindo que todos contribuam para o sucesso do festival e para a continuidade das atividades do projeto. Prêmio: Copia da minha biblioteca pessoal de AdvPL/TLpp ..etc Participe da Rifa Eu já contribui. Só falta você! ```cmd Pasta de C:\GitHub\naldodj-tlpp 13/04/2024 19:17 . 19/03/2024 13:49 .. 05/01/2024 12:22 2.742 .gitattributes 14/11/2023 16:02 83 .gitignore 02/12/2023 20:08 .vscode 05/01/2024 12:05 bin 13/04/2024 19:18 4.121 ChangeLog.txt 27/12/2023 02:05 include 14/11/2023 16:02 27.030 LICENSE.txt 14/11/2023 16:02 0 makepatch.lst 14/11/2

Protheus :: "Script Linux CentOs/RedHat start/stop/restart TotvsdbAccess/TopConnect"

Para aqueles que usam o SGBD da Oracle e o TotvsdbAccess/TopConnect em Linux, um pequeno "script" para "start,stop and restart" do "daemon" do TotvsdbAccess/TopConnect. Adapte-o às suas necessidades e, atenção para a seguinte linha: NLS_LANG='Brazilian Portuguese_Brazil.WE8ISO8859P1'; export NLS_LANG Altere-a conforme a configuração de NLS_LANG configurada no SGBD #script file: dbacces #!/bin/bash # Avoid using root's TMPDIR unset TMPDIR RETVAL=0 TMP=/tmp; export TMP TMPDIR=$TMP; export TMPDIR ORACLE_BASE=/u01/app/oracle; export ORACLE_BASE ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1; export ORACLE_HOME PATH=/usr/sbin:$PATH; export PATH PATH=$ORACLE_HOME/bin:$PATH; export PATH LD_LIBRARY_PATH=$ORACLE_HOME/lib32:/lib:/usr/lib; export LD_LIBRARY_PATH NLS_LANG='Brazilian Portuguese_Brazil.WE8ISO8859P1'; export NLS_LANG start() { ulimit -n 65526 ulimit -s 1024 ulimit -c 0 ulimit -f unlimited ulimit -v unlimited

Protheus :: Programação Básica em Advpl “Combo XL”

Classificando um Array Unidimensional e Bidimensional: Da mesma forma que podemos passar um bloco para aScan(), também podemos passar um bloco para aSort(). A função aSort() classifica o Array passada por parâmetro, na ordem ascendente, mas, em substituição, podemos passar para ela um bloco de codificação para fazer a comparação. Quando fizermos isso, em vez de aSort() comparar os elementos internamente, ela passará para o Bloco de Codificação os dois elementos necessários para a comparação. A avaliação do Bloco, então, retornará verdadeiro se os dois elementos estiverem classificados em ordem; caso contrário, retornará falso. Quando o Bloco retornar falso, aSort() trocará os dois elementos. É importante observar que aSort() passa o elemento com o número mais baixo do Array como primeiro parâmetro do bloco; desta forma, saberemos quem é quem! É igualmente importante notar que não teremos conhecimento dos dois elementos que estaremos comparando; só saberemos que o primeiro parâmetro é u

Protheus :: Programação Básica em Advpl “Combo XXXIX”

Buscando um Array Bidimensional: Existem várias funções de manipulação de Array. Uma delas é a aScan() que serve para efetuar pesquisa em um Array e retorna o numero do elemento do Array ( Índice ) se a pesquisa foi satisfeita e Zero (0) caso contrário. Essa função poderá ser utilizada tanto em Arrays unidimensionais como em Arrays Bidimensionais. aScan() recebe quatro parâmetros: O primeiro é o Array a ser pesquisado, o segundo é um Bloco de Código com as instruções para pesquisa, o terceiro é a posição inicial ( índice ou elemento inicial ) para pesquisa e o quarto é a posição final para pesquisa ( índice ou elemento final ). O primeiro parâmetro o Array a ser pesquisado é obrigatório, já do segundo ao quarto são opcionais. O segundo parâmetro deve ser passado quando o array a ser pesquisado for um array Multidimensional ou Bidimensional e, quando o Bloco de Codificação for passado aEval() se comportará de maneira diferente do usual. Em vez de aScan() comparar internamente elementos

Protheus :: Programação Básica em Advpl “Combo XXXVIII”

Processando Array com aEval(): aEval() é uma “internal function” que é utilizada para processar variáveis do tipo Array. Em sua forma mais simples usa dois parâmetros, um Array e um bloco de codificação. aEval() simplesmente faz um Loop em cada elemento do Array, passando um de cada vez, como um parâmetro para o Bloco de Codificação. Se o Array contém 5 elementos, aEval() avalia o bloco 5 vezes. Como exemplo, a seguinte chamada a aEval() mostra no Console do Server cada elemento do Array. Local aArray := {“Marinaldo”,“Paulo Lira”,“Paulo Martins”,“Sergio”,“Henry” } aEval( aArray , { |cElem| ConOut( cElem ) } ) Observamos que aEval() está avaliando o bloco de codificação, passando um parâmetro por vez. Denominamos o parâmetro como cElem, mas ele pode ser atribuído com qualquer nome. aEval() é, realmente, uma função muito simples. Poderíamos até criar a nossa. Por exemplo: User Function aEval( aArray , bEval ) Local nLoop Local nLoops nLoops := Len( aArray ) For nLoop := 1 To nLoops

Protheus :: Programação Básica em Advpl “Combo XXXVII”

Arrays Multidimensionais: Examine a seguinte declaração de um array bidimensional: Local aValores[ 3 , 2 ] /*/ que também pode ser declarado como: Local aValores := Array( 3 , 2 ) Local aValores := { { NIL , NIL } , { NIL , NIL } , { NIL , NIL } } Local aValores := { Array( 2 ) , Array( 2 ) , Array( 2 ) } /*/ Em Advpl essa(s) declaração(ões) serão implementadas como um array de três elementos do tipo array e cada array com dois elementos ( onde os valores iniciais são NIL ) Podemos testar da seguinte forma ValType( aValores ) //A Len( aValores ) //3 ValType( aValores[1] ) ) //A Len( aValores[1] ) //2 aValores[1,1] //NIL ValType( aValores[1,1] ) //U Conforme demonstrado acima, aValores é uma referência a um Array de Três elementos, em que cada elemento é uma referência à outra array de dois elementos. Cada elemento de aValores é simplesmente outro array e podemos testá-lo dessa forma. Por exemplo, para localizar aValores[1]

Protheus :: Programação Básica em Advpl “Combo XXXVI”

Elementos de Arrays como Parâmetros: Em Advpl os elementos do array são sempre passados por valor. Para podermos modificar um elemento do array passado como parâmetro, devemos preceder a variável com o operador de referência @, conforme fragmento de código abaixo. Local aTeste[1] aTeste[1] := "Valor Antigo" Alert( aTeste[1] ) //”Valor Antigo” aTeste( aTeste[1] ) Alert( aTeste[1] ) //”Valor Antigo” aTeste( @aTeste[1] ) Alert( aTeste[1] ) //”Novo Valor” Static function aTeste( cTeste ) cTeste := "Novo Valor" Return( NIL )

Protheus :: Programação Básica em Advpl “Combo XXXV”

Passando Arrays por Referência: Verificamos que as variáveis do tipo Array são realmente passadas por valor. Mas podemos, também, passá-las por referência. Para que isso aconteça, temos que preceder o parâmetro real com o símbolo @. Dessa forma, poderemos mudar os elementos do array como antes, e a rotina continuará recebendo uma referência aos elementos do array. Mas, neste caso, a diferença é que, agora, podemos mudar aquilo a que o array se refere, uma vez que a própria variável array foi passada por referência. Podemos ilustrar isso da seguinte forma: Local aNomes := { “P.A.Cabral” , “Santos Dumont” } U_Test( @aNomes ) Alert( aNomes[1] ) // “Einstein” User Function Test( aFormal ) Alert( aFormal[1] ) // P.A.Cabral aFormal := { “Einstein” , “Leibiniz” } Return( NIL ) Se quisermos que a rotina chamada nunca altere o valor do array original, podemos forçar que ela sempre receba uma cópia do array ao invés do próprio array. Isso pode ser feito utilizando a função aClone() da seguinte f

Protheus :: Programação Básica em Advpl “Combo XXXIV”

Arrays como Parâmetro: Ao escrever uma função nós a definimos em termos de parâmetros. Chamamos esses parâmetros de Parâmetros Formais da função. Quando chamamos a função, fornecemos os parâmetros que denominamos Parâmetros Reais. Quando passamos um Array como parâmetro, o Advpl faz o parâmetro formal apontar para o mesmo local indicado pelo parâmetro real. Dessa forma, poderemos mudar os elementos do Array fazendo atribuições a seus parâmetros. Se o parâmetro real tiver um escopo Public ou Private, ele ficará também visível dentro da rotina chamada. Portanto, poderemos usar o operador == para verificar se eles realmente apontam para o mesmo array. Exemplo: Private aNomes := { “P.A.Cabral” , “Santos Dumont” } Test( aNomes ) Function Test( aFormal ) Return( aFormal == aNomes ) //.T.(apenas porque se referem ao //mesmo ponteiro) Podemos, concluir, a partir disto, que os array são passados por referência; acima de tudo, podemos mudar seus elementos. Entretanto, precisamos distinguir e

Protheus :: Programação Básica em Advpl “Combo XXXIII”

Estruturas de Dados usando Arrays: Podemos dizer que em Advpl os Arrays são tratados como referências ou ponteiros. Eles podem ser utilizados para armazenar estruturas de dados complexas como outros arrays, dados numéricos, strings, objetos e até blocos de codificação. Arrays como Referência: Ao declarar um array de nElementos, na verdade, estamos criando duas estruturas de memória. O Advpl cria uma estrutura para conter a própria variável e depois uma seqüência de estruturas para armazenar cada elemento do Array. Imagine uma variável contendo um array como separada dos próprios elementos do array. Pense na variável como se estivesse “apontando” ou “citando” os elementos. Presumindo-se a seguinte declaração: Local aNomes[4] Poderíamos afirmar que aNomes refere-se ao primeiro elemento do Array. Em Advpl podemos fazer com que outra variável Array faça referência ( ou aponte ) para uma outra variável Array. Neste caso elas serão equivalentes. Ex.: Local aNomes[4] Local aVar aVar := aNomes

Protheus :: Programação Básica em Advpl “Combo XXXII”

Parâmetros de Blocos de Codificação: As barras verticais utilizadas na montagem do Bloco de Codificação são as delimitadoras das especificações dos parâmetros formais e o que caracteriza a Montagem de um bloco de código, se elas não forem utilizadas o sistema interpretará que o valor que está sendo atribuído à variável é um array e não um Bloco de Código. A definição e uso desses parâmetros é opcional mas as barras não. Exemplo: bVar := { | nVar1 , nVar2 | nVar1 + nVar2 } nRetult := Eval( bVar , 10 , 20 ) Quando Eval avaliar o bloco de codificação nVar1 terá o conteúdo 10 e nVar2 terá o conteúdo 20. Como em uma função, os parâmetros deverão ser passados na seqüência em que foram declarados. Outro exemplo poderia ser: bVar := { |nVar1,nVar2,cVar3,aVar4| U_Teste(nVar1,nVar2,cVar3,aVar4)} Eval( bVar , 10 , , “C” , {} ) Neste caso, Eval, na avaliação do bloco de codificação, irá efetuar a chamada à função U_Teste() com passagem de parâmetros. Observe que o segundo parâmetro não foi p

Protheus :: Programação Básica em Advpl “Combo XXXI”

Blocos de Codificação: Os Blocos de Codificação ou CodeBlock são variáveis que utilizamos para armazenar fragmentos de codificação do programa. Esses fragmentos podem ser passados para funções que irão executá-los. Criamos um bloco de codificação à partir da seguinte sintaxe: bVar := { || Teste() } O caractere { significa “inicio do bloco de codificação” e o caractere “}”, “fim do bloco de codificação”. As duas barras verticais ( || ) delimitam a lista de parâmetros formais do bloco de codificação. A variável bVar pode ser Local, Static, Private ou Public; não faz diferença. Ela só contém um fragmento de codificação e quando avaliado ele chama a função Test() Para avaliar – ou executar – um bloco de código, use a função Eval(), como em: nResult := Eval( bVar ) esta chama a função Test(). Como toda função Eval() retorna um resultado ( que é o último elemento do bloco de código ) Ex.: bRetVal := {|nVar1,nVar2,nVar3|nVar2:=nVar1+nVar2, nVar2*nVar3} n

Protheus :: Programação Básica em Advpl “Combo XXX”

LOCAL, STATIC e MACROS: As variáveis Local e Static não são mantidas na tabela de símbolos de execução, portanto, os programas que as utilizam executam com mais velocidade e menos memória. Uma conseqüência disto, conteúdo, é que não poderemos acessá-las a partir de expansão de macro. O operador de macros & ou a internal function __ExecMacro() compilam a codificação, durante o processo de execução, à partir de uma string de caracteres contendo uma expressão. Se a expressão citar uma variável, o sistema na execução precisará encontrá-la na tabela de símbolos. O problema com as Locai e Static, evidentemente, é que o sistema, por não armazená-las na tabela de símbolos, nas as encontra fazendo com que ocorra erro durante a execução do sistema se foram expandidas por macro. Por exemplo: nVar := 1 cVar := “nVar” Alert( Str( &( cVar ) ) //ou Alert( Str( __ExecMacro( cVar ) ) Se nVar for uma variável Local, o programa falhará. Observe que cVar pode ser uma variáv

Protheus :: Programação Básica em Advpl “Combo XXIX”

STATIC e PUBLIC: Estas duas instruções também declaram variáveis. PUBLIC declara variáveis que ficam visíveis durante todo o programa. Os problemas que examinamos com relação as variáveis Private também ocorrem com as variáveis Public, contudo com mais abrangência. Em vez de isolados a rotinas chamadas a partir de uma função, os problemas ocorrem na aplicação inteira. As variáveis STATIC podem ajudar a solucionar este problema. Existem dois tipos de variáveis static: internas e externas. A diferença está na abrangência. As variáveis static em nível de arquivo abrangem o arquivo: elas ficam visíveis em qualquer função ou rotina dentro do arquivo de programa no qual estão declaradas. As variáveis static declaradas dentro de uma função ( static internas ) tem escopo local, exatamente como as variáveis local. Obs.: No Protheus, as variáveis Static criadas à partir do menu, serão liberadas sempre que se voltar para o menu. Já as Static criadas durante a entrada do sistema serão mant

Protheus :: Programação Básica em Advpl “Combo XXVIII”

LOCAL, PRIVATE: Essas duas instruções declaram variáveis para uso subseqüente. Entretanto, existem diferenças importantes entre os tipos de variáveis que elas criam. PRIVATE declara variáveis visíveis na rotina na qual você as declara e também em qualquer rotina que você chame a partir do ponto da declaração. User Function Test() Private nI U_Test1() Return( NIL ) User Function Test1() //aqui poderemos enxergar e fazer uso da variável nI criada em //U_Test() Return( NIL ) A instrução LOCAL declara variáveis somente visíveis na rotina na qual foram declaradas; dessa forma: User Function Test() Local nI U_Test1() Return( NIL ) User Function Test1() //aqui não poderemos enxergar e nem fazer uso da variável nI criada //em U_Test() Return( NIL ) O problema com as Private: As variáveis Private representam um dos maiores obstáculos para a criação de rotinas modulares e confiáveis. O principal problema é que elas não são privadas de modo algum e isto ocasiona sérios problemas. Por exemplo, ex

Protheus :: Programação Básica em Advpl “Combo XXVII”

Instruções de Declarações: Uma instrução de declaração é uma instrução para um compilador. Neste seção estamos interessados nas seguintes declarações: LOCAL PRIVATE PUBLIC STATIC LOCAL, PRIVATE, PUBLIC e STATIC declaram variáveis. Obs.: Para evitar ambigüidade entre campos e variáveis Private com o mesmo nome é recomendado a prefixação da variável Private com M->[Nome da Variável ] para identificar que é uma variável de memória e/ou prefixar o campo com o respectivo Alias usando o operador -> como em: [Alias]->[ Campo da Tabela ]. Obs.: Melhor do que declarar uma variável com o Mesmo nome do campo é declarar a variável utilizando a notação Húngara Modificada onde as variáveis são prefixadas com a letra minúscula correspondente ao seu tipo ( Em Inglês ). Tipo: Exemplo: "N"umeric nNumber "C"haracter cChar "B"lock bBlock "D"ate dDate "L"ogic lOk "O&

Protheus :: Programação Básica em Advpl “Combo XXVI”

Recursividade: As funções e rotinas podem ser recursivas, isto é, podem chamar a si mesmas. Cada chamada recebe uma nova cópia das variáveis Local e Private e de quaisquer parâmetros. Quando uma função retorna, os valores anteriores são restabelecidos. Obs.: Não são alocadas novas cópias de variáveis STATIC. Exemplo: User Function SaveArray( uArray , cFileName , nErr ) Local cValTypeuArray := ValType( uArray ) Local lSaveArray := .F. Local aArray Local nfHandle Begin Sequence IF !( cValTypeuArray $ "A/O" ) Break EndIF IF ( cValTypeuArray == "O" ) aArray := ClassDataArr( uArray ) Else aArray := uArray EndIF lSaveArray := FileCreate( cFileName , @nfHandle , @nErr ) IF !( lSaveArray ) Break EndIF SaveArr( nfHandle , aArray ) //Aqui chamamos a função para salvar o Array fClose( nfHandle ) End Sequence Return( lSaveArray ) Static Function SaveArr( nfHandle , aArray ) Local cElemType Local

Protheus :: Programação Básica em Advpl “Combo XXV”

Chamando Funções Indiretamente: Em Advpl é possível efetuar a chamada de funções indiretamente usando o operador de macros. Este procedimento lhe permitirá usar aplicativos controlados por dados. Pode-se usar um bando de dados ( à exemplo do SX3 ) para armazenar uma seqüência de funções a serem chamadas, e depois usá-lo para gerar telas, efetuar validação de campos, iniciar o conteúdo de campos, etc. Para passar uma função como parâmetro, passe o nome da função como uma string de caracteres ou como uma chamada de função dentro de um bloco de codificação. Para chamá-la, use o operador de macros & ou a função __ExecMacro() quando estiver passando uma string de caracteres ou Eval() para avaliar o bloco de código. Exemplo: cExecTeste := “U_TESTE()” &( cExecTeste ) ou cExecTeste := “U_TESTE()” //Executa a função U_TESTE() __ExecMacro ( cExecTeste ) //Executa a função U_TESTE() ou ainda bExecTeste := { || U_TESTE() ) Eval( bExecTeste ) //Executa a função U_TESTE()

Protheus :: Programação Básica em Advpl “Combo XXIV”

Envio Por Referência ou por Valor: Um aspecto importante do envio de parâmetros para as funções é se eles são passados por referência ou por valor. O método de envio de um argumento dependerá do método de chamada; ele não pode ser determinado no ponto em que a própria função é definida. Quando os parâmetros são passados por referência, a função recebe ponteiros para os verdadeiros parâmetros, e quaisquer mudanças que ela introduzir neles serão imediatamente refletidas em seus valores: User Function Test1() Local nVar nVar := 3 U_Test2( @nVar ) //Apos o retorno de U_Test2() nVar terá o conteúdo igual 1 Return( NIL ) User Function Test2( nVar1 ) nVar1 := 1 Return( NIL ) Para efetuarmos a passagem por referência devemos prefixar a variável com o operador de referência @. Se passarmos um parâmetro por valor, o valor inicializará a variável local ou privada associada com o parâmetro formal, mais quaisquer mudanças introduzidas neste valor pela função desaparecerão. O verdadeiro parâmetro nã

Protheus :: Programação Básica em Advpl “Combo XXIII”

Funções/Parâmetros Ao fazer uma chamada a uma função valores são fornecidos para os parâmetros. Esses valores podem assumir a forma de constantes, variáveis, campos, elementos de arrays ou expressões, e eles são citados como parâmetros reais ou argumentos de chamada. Uma chamada de função pode, também, omitir argumentos para qualquer número de parâmetros, deixando um vazio onde o argumento deveria estar. Será necessário incluir as vírgulas delimitadoras na lista de argumentos, exceto para quaisquer argumentos omitidos no final da lista. Isto assegura não existir ambigüidade sobre quais parâmetros foram deixados em branco. Quaisquer argumentos omitidos de uma chamada de função serão tratados exatamente como se o valor NIL tivesse sido realmente passado. Não há como distinguir, dentro da definição de função, entre o argumento omitido e um valor NIL passado explicitamente. A chamada: User Function Test( nS , nE , nI , nD ) Return U_Test( nRow , , 2 ) À função U_Test(), conforme definida

Protheus :: "Windows® PowerShell® Script Stop and Start Services"

Como é do conhecimento de todos, os serviços do Protheus tem um "pequeno" problema no que diz respeito ao gerenciamento de memória (quando executado sobre a plataforma Windows Server 32). Sendo assim, de vez em quando faz-se necessário "reiniciar" esses serviços de forma a liberar memória e evitar efeitos colaterais. Em função desse "pequeno problema", disponibilizo um "script" em Windows® PowerShell® para "reiniciar" os serviços do Protheus. Para adaptá-lo às suas necessidades altere: $IniPort; $EndPort; o nome do serviço a ser "parado/reiniciado" e o intervalo de definição das "portas" (presumindo que existam vários serviços do Protheus "escutando" em um mesmo "server"). #Script Name P10Restart.ps1 $IniPort = 5110 $EndPort = 5911 for ( $Port = $IniPort ; $Port -le $EndPort ; $Port+=100 ) { if ( get-service | where { $_.status -eq "running" -and $_.name -eq "P10Server"

Protheus :: Programação Básica em Advpl “Combo XXII”

Funções: As funções, em Advpl, podem ser entendidas como um mecanismo de sub-rotinas. Elas sempre retornam um valor. Uma função pode retornar qualquer tipo de dados ( array, numérico, string, objeto, lógico... ) e, se nenhum tipo de retorno for definido a função retornará NIL. Elas retornam seu valor como uma expressão após a instrução RETURN ( Obs.: a rotina chamadora da função não precisa, necessariamente, usar o valor de retorno ). O uso adequado das funções possibilita a grande reutilização da codificação. As funções são definidas uma só vez dentro de um programa, mas podem ser chamadas várias vezes. Elas podem ser definidas em qualquer ordem e você pode chamar uma antes de defini-la. Todas as funções são armazendas no Repositório de Objetos. E Podem ser declaradas como: Públicas: Podem ser chamadas em qualquer programa: Funções Reservadas ( Microsiga ) Function -> Reservado para desenvolvimento no ERP na Microsiga Template Function -> Para a criação

Protheus :: Programação Básica em Advpl “Combo XXI”

Compilação Condicional: A compilação condicional nos permite incluir ou excluir codificação baseada numa condição. O propósito usual é manter diferentes versões de um programa, sem precisar separar cópias da codificação de origem. Por exemplo, poderíamos ter uma verão utilizando o TopConNect e outra para CodBase, As diretivas do pré-processador para a compilação condicional se parecem com as instruções IF/ELSE/ENDIF. O pré-processador inclui ou exclui codificação do arquivo de saída, baseado no resultado do teste. O teste, conseqüentemente, atua como um filtro. O aspecto importante a observar é que o pré-processador faz o teste, não o programa. Dessa forma, a codificação não-selecionada nem sequer existe no arquivo de saída. As diretivas verificam se um símbolo está definido ou se ele tem um valor específico ( podemos definir um símbolo com a diretiva #DEFINE ). As diretivas do pré-processador são: #IFDEF - Verifica se um símbolo está definido #IFNDEF - Verifi

Protheus :: Programação Básica em Advpl “Combo XX”

Macros do compilador: Podemos visualizar uma macro do compilador como uma função diretamente na codificação de origem do programa onde poderíamos parametrizar uma seqüência de comandos, exatamente como uma função. A diferença é que as macros do pré-processador são substituídas diretamente no arquivo de origem ( elas não são chamadas do mesmo modo que uma função ) . Por exemplo, poderíamos escrever uma macro de pesquisa de mínimo como: #DEFINE MIN( a , b ) IIF( a < b , a , b ) Quando, subseqüentemente, chamar-mos a MIN com: nMin := MIN( nY , nZ ) O pré-processador a substituirá por sua definição como em: nMin := IIF( nY < nZ , nY , nZ ) Defina a macro usando parâmetros formais, exatamente como uma função. Quando o pré-processador a expandir, ele os substituirá pelos verdadeiros parâmetros (argumentos). Isto é basicamente o que acontece quando você chama uma rotina ou função. A diferença é que a substituição dos argumentos ocorre no tempo do pré-processador

Protheus :: Programação Básica em Advpl “Combo XIX”

Arqivos Include: As constantes simbólicas só são conhecidas no arquivo de origem que as define. O pré-processador só conhece seus valores depois da tradução. Portanto se definirmos uma constante um programa ela só valerá durante a compilação deste programa. Para que uma constante possa valer para mais de um programa, devemos usar um recurso de inclusão de arquivos através da diretiva #include. Ou seja, as constantes seriam incluídas em um arquivo à parte e todo programa que fosse utilizar essas constantes teria a seguinte linha #include “ ”.

Protheus :: Programação Básica em Advpl “Combo XVIII”

Pré-Processador: O pré-processador é um importante recurso no Advpl. Imagine-o como um programa que executa antes do compilador. Ele lê o programa como entrada e gera um arquivo pré-processado como saída. O arquivo de saída, então, serve como a entrada do compilador. Podemos incluir comandos do pré-processador, chamadas de diretivas, no programa de origem. O pré-processador as manipulará; o compilador nunca as percebe, uma vez que ele só manipula o arquivo de saída. O pré-processador do Advpl tem os seguintes recursos: - constantes simbólicas ou manifestas - arquivos include - macros do compilador - compilação condicional - comandos definidos pelo usuário Constantes Simbólicas: No Advpl é possível a definição de constantes simbólicas para uso no processo de pré-compilação. Devemos abrir mão desse recurso para tornar os programas mas legíveis e fácil de entender. Por Exemplo, no fragmento de codificação: IF ( nOpc == 1 ) Inclui() ElseIF ( nOpc ==

Protheus :: Programação Básica em Advpl “Combo XVII”

Loops: O Advpl oferece os loops FOR e WHILE. A instrução FOR executa instruções até o NEXT correspondente durante um determinado número de vezes. Devemos informar a quantidade de vezes a iterar, como em Local nLoop Local nLoops := 10 For nLoop := 1 To nLoops ... ... Next nLoop A inicialização da variável para controle do Loop deverá é feita na declaração For nLoop :=, o NEXT incrementa-a automaticamente e, se ele não tiver ultrapassado seu limite, o controle retornará para a primeira instrução dentro do loop. O valor do incremente é igual a 1, a menos que especificado de outra maneira com a opção STEP. Local nLoop Local nLoops := 100 For nLoop := 1 To nLoops Step 10 … Next nLoop ou Local nLoop Local nLoops := 0 For nLoop := 100 To nLoops Step –10 … Next nLoop Podemos usar os comandos EXIT e LOOP dentro do corpo do loop FOR. Exit encerra o Loop, transferindo o controle para a instrução depois do NEXT; o LOOP dá um salto para o início, reavaliando a

Protheus :: Programação Básica em Advpl “Combo XVI”

Estruturas de controle: Como acontece com a maioria das linguagens, o Advpl fornece instruções para suportar desvios e loops. As instruções de desvio permitem que seus programas selecionem entre alternativas; as instruções de loops permitem executar um grupo de instruções repetidas vezes. Desvio: No Advpl existem dois métodos de desvio: o bloco de instruções IF/ELSE/ELSEIF/ENDIF ou o bloco DO CASE/ENDCASE. ELSEIF é apenas uma abreviação que evita a necessidade de se escrever outro IF/ENDIF. Os dois exemplos que se seguem são equivalentes: IF ( nX < 10 ) ... Else IF ( nX > 20 ) ... EndIF EndIF ou IF( nX < 10 ) ... ElseIF ( nX > 20 ) ... EndIF Observe que, como o Advpl sempre insiste num ENDIF encerrando todo o bloco de IF, sempre saberemos a quem pertence um Else. Obs.: Ao testar várias condições, é preferível uma instrução CASE a uma longa seqüência de IF/ELSEIFs. Na implementação das instruções CASE, o Advpl avalia uma condição de cada vez, at

Protheus :: Programação Básica em Advpl “Combo XV”

O último operador que examinaremos é o $ ( contido em ). Use-o para verificar se uma string está contida em outra. Por exemplo, para constatar se a variável de memória de caractere isolado cTipoPeca é R, D, ou b, podemos escrever: IF cTipoPeca $ “RDB” ... Para verificar se uma variável de memória de dois caracteres é “PR”, “SP”, ou “AM”, escreva: IF cEstado $ “PR_SP_AM” ... Obs.: Os separadores “_” são necessários para invalidar combinações, como “RS” e “PA” que são estados válidos. Dica: Use o operador $ ao invés de várias condições separadas. Ex.: Do Case Case cEstado == “PR” ; Execute(“PR”) Case cEstado == “SP” ; Execute(“SP”) Case cEstado == “AM” ; Execute(“AM”) EndCase Poderia ser escrito como IF ( cEstado $ “PR_SP_AM” ) Execute(“PR_SP_AM”) EndIF Expressões condicionais: IIF() ou IF() é uma expressão condicional. São abreviações de uma simples seqüência de IF/ELSE/ENDIF. Por exemplo, para encontrar

Protheus :: Programação Básica em Advpl “Combo XIV”

Conectivos Lógicos: É possível negar uma expressão lógica com .NOT. ou com o ponto de exclamação, que é equivalente. No Advpl as expressões lógicas são avaliadas da esquerda para a direita ( parando assim que o resultado é conhecido ). Esse processo é chamado “avaliação de curto-cirquito”. Por exemplo: #DEFINE NLIMITE 10 Local aArr[NLIMITE ] Local nIndice := 1 Local nMax := 50 ... ... While ( ( nIndice <= NLIMITE ) .and. ( aArr[ nIndice ] < nMax ) ) Process() nIndice := nIndice + 1 //ou ++nIndice End While Quando o valor de nIndice for 11, a primeira expressão provocará a interrupção da avaliação. ( no exemplo, a segunda expressão não será avaliada, caso contrário ocorreria o erro conhecido como “erro de subscrito” – O erro ocorreria porque “aArr” for definido com 10 elementos ( NLIMITE 10 ); se a segunda comparação fosse efetuada, teríamos aArr[11 ] para um array de 10 elementos apenas. O Advpl avalia os operandos de operadores binários, tanto aritm

Protheus :: Programação Básica em Advpl “Combo XIII”

Operadores Relacionais: No Advpl são permitidos os seguintes operadores relacionais: Os operadores relacionais têm menos prioridade do que os aritméticos. Por exemplo: nI < nLimite – 1 é avalidado como: nI < ( nLimite – 1 ) e não como: ( nI < nLimite ) – 1

Protheus :: Programação Básica em Advpl “Combo XII”

Operadores Unários: O Advpl suporta um sinal negativo ( o chamado operador unário). Ele tem a maior prioridade entre os operadores aritméticos. Por Exemplo: - 1 + 2 resulta 1 e não -3. O Advpl suporta os operadores de incrementos e decrementos unários ++ e --. O Operador ++ acrescenta 1 a seu operando, -- subtrai 1. Ambos têm parceiros nas instruções regulares de atribuições. Exemplo: nContador++ é idêntico a nContador := nContador + 1 Entretanto, a vantagem desses operadores unários é o fato de serem concisos e de poderem ser utilizados para deferir a operação até depois de processado o valor. Por Exemplo, para carregar um array de campo CPnome de cada registro de um banco de dados chamado Alunos, poderíamos escrever: Local acPNomes Local nContador := 1 Use Alunos acPNomes := Array( RecCount() ) While ( Alunos )->( !Eof() ) acPNomes[ nContador++ ] := ( Alunos )->CPNOME ( Alunos )->( dbSkip() ) End While O Subscrito do array usa o valor de nContador,

Protheus :: Programação Básica em Advpl “Combo XI”

Operadores e Expressões: O Advpl suporta os seguintes operadores binários: Que agrupados em ordem de precedência ( prioridade, a mais alta primeiro ). Os operadores ** e ^ têm ambos a prioridade mais alta. Os operadores *, / e % tem níveis de prioridades iguais, assim como os operadores + e -. Os operadores *, / e % tem uma precedência maior do que + e -. O Advpl avalia os operadores, de igual precedência, da esquerda para a direita.

Protheus :: Programação Básica em Advpl “Combo X”

Variáveis Numéricas: O Advpl, na leitura de uma variável numérica, atribui, automaticamente, dez posições antes da casa decimal, a despeito do seu tamanho atual. Portanto, esse tamanho é passível de ser aumentado. Já em relação ao número de posições depois do ponto decimal é determinado quando você o atribui a ela. Assim, se para montar um Get, tivermos o seguinte bloco de programa: Local nValor := 15.1270 @ 10 , 10 Say “Digite um novo valor:” Get nValor nValor terá 4 posições após o ponto decimal e duas posições antes do ponto decimal ( conforme valor atribuído à variável ); portanto o Get usa 7 colunas da tela: 2 para antes do ponto decimal, uma para o próprio ponto decimal e quatro depois dele. Ao inicializar variáveis numéricas para uso em um Get, certifique-se de atribuir a elas o número correto de casas decimais ou utilize picture como em: Local nValor := 15.12 @ 10 , 10 Say “Digite um novo valor:” Get nValor Picture @R 999.99999 Apesar de nValor ter sido declarado como tendo ape

Protheus :: Programação Básica em Advpl “Combo IX”

Protheus :: Programação Básica em Advpl “Combo IX” Tamanho: Faz-se necessário observar o tamanho de variáveis de caracteres e numéricas uma vez que um problema difícil de analisar é a comparação de variáveis de tamanhos diferentes; os espaços de preenchimento podem ser significativos.: Variáveis Caractere Ex.: Local cUsuario := “Administrador” Local cUser := “Administrador “ Local lEqual lEqual := ( cUsuario == cUser ) No exemplo acima lEqual irá retornar .F. uma vez que o conteúdo armazenado na variável cUsuario ( apesar de parecer igual ) é diferente do conteúdo da variável cUser. O que diferencia o conteúdo entre uma variável e outra são os espaços à direita. Para resolver o problema na comparação teremos que abir mão de uma função que remova os espaços à direita ( RTrim( ) ). Ex.: Local cUsuario := “Administrador” Local cUser := “Administrador “ Local lEqual lEqual := ( cUsuario == RTrim( cUser ) ) //Removendo espaços a //direita ou lEqual := ( cUsuari

Protheus :: Personalizando o RHOnLine

Neste artigo vou demonstrar como personalizar o seu RHOnLine, deixando-o com a cara de sua empresa e no padrão W3C de forma a funcionar nos principais "browsers" (IE, Firefox, Google Chrome, etc. O RHOnLine do padrão só funciona com o IE). Neste exemplo não teremos todas as funcionalidades do RHOnLine padrão, apenas uma tela de abertura, o Demonsrtrativo de Pagamento e a opção para alteração de senha. Mas isso não impede que as demais funcionalidades sejam implementadas, bastando seguir o modelo aqui fornecido. Nesse modelo utilizamos uma ferramenta do site BarcodesInc® para gerar o código de barras para o Demonstrativo de Pagamento de forma a dar-lhe mais "credibilidade". A personalização do RHOnLine terá as seguintes características: Tela de Abertura Tela de Apresentação Tela para escolha do período para impressão do Demonstrativo Tela de mensagem caso não existam informações de Demonstrativo Tela do Demonstrativo Tela de rodapé do Demonstrativo (com código de

Protheus :: Programação Básica em Advpl “Combo VIII”

Conversão de variáveis: No Advpl é possível converter os tipos usando uma função ou expressão condicional. Tabela de Conversão de Tipos (Clique na Imagem para ampliá-la)

Protheus :: Programação Básica em Advpl “Combo VII”

Tipo: O Advpl suporta os seguintes Tipos: Array Bloco Caractere ( Caractere isolado ou string até 1Mb ) Data Lógico Memo Numérico Objeto Diferentemente das linguagens como C, C++, Java, etc..., as variáveis em Advpl não são prototipadas. Seus tipos são definidos no momento após a atribuição de valores. Para testar o tipo de uma variável pode-se utilizar a função Type() ou ValType(). Type() para variáveis públicas e privadas declaradas em outras instâncias do programa e ValType() para variáveis que pertencem à mesma instància. Ex.: Function Test1() Local aTest Private aTest1 := {} Test2( aTest ) Return( NIL ) Function Test2( aTest ) IF ( Type( “aTest1” ) == “A” )//A variável deve estar entre aspas IF ( ValType( aTest ) == “A” ) aTest := aTest1 Else Alert( “A variavel aTest nao eh um Array” ) EndIF EndIF

Protheus :: Programação Básica em Advpl “Combo VI”

Variáveis: No Advpl, as regras para a nomeação de identificadores são parecidas com as das linguagens típicas de computadores. A nomeação poderá ser iniciada com uma letra ou um caractere de sublinhado e poderão conter letras, sublinhados e dígitos. Para manter compatibilidade com o “legado” foi mantida a limitação de dez primeiros caracteres como significativos. Por isso, deve-se ter muito cuidado com nomes extensos. Se for utilizar nomes extensos lembre-se que atualmente apenas os dez primeiros caracteres serão considerados mas, se declarar uma variável com nome extenso, utilize-a da forma como foi declarada para que, se um dia a limitação de dez caracteres foi modificada, não seja necessário estar modificando os programas. A restrição em dez caracteres pode ser fonte de defeitos ardilosos. Por exemplo, as seguintes variáveis: cSNome_do_Pai cSNome_do_Avo Serão consideradas idênticas. A truncagem dos identificadores longos é conseqüência do tamanho fixo dos nomes nas tabel

Protheus :: Programação Básica em Advpl “Combo V”

Comandos vs Literais: Alguns comandos em AdvPl exigem argumentos literais. Uma literal é uma seqüencia de caracteres interpretada literalmente. Não será possível usar uma constante ou expressão no lugar da literal. Ex.: Use cTable No exemplo acima, cTable é uma literal. Ela é interpretado literalmente, não como uma variável. O pré-compilador irá transformar a Literal em uma string de caracter da seguinte forma: dbUseArea( .F.,, "cTable",, if(.F. .OR. .F., !.F., NIL), .F. ) Para que cTable não seja considerado como uma literal mas sim como uma variável coloque-a entre parenteses como em: Use ( cTable ) Que o pré-processador converterá em: dbUseArea( .F.,, ( cTable ),, if(.F. .OR. .F., !.F., NIL), .F. )

Protheus :: Programação Básica em Advpl “Combo IV”

Constantes: Constantes são Valores predefinidos que não mudam durante o programa. Elas podem ser strings de caracteres, números, valores lógicos, blocos de codificação, arrays ( vetores ). Ex.: “pressione uma tecla para continuar” 15 1970.15 .T. { || MyTest() } {“Domingo”,“Segunda”,“Terça”,“Quarta”,“Quinta”,“Sexta”,“Sábado”} No Advpl, as constantes numéricas são sempre decimais. Não são suportados outros sistemas de números nem notação científica. Não há diferença entre caracteres isolados “a” e strings “Isso é uma string”. Uma string é simplesmente um ou mais caracteres. Para definir uma constante do tipo string maior que uma linha, continue-a com um ponto e vírgula e junte as partes com o operador “+” Ex.: “esta string será continuada”+; “na próxima linha” No AdvPl não existem constantes de datas. Será necessário contruí-las à partir de uma string de caracteres e com a função CToD() como no exemplo: Ex.: Ctod( “18/02/2005”) O resultado será uma data, mas ela não será realmente u

Protheus :: Programação Básica em Advpl “Combo III”

Comentários: O compilador Advpl ignora as linhas em branco e a indentação. Ambas tornam o programas mais legível e, devemos abrir mão deste recurso para tornar os programas mais legíveis. Os comentários também são ignorados pelo compilador. Na realidade, as linhas em branco, a identação e os comentários nos programas são tratados pelo pré-processador. No Advpl são permitidas as seguintes formas de se comentar um programa: //Para efetuar o comentário em uma linha. ( Tudo o que estiver à direita //das ( // ) será considerado como um comentário. Obs.: Pode-se utilizar o sinal de * ou && no inicio da frase para se efetuar o comentário de uma única linha. Deve-se escolher uma por padrão e ser coerente. /* Para efetuar o comentário em mais de uma linha. ( Tudo o que estiver entre ( /* e */ ) será considerado como comentário. */ Obs.: para facilitar a utilização do modelo de comentário acima utilize /*/ para abrir o comentário e /*/ para garantir que um comentário nunca deix

Protheus :: Programação Básica em Advpl “Combo II”

Instruções e Comandos: As instruções são elementos fixos da linguagem, que lidam com afirmações e com o controle do programa; c := IF( a > b , a , b ) While ( ( cAlias )->( !Eof() ) //... mais instruções ( cAlias )->( dbSkip() ) End While nLoops := 10 For nLoop := 1 To nLoops //... mais instruções Next nLoop ... Já os comandos, representam o conjunto de tipos de instruções da linguagem que não são nem rotinas nem chamadas de função e nem atribuições. Replace cCampo1 With “Conteudo do Campo 1”,; cCampo2 Whit “Conteudo do Campo 2” Obs.: Como padrão, um caractere de final de linha encerra uma instrução. Para continuar na outra linha, use o caractere de ponto-e-vírgula. Use cTable New Via “DBFCDX” Copy To cNewTable Via “DBFCDX” Totas as instruções são fixadas em determinada versão da linguagem e, todos os comandos são convertidos pelo pré-processador em chamadas de funções e atribuições. Onde: Replace cCampo1 With “Conteudo do Campo 1”,; cCampo2 Whit “Con

Protheus :: Programação Básica em Advpl “Combo I”

A linguagem Advpl é um Super-Conjunto da linguagem padrão xBase/CodBase e evoluiu à partir do padrão do Clipper 5.3 e das bibliotecas do FiveWin. Ela comporta quase todos os comandos e funções utilizados no Clipper 5.3 e no FiveWin. O Advpl é a linguagem utilizada pela Totvs/Microsiga para o desenvolvimento do ERP e no desenvolvimento de rotinas específicas nas empresas usuárias desse sistema. Os elementos sintáticos que formam as instruções de programação em Advpl podem ser divididas nos seguintes grupos: instruções, comandos, diretivas, funções, classes, métodos, constantes , campos e operadores.

Windows® PowerShell® "Script" para sincronização do Repositório do Protheus

Hoje Postarei uma dica de como criar um "script", utilizando o Windows® PowerShell® para sincronizar os "Repositórios de Objetos" do Protheus entre o ambiente de desenvolvimento e o de produção. Crie o arquivo syncApos.ps1 e, utilizando um editor de texto de sua preferência (Notepad, Notepad++ ou Edit, etc.), inclua o código abaixo. Altere o "Path" <$path>, a "string" de busca <$find>, a "string" de substituição <$replace>,o caminho de onde o repositório deverá ser copiado e o diretório de destino do repositório para adequar às suas necessidades. Para maiores informações de como instalar o Windows® PowerShell® e de como executar "scripts" leia o "Post" Conexão automática ao Claro3G. Tendo feito isso basta criar um agendamento utilizando o Agendador de Tarefas do Windows® ("Task Manager") e seus repositórios serão sincronizados. Obs.: Para que o "script" possa ser executado no