sexta-feira, novembro 10, 2006

Natural/ADABAS - Dicas 1

O Natural é uma linguagem simples, parecida com o Cobol (mas nem tanto poderosa) . Se você conhece o Cobolzão, sabe que tem as redefinições de variável para pegar uma parte em específico e utilizá-la de maneiras variadas. Por rodar embaixo do ADABAS, o Natural tem uma conversa direta com o banco... mas é aquele jeitão de ler os files (tabelas) - READ... FIND.
Bom, se você está lendo isso aqui, provavelmente você trabalha com ele, porque ninguém em sã consciência leria essa postagem de bobeira ;P
Vamos lá!

Alfa para numérico:
Para definir as variáveis usamos DEFINE DATA. Depois dele e antes do END-DEFINE, você põe todas as variáveis que você vai usar, além de LOCALS e GLOBALS com as definições de variáveis dentro delas.
No Natural você tem que dizer o tamanho das variáveis e se elas são alfa-numéricas (A) ou numéricas (N). existem outros tipos, mas vamos ficar por aqui.
Veja um exemplo bobo:
DEFINE DATA
LOCAL
01 #NOME (A30)
01 #TELEFONE (N10)
01 REDEFINE #TELEFONE
02 #DDD-TELEFONE (N02)
02 #NUM-TELEFONE (N08)
01 #TELEFONE-ALFA (A10)
END-DEFINE

De alguma maneira recebemos do usuário pela variável telefone-alfa e o usuário não digita os 10 caracteres pedidos (A10). Fica:
O valor de #TELEFONE-ALFA é '99123456__', com 2 espaços no final.
Nós, humanos, entendemos que o DDD é 99 e o telefone é 123456. Beleza. Mas ao passar o conteúdo para a variável numérica #TELEFONE ficaria com 0099123456. Um conteúdo alfa-numérico é alinhado por padrão para a esquerda preenchendo com espaços, e o numérico para a direita preenchendo com zeros.
Agora imagina a situação de você guardar isso no file e depois quiser pegar só o DDD desse número... vai vir 00; e se pegar o número, vai vir 99123456.
Por isso tome cuidado com a passagem entre variáveis, critique com máscara, valide o conteúdo (o programa pode "abendar" - ABNORMAL END - se passar uma letra para uma variável numérica), cuidado com variáveis em branco que são convertidas para 0 etc.

COMPRESS:
Quando trabalhamos com arquivos de leiaute predefinido, não podemos deslocar nada.. temos que ter o nome com 30 caracteres e pronto... o que sobrar fica lá em branco.
Esse cara junta textos e variáveis em uma variável para o conteúdo final. O comando básico é:
COMPRESS 'TEXTO' #VARIAVEL1 #VARIAVEL2 INTO #VARIAVEL3

ou seja, ele junta 'texto', o conteúdo da variável 1 e da variável 2 e joga na variável 3. Maravilha!
Mas se eu tiver uma variável alfa de tamanho 30 e tiver usado somente 12, os 18 espaços vão ser perdidos pelo COMPRESS. Para juntar com os espaços também, use:
COMPRESS FULL #VAR1 #VAR2 INTO #VAR3

Mesmo assim ocorre outro problema. Ele deixa um espaço entre as variáveis... para isso use:
COMPRESS FULL #VARABACATE #VARMAMAO INTO #VARPERA LEAVING NO SPACE

Ufa! Você pode fazer isso ou criar uma variável de retorno redefinida e jogar os conteúdos nessas redefinições. já apanhei por causa disso...

FIND errado:
O programa com essa find estava consumindo muita CPU:
FIND (1) MINHA-VIEW WITH
SUPER-S3 GE #CHAVE-INICIAL AND
SUPER-S3 LE #CHAVE-FINAL

O programa fazia duas verificações, gerando como se fosse duas listas. O find seguinte resolveu o problema, que passou a utilizar metade dos recursos utilizados pelo primeiro:
FIND (1) MINHA-VIEW WITH
SUPER-S3 EQ #CHAVE-INICIAL THRU #CHAVE-FINAL

Coisinha boba, mas causa um problema quando o programa é bem requisitado....

Um comentário:

Daniel disse...

Comentários do blog em paralelo no wordpress (a desativar)

Gilvandro said 2 weeks ago:

Daniel,

Essa dica sobre COMPRESS matou a charada para um problema que eu encontrava ao concatenar variáveis.

Valeu! Continue com boas dicas como essa.

Renan said 2 weeks ago:

Prezado você poderia me ajudar na sequinte questao?

Tenho uma varialvem teste (A20) , que marmazena um texto que é
teste=’Renan’ gostaria de saber do comando em natural que me retornaria o tamanho ocupado pelo’Renan’ tipo len(teste) = 5

cordialmente,
Renan.

Daniel said 2 weeks ago:

Cara, não conheço uma função assim para Natural, porém o Natural permite a redefinição de uma variável e você pode trabalhar em cima disso:


DEFINE DATA LOCAL
01 #NOME (A20)
01 REDEFINE #NOME
02 #NOME-A (A1/1:20)
01 #INDICE (N02)
01 #TAMANHO (N02)
...
END-DEFINE
...
FOR #INDICE 20 TO 1 STEP -1
IF #NOME-A(#INDICE) NE '' THEN
MOVE #INDICE TO #TAMANHO
ESCAPE BOTTOM
END-IF
END-FOR
...
END

Eu não testei esse código, mas com certeza essa é a lógica para saber o tamanho.
Você deve fazer um FOR de trás para frente e quando você achar a primeira ocorrência de um caractere diferente de vazio ou espaço, essa é a última posição de conteúdo e o tamanho da string preenchida, já que o vetor Natural inicia em 1. Tente algo assim e depois dê um retorno… você pode até criar uma sub-rotina….. aí vai de você!

Abraço!

Renan said 2 weeks ago:

Obrigado pela ajuda amigo! Acho que essa tb da!

EXAMINE #LISTA-CONST-AUX FOR #LISTA-CONST-AUX GIVING LENGTH #TAMANHO