4D v16.3

Detalhes de sintaxe

Página Inicial

 
4D v16.3
Detalhes de sintaxe

Detalhes de sintaxe  


 

 

O compilador espera as regras de sintaxe habituais dos comandos 4D, não necessita modificações especiais para bancos que vão ser compilados.

Entretanto esta seção oferece alguns lembretes e detalhes específicos:

  • Alguns comandos que influem no tipo de uma variável podem, se não tiver cuidado, levar a conflitos.
  • Alguns comandos utilizam mais de uma sintaxe ou parâmetros, é importante saber qual é o mais apropriado.

Strings  

Para os comandos que operam sobre strings, só a função Character code requer atenção especial. Em modo interpretado, pode passar indiferentemente uma string não vazia ou vazia a esta função.
Em modo compilado, não pode passar uma string vazia.
Se passa uma string vazia e o argumento passado a Character code é uma variável, o compilador não poderá detectar um erro na compilação.

SEND VARIABLE(variable)
RECEIVE VARIABLE(variable)

Estes dois comandos são utilizados para escriever e receber variáveis enviadas ao disco. As variáveis são passadas como parâmetros a estes comandos.

O parâmetro que passa deve ser sempre do mesmo tipo. Suponha que deseja enviar uma lista de variáveis a um arquivo. Para eliminar o risco de mudar os tipos de dados involuntariamente, recomendamos especificar ao princípio da lista o tipo das variáveis enviadas. Desta forma, quando você recebe estas variáveis, sempre começará por obter um indicador. Depois, quando chama a RECEIVE VARIABLE, a transferência se maneja através de uma instrução Case of.

Exemplo:
 SET CHANNEL(12;"Arquivo")
 If(OK=1)
    $Tipo:=Type([Cliente]Total_A)
    SEND VARIABLE($Tipo)
    For($i;1;Records in selection)
       $Enviar_A:=[Cliente]Total_A
       SEND VARIABLE($Enviar_A)
    End for
 End if
 SET CHANNEL(11)
 SET CHANNEL(13;"MeuArquivo")
 If(OK=1)
    RECEIVE VARIABLE($Tipo)
    Case of
       :($Tipo=Is string var)
          RECEIVE VARIABLE($Cadena)
  `Processo da variável recebida
       :($Tipo=Is real)
          RECEIVE VARIABLE($Real)
  `Processo da variável recebida
       :($Tipo=Is text)
          RECEIVE VARIABLE($Text)
  `Processo da variável recebida
    End case
 End if
 SET CHANNEL(11)

Field (ponteiro campo) ou (tabela número;campo número)
Table (
ponteiro tabela) ou (tabela número) ou (ponteiro campo)

Estes dois comandos devolvem os resultados de diferentes tipos de dados, de acordo com os parâmetros passados:
  • Se passa um ponteiro a função Table, o resultado devolvido é um número.
  • Se passa um número á função Table, o resultado devolvido é um ponteiro.

Lembre que as referências do documento retornado pelas funções Open document, Append document e Create document são de tipo Hora.

Mod (valor;divisor)

A expressão “25 modulo 3” pode ser escrita de duas formas diferentes em 4d:
 Variable:=Mod(25;3)

ou

 Variable:=25%3

O compilador vê uma diferença entre as duas: Mod aplica a todos os tipos numéricos, enquanto o operador % aplica somente a Inteiros e Inteiros longos. Se o operando do operador % excede a faixa dos Inteiros longos, o resultado retornado provavelmente será errado.

IDLE
ON EVENT CALL (Method{; ProcessName})
ABORT

O comando IDLE foi adicionado à linguagem 4D para manejar exceções. Este comando deve ser utilizado quando utilize o comando ON EVENT CALL.

Este comando pode ser definido como uma diretriz de gestão de eventos.
Só o kernel (núcleo) de 4D pode detectar um evento sistema (clique do mouse, atividade do teclado, etc.). Na maioria dos casos, as chamadas ao kernel são iniciadas pelo mesmo código compilado, de uma maneira transparente para o usuário.

Por outra parte, quando 4D está esperando tranquilamente por um evento, por exemplo em um loop de espera, é evidente que não haverá nenhuma chamada.

  `Método de projeto CliqueMouse
 If(MouseDown=1)
    <>vPrueba:=True
    ALERT("Alguem clicou no mouse")
 End if
 
  `Método Espera
 <>vPrueba:=False
 ON EVENT CALL("CliqueMouse")
 While(<>vPrueba=False)
  `Loop de atenção do evento
 End while
 ON EVENT CALL("")

Neste caso, se adiciona o comando IDLE da seguinte forma:

  `Método Espera
 <>vPrueba:=False
 ON EVENT CALL("CliqueMouse")
 While(<>vPrueba=False)
    IDLE
  `Chamar ao Kernel para detectar um evento
 End while
 ON EVENT CALL("")
ABORT  

Utilize este comando só em métodos de projeto de lidar com erros. Este comando funciona exatamente como em 4D, exceto em um método que tenha sido chamado por um dos seguintes comandos: EXECUTE FORMULA, APPLY TO SELECTION e APPLY TO SUBSELECTION. Trate de evitar esta situação.

Arrays  

Sete comandos de 4D são utilizados pelo compilador para determinar o tipo de um array:

COPY ARRAY(fuente;destino)
SELECTION TO ARRAY(campo;Array)
ARRAY TO SELECTION(Array;campo)
SELECTION RANGE TO ARRAY(início;fim;campo;Array)
LIST TO ARRAY(lista;Array{; itemRefs})
ARRAY TO LIST(Array;lista{; itemRefs})
DISTINCT VALUES(campo;Array)

O comando COPY ARRAY aceita dois parâmetros de tipo Array. Se um dos parâmetros de array não foi declarado, o compilador determina o tipo do array não declarado segundo o tipo do declarado.
Esta dedução é realizada nos dois casos seguintes:

  • O array declarado é o primeiro parâmetro. O compilador atribuiu o  tipo do primeiro array ao segundo array.
  • O array declarado  é o segundo parâmetro. Neste caso, o compilador atribuiu o tipo de dado do segundo array ao primeiro array.

Como o compilador é rigoroso com os tipos, COPY ARRAY só pode ser feito desde um array de um certo tipo a um array do mesmo tipo.
Portanto, se deseja copiar um array de elementos cujos tipos são similares, ou seja, Inteiros, Inteiros longos e Reais, ou Texto e Alfas, ou Alfas de diferentes longitudes, tem que copiar os elementos um por um.

Imagine que deseja copiar elementos de um Array Inteiro a um Array Real. Pode agir da seguinte forma:

 $Tamanho:=Size of array(ArrInt)
 ARRAY REAL(ArrReal;$Tamanho)
  `Estabelecer o mesmo tamanho para o array Real que para o array Inteiro
 For($i;1;$Size)
    ArrReal{$i}:=ArrInt{$i}
  `Copiar cada elemento
 End for


Lembre que não pode mudar o número de dimensões de um array durante o processo. Se copiar um array de uma dimensão em um array bidimensional, o compilador gera uma mensagem de erro.

Com 4D em modo interpretado, estes quatro comandos não necessitam a declaração de arrays. Os arrays não declarados recebem o mesmo tipo que o campo especificado no comando.
Se escreve:

 SELECTION TO ARRAY([MinhaTabela]CampoInteiro;MeuArray)

o tipo de dados de MeuArray seria Inteiro de uma dimensão. (assumindo que CampoInteiro seja um campo inteiro).

Se o array foi declarado, tenha certeza de que o campo seja do mesmo tipo. Mesmo que Inteiro, Inteiro longo e Real são tipos similares, não são equivalentes.
Por outro lado, no caso de tipos Texto e Alfa, tem um pouco mais de latitude. Por padrão, se um array não foi declarado previamente e você aplica um comando que inclui um campo de tipo Alfa como parâmetro, se atribui o tipo Texto ao array. Se o array foi declarado previamente como de tipo Alfa ou de tipo Texto, estes comandos seguirão suas diretrizes.

O mesmo acontece no caso dos campos de tipo Texto––suas diretrizes tem prioridade.
Lembre que os comandos SELECTION TO ARRAY, SELECTION RANGE TO ARRAY, ARRAY TO SELECTION e DISTINCT VALUES só  podem ser utilizados com arrays de uma dimensão.

O comando SELECTION TO ARRAY também tem uma segunda sintaxe:
SELECTION TO ARRAY(tabla;Array).
Neste caso, a variável MeuArray será de Array de Inteiros longos. O comando SELECTION RANGE TO ARRAY funciona da mesma forma.

Os comandos LIST TO ARRAY e ARRAY TO LIST referem só a dois tipos de arrays:

  • os arrays Alfa de uma dimensão e
  • os arrays Texto de uma dimensão.
    Estes comandos não necessitam a declaração do array que se passa como parâmetro. Por padrão, um array não declarado receberá o tipo Texto. Se o Array foi declarado previamente como de tipo Alfa ou Texto, estes comandos seguirão suas diretrizes.

O compilador não pode detectar um conflito de tipo se utilizar um ponteiro sem referência como parâmetro de um comando de declaração de um array. Se escreve:

 SELECTION TO ARRAY([Tabela]Campo;Ponteiro->)

onde Ponteiro-> representa um array, o compilador não pode verificar que o tipo do campo e o do array são idênticos. Deve prevenir tais conflitos; deve declarar o array referenciado pelo ponteiro.

O compilador emite uma advertência quando encontra uma rotina de declaração de array na qual um dos parâmetros é um ponteiro. Estas mensagens podem ser úteis na detecção de este tipo de conflito.

Se seu banco utiliza arrays locais (arrays reconhecidos unicamente no método no qual foram criados), é necessário declará-los explicitamente em 4D antes de utilizá-los.

Para declarar um array local, utilize um dos comandos de array tais como ARRAY REAL, ARRAY INTEGER, etc.

Por exemplo, se um método cria um array local de inteiros que contém 10 elementos, deve declarar o array antes de utilizá-lo. Utilize o comando:

 ARRAY INTEGER($MeuArray;10)

Get pointer(varName)
Type (object)
EXECUTE FORMULA(statement)
TRACE
NO TRACE

Get pointer é uma função que devolve um ponteiro ao parâmetro que você lhe passou. Suponha que deseja inicializar um array de ponteiros. Cada elemento nesse array aponta a uma variável dada. Suponha que há doze variáveis chamadas V1, V2, …V12. Pode escrever:

 ARRAY POINTER(Arr;12)
 Arr{1}:=->V1
 Arr{2}:=->V2
 
 Arr{12}:=->V12

Também pode escrever:

 ARRAY POINTER(Arr;12)
 For($i;1;12)
    Arr{$i}:=Get pointer("V"+String($i))
 End for

Ao final desta operação, pode obter um array de ponteiros onde cada elemento aponta a uma variável Vi.

Estas duas sequências podem ser compiladas. Entretanto, se as variáveis V1 a V12 não são utilizadas explicitamente em outra parte do banco, o compilador não pode dar-lhes um tipo. Portanto, devem ser utilizadas ou declaradas explicitamente em outra parte.
Esta declaração explícita pode ser realizada de duas formas:

  • Declarando V1, V2, …V12 através de uma diretiva de compilação:
 C_LONGINT(V1;V2;V3;V4;V5;V6;V7;V8;V9;V10;V11;V12)
  • Atribuindo estas variáveis em um método:
 V1:=0
 V2:=0
 
 V12:=0

Como cada variável em um banco compilado tem um só tipo, esta função pode parecer não muito útil. Entretanto, pode ser útil quando trabalha com ponteiros. Por exemplo, pode ser necessário conhecer o tipo da variável a qual o ponteiro faz referencia; devido à flexibilidade dos ponteiros, nem sempre é possível saber a que objeto apontam.

Este comando oferece janelas em modo interpretado que não oferece em modo compilado.
Em modo compilado, um nome de método passado como parâmetro a este comando será interpretado. Portanto, não se beneficia das janelas oferecidas pelo compilador e a sintaxe de seu parâmetro não poderá ser verificada.
Além disso, você não pode passar variáveis locais como parâmetros.
Pode substituir EXECUTE FORMULA por uma série de instruções. Estes são dois exemplos.

Dada a seguinte sequência:

 i:=FormFunc
 EXECUTE FORMULA("FORM SET INPUT(Form"+String(i)+")")

Pode ser substituída por:

 i:=FormFunc
 VarForm:="Form"+String(i)
 FORM SET INPUT(VarForm)

Olhemos este outro exemplo:

 $Num:=SelPrinter
 EXECUTE FORMULA("Print"+$Num)

Aqui, EXECUTE FORMULA pode ser substituída por Case of:

 Case of
    :($Num=1)
       Print1
    :($Num=2)
       Print2
    :($Num=3)
       Print3
 End case

O comando EXECUTE FORMULA pode ser substituído sempre. Como o método a executar se escolhe da lista dos métodos de projeto do banco ou dos comandos de 4D, há um número finito de métodos. Portanto, sempre é possível substituir o comando EXECUTE FORMULA por Case of ou por outro comando. Além disso, seu código se executará mais rápido.

Estes dois comandos são utilizados no processo de depuração. Não tem nenhum objetivo em um banco compilada. Entretanto, pode mantê-los em seus métodos, simplesmente serão ignorados pelo compilador.

Undefined(variable)
SAVE VARIABLES(documento;variable1{; variable2…})
LOAD VARIABLES(documento;variable1{; variable2…})
CLEAR VARIABLE(variable)

Considerando o processo de declaração efetuado pelo compilador, uma variável não pode em nenhum momento indefinida em modo compilado. Na verdade, todas as variáveis foram definidas no momento em que termina a compilação. A função Undefined portanto sempre retorna False, sem importar o parâmetro que seja passado.

Nota: para saber se sua aplicação está correndo em modo compilado, chame o comando Compiled application.

Em modo interpretado, pode verificar que o documento existe provando se uma das variáveis está indefinida depois da execução de LOAD VARIABLES. Isto não é possível em bancos compilados, já que a função Undefined sempre retorna False.

Esta proba pode ser realizada em modo interpretado ou compilado:
1. Inicialize as variáveis que vai  receber em um valor que não seja um valor legal para qualquer das variáveis.
2. Compare uma das variáveis recebidas com o valor de inicialização depois de LOAD VARIABLES.
O método pode ser escrita deste modo:

 Var1:="xxxxxx"
  `"xxxxxx" é um valor que não pode ser retornado por LOAD VARIABLES
 Var2:="xxxxxx"
 Var3:="xxxxxx"
 Var4:="xxxxxx"
 LOAD VARIABLES("Documento";Var1;Var2;Var3;Var4)
 If(Var1="xxxxxx")
  `Documento não encontrado
 
 Else
  `Documento encontrado
 
 End if

Esta rotina utiliza duas sintaxes diferentes em modo interpretado:
CLEAR VARIABLE(variable)
CLEAR VARIABLE("a")
Em modo compilado, a primeira sintaxe de CLEAR VARIABLE(variable) reinicializa a variável (colocada em zero para um numérico; cadeia vazia para um string de caracteres ou um texto, etc.), já que nenhuma variável pode estar indefinida em modo compilado.
Portanto, CLEAR VARIABLE não libera memória em modo compilado, exceto em quatro casos: as variáveis de tipo Texto, Imagem, BLOB e Arrays.
Para um Array, CLEAR VARIABLE tem o mesmo efeito que uma nova declaração do array onde o tamanho se estabelece como zero.

Para um array MeuArray cujos elementos são de tipo Entero, CLEAR VARIABLE(MiArray) tem o mesmo efeito de uma das expressões seguintes:

 ARRAY INTEGER(MiArray;0)
  `sim é um array de uma dimensão
 ARRAY INTEGER(MiArray;0;0)
  `sim é um array de duas dimensões

A segunda sintaxe, CLEAR VARIABLE("a"), não é compatível com o compilador, já que o compilador acessar as variáveis por direção, não por nome.

Os seguintes comandos tem uma característica em comum: aceitam um primeiro parâmetro opcional [Tabela] e o segundo parâmetro pode ser um ponteiro.

ADD TO SETLOAD SET
APPLY TO SELECTIONLOCKED ATTRIBUTES
COPY NAMED SELECTIONORDER BY
CREATE EMPTY SETORDER BY FORMULA
CREATE SETFORM SET OUTPUT
CUT NAMED SELECTIONPAGE SETUP
DIALOGPrint form
EXPORT DIFPRINT LABEL
EXPORT SYLKQR REPORT
EXPORT TEXTQUERY
GOTO RECORDQUERY BY FORMULA
GOTO SELECTED RECORDQUERY SELECTION
GRAPH TABLEQUERY SELECTION BY FORMULA
IMPORT DIFREDUCE SELECTION
IMPORT SYLKRELATE MANY
IMPORT TEXTREMOVE FROM SET
FORM SET INPUT

Em modo compilado, é fácil retornar o parâmetro opcional [Tabela]. Entretanto, quando o primeiro parâmetro passado a um desses comandos é um ponteiro, o compilador não sabe a que ponteiro está fazendo referência; o compilador o trata como um ponteiro de tabela.

Tomemos o caso do comando QUERY cuja sintaxe é a seguinte:
QUERY({tabla{;formula{;*}})
O primeiro elemento do parâmetro formula deve ser um campo.
Se escreve :

 QUERY(PtrField->=True)

o compilador buscará um símbolo que represente um campo no segundo elemento. Quando encontra o signo "=", emitirá uma mensagem de erro, ao não poder identificar o comando com uma expressão que saiba como processar.

Por outro lado, se escrever:

 QUERY(PtrTabla->;PtrCampo->=True)

ou

 QUERY([Tabla];PtrCampo->=True)

evitará qualquer ambigüidade possível.

When using pointers, there is a particularity concerning commands where the first parameter [aTable] and second parameter are both optional. In this context, for internal reasons, the compiler does not allow a command that returns a pointer (for example Current form table) to be passed directly as a parameter (an error is generated).

This is the case, for example, of the FORM SCREENSHOT command. The following code works in interpreted mode but is rejected during compilation:

  //triggers a compilation error
 FORM SCREENSHOT(Current form table->;$formName;$myPict)

In this case, you can just use an intermediate variable in order for this code to be validated by the compiler:

  //equivalent compilable code
 C_POINTER($ptr)
 $ptr:=Current form table
 FORM SCREENSHOT($ptr->;$formName;$myPict)

Se criar seus próprios recursos 4DK# (constantes), tenha certeza de que os numéricos sejam declarados como de tipo Inteiro longo (L) ou Reais (R) e as cadeias de caracteres como Strings (S). Qualquer outro tipo gerará uma advertência.



Ver também 

Dicas de otimização
Guia Digitação
Mensagens de Erro
Usar Diretivas de Compilador

 
PROPRIEDADES 

Produto: 4D
Tema: Compilador

 
HISTÓRIA 

 
ARTICLE USAGE

Manual de linguagem 4D ( 4D v16)
Manual de linguagem 4D ( 4D v16.1)
Manual de linguagem 4D ( 4D v16.2)
Manual de linguagem 4D ( 4D v16.3)