Escolar Documentos
Profissional Documentos
Cultura Documentos
E-mail: __________________________________________________
Profissao: ___. __________________________________________
Salario Pretendido: _______.__
/Telamens
___________________________________________________ _
/Aviso
Este é um exemplo de tela sem
janelas...
/*
//****Exemplo de comentário em Dataflex****
Acima temos o exemplo da declaração de 3 telas em dataflex. Observe que o nome da tela deve
começar com "/" tipo "/Nome_da_tela". A primeira etapa é desenhar as telas, claro que dá pra caprichar
mais do que no exemplo acima e fazer sombra, contorno e se for modo gráfico então nem se fala. Todo
programa começa com as telas e depois vem o simbolo "/*" colocado sempre totalmente a esquerda e
depois das telas pra iniciar o código.
Janelas são chamados os locais de entradas de dados (diferente de janela no windows). Por exemplo
"____.__" é uma janela para entrada numérica de 4 inteiros e dois decimais.
Tipos de janelas:
ASCII: ______________________
São para entradas de dados ascii
Numéricas: _________. Inteiro de 10 digitos no maximo
_________.____ Float de 10 digitos e 4 decimais
___,___.__ Float formatada
Datas: __/__/____ Para entrada de datas tipo dd/mm/aaaa
Observe que é uma boa prática dimensionar a janela com o mesmo tamanho e tipo do campo de
arquivo. Mais tarde voce vera como conectar a janela com seu campo de arquivo respectivo.
Quando voce cria uma tela as janelas tem nomes padrão que depois poderão ser redefinidos. A
nomenclatura funciona assim:
TELA1.1 seria o codigo
TELA1.2 é a primeira janela que corresponde ao nome.
TELA1.3 é o endereço
TELA1.4 é a terceira janela da direita pra esquerda e de cima pra baixo que coresponderia ao codigo da
cidade
TELA1.5 corresponderia ao nome da cidade
TELA1.6 seria a UF ou estado
E assim sucessivamente seguindo a regra: Nome_da_tela.indice_janela
Teriamos Telamens.1 e Telamens.2 na outra tela.
Obseve que nem todas telas tem janelas (pode ser uma tela apenas pra help ou aviso) mas toda janela
tem que estar definida numa tela.
Quando o usuário estiver usando o programa ele inserirá uma informação numa janela em seguida
apertará ENTER e o cursor vai prá janela seguinte pra nova entrada, isto veremos melhor depois.
IMPORTANTE: O simbolos "/" sempre deve estar encostado no inicio da linha quando se referir a
nome de tela ou "/*" inicio de programaçao.
Recomendações:
1-Capriche no layout das telas e procure seguir padrões que seus usuarios ficaram satisfeitos. Evite
telas muito carregadas de janelas e também evite programas com muitas telas pra entrada de dados.
No proximo capítulo veremos um pouco de código, calma...
ACCEPT - aceita uma entrada de tecaldo numa janela, a entrada é terminada com o pressionamento da
tecla enter. Exemplo:
name telamens mens resp
inicio:
<comandos>
move "Dados corretos para gravar? (S/N)" to mens //mosta a mensagem
move "S" to resp //valor padrão da resposta
accept resp {Capslock,check="SN"} //opa isso de capslock falaremos depois
if resp eq "N" goto inicio
<comandos>
abort //fim do programa
AUTOPAGE - pra poder dar entry's sem precisar citar a janela, mas segue a ordem das janelas. EX:
autopage tela1
entry produtos.cod_tipo
entry produtos.cod_produto
entry produtos.desc_produto
...
ASCII - usa-se ascii str to var_int, isto é, obtem o valor inteiro de um caracter ascii e guarda-o numa
variável. Veja CHARACTER.
CHARACTER - var_int to str. Obtem o caracter ascii correspondente ao inteiro e quarda-o numa
variavel string.
CURRENT_WINDOW - variável inteira interna do dataflex que guarda o valor da janela corrente.
CURRENT_IMAGE - variável inteira interna do dataflex que guarda o valor da imagem (tela)
corrente.
ENTDISPLAY - mostra os campos nas janelas com entrys, geralmente após uma busca. Ex:
entry produtos.codigo codigo
entry produtos.desc desc
entry produtos.val_unit val_unit
<comandos>
findkey eq produtos by index.1 ;
for produtos.codigo eq 11135
[ found] entdisplay produtos
ENTERMODE - impede o cusor de voltar pra janelas anteriores a sua chamada. Este comando não
deve ser usado no meior de entrys.
ENTRY - opa este é um comando importante que mostraremos com detalhes nos próximos capítulos.
Ele faz a ligação da janela com o campo de arquivo. Ele da um accept e joga o valor da janela no
buffer.
É usado na macro enter ou entergroup, nunca fora delas!
Exemplo:
ENTRY Produtos.Cod_produto Cod_produto
ENTRY Clientes.Nome Tela1.4 {Capslock}
DELETE - deleta o registro no buffer, se não tiver registro mostra erro.
Usa-se delete nome_arquivo
ENTER - macro enter, proporciona um ambiente completo de entrada de dados, será vista em breve.
ERROR - Da uma mensagem de erro pro usuário com numero e com beep.
Ex: error 200 "Codigo invalido!"
FIND, FINDKEY, SEARCHKEY - São comandos de busca de registros no dataflex que setam found e
finderr após a busca ser efetuada
Exemplos:
(1)
move "P" to clientes.nome //inicializa a chave
find gt clientes by index.2
[ found ] move clientes.codigo to tela1.3
vai mostrar o próximo nome c/valor maior que "P",por exemplo "Patricia Souza"
find pode ser find gt, find ge, find le, find le
(2)
findkey eq produtos by index.1 ;
for produtos.cod_tipo eq 10202 ;
produtos.cod_produto eq "1166665P"
findkey é usado quando o indice é exclusivo e todos campos estão preenchidos
(3)
searchkey ge produtos by index.4 ;
comparing produtos.cod_inter eq cod_inter
searchkey é usado para indices não exclusivos
FINDERR - indicador pré-definido que indica se foi achado registro numa busca. Se não acho finderr =
true. Juntamente com o found é setado após um comando de busca em arquivo
(find,findkey,searchkey).
FOUND - indicador pré-estabelecido que indica se foi achado registro ou não após um comando de
busca tipo find, findkey, searchkey etc. Quando chega no final do arquivo de dados o found = false e
finderr = true.
GOSUB - subrotinas são muito boas pra dar legibilidade e facilitar a manutenção dos seus programas,
infelizmente na versão 2.3 elas não retornam valores, devendo trabalhar sempre com variáveis do tipo
global declarados no inicio do seu programa. Exemplo:
<comandos>
GOSUB Calcula_media
<comandos>
ABORT
//===[ Subrotinas ]====
Calcula_media:
<comandos>
RETURN
Observe que o comando RETURN volta pro ponto logo a seguir a chamada da subrotina com GOSUB.
LEFT, RIGHT e MID - movem parte de dados de um local pra outro. Exemplo:
integer dia mes ano
string strdata 10
move clientes.data_cadastro to strdata
right strdata to ano 4
mid strdata to mes 2 4
left strdata to dia 2
Peceba que left e right usa-se com um parametro que é o tamanho a ser movido e mid tem dois
parametros um o tamanho e o segundo a posição de inicio pra mover. São comandos muito uteis.
INKEY - captura uma tecla do teclado sem precisar apertar enter. Ex:
string letra 1
inkey letra
if letra eq "R" gosub relatorio
INKEY$ - é usado pra capturar teclas em loops, sem parar o loop, é bom pra por em loops muito
demorados pro usuario poder abortar se quizer.Ex:
string letra 1
<comandos>
repeat
<comandos>
inkey$ letra
if letra eq "A" abort
until [ found ]
INSERT - insere uma substring numa string numa posição determinada. Ex.
insert substr IN str AT 04
LENGTH - retorna o tamanho de uma string. Ex: For num from 1 to length(str)
MOVESTR, MOVE - são comandos usados pra mover dados. Só que o movestr move exatamente o
dado sem formatalo.
OPEN e OPEN .. AS - abre arquivo pra leitura/gravação. Se usarmos file_mode podemos abrir só pra
leitura. EX:
open "C:\bdados\meu_arq" as meu_arq
file_mode read_only //==só leitura
OUTFILE - prepara um arquivo ou dispositivo pra ser a saida padrão, fecha com OUTCLOSE. Ex:
outfile "arquiv1.txt"
outfile "LST:", pra impressora
OUTPUT - manda uma tela pra saida padrão que pode ser redirecionada. Ex:
outfile "LST:"
output tela1 //imprime a tela1
outclose
PAGE - mosta uma tela no video, esta embutido em comandos como accept e entry. Ex: page telamens
PAGESET - ajusta uma tela no video. Ex: page set tela1 at 05 06 colors 10 11 o colors é opcional.
PAUSE - faz uma pausa no programa esperando digitação e mostrando uma mensagem pro usuário.
Ex: pause "Pressione tecla para continuar..."
POS - posicao de uma substring numa string tipo pos substr in str to num, o pos seta o indicador found
também. (found = true se achou)
REPLACE - muda o valor de uma substring numa string por outra string, e devolve o valor de found =
true se achou a substring e found = false se não a achou. Exemplos:
move "paula" to str
replace "a" in str with "o" //resulta str="poula"
move "paula" to str
while [ found ]
replace "a" in str with "o
loop
//resulta str= "poulo"
move "paula" to str
replacle "pau" in str with "" //resulta str="la"
REPORT - macro report proporciona grande facilidade pra relatórios, será estudada c/detalhes
posteriormente.
RETURN - volta de um gosub, se usarmos RETURN RETURN volta da subrotina e da rotina que
chamou aquela subrotina (2 níveis).
RUNPROGRAM - excuta um outro programa externo e não dataflex e volta se for acompanhado de
WAIT.Ex:
string programa
move "edit arquivo.txt" to programa
runprogram programa, executa o edit e sai
runprogram wait programa, executa o edit e volta
Se for programa dataflex use CHAIN com ou sem WAIT
move "cad001" to programa
chain programa
chain wait programa
SAVE - salva o registro no buffer, e move os dados do arquivo principal pros arquivos relacionados
secundários salvando-os em seguida. Nunca use save dentro da macro enter ou entergroup, pois os
dados não foram ainda movidos pro buffer. Use-o fora depois do enterend ou depois do endgroup.
SAVERECORD - salva o regitro no buffer mas no caso de arquivos relacionados não move os dados
do arquivo principal pros arquivos relacionados secundários. Ex: SAVERECORD CLIENTES
Não use saverecord dentro de macro enter ou entergroup pelo mesmo motivo do comando save.
SHOW e SHOWLN pra mostrar uma mensagem direto na tela sem janelas.
SUBTOTAL - comando usado na macro report pra totalizar. Será visto mais adinate com detalhes. Ex:
subtotal body.2 to subtotal1.1
WINDOWINDEX - variavel que contém o indice da janela, seu uso facilita muito a programaçao.Ex:
/tela1
___. ___. ___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
/*
<comandos>
move ( mes - 1 ) to windowindex
calc ( valor + tela1.1& ) to tela1.1&
Observe que a windowindex tem que ser acessada usando o simbolo "&", no exemplo acima se o mes é
5 ele acumula o valor na tela1.5
AUTOFIND_GE - sua função é a mesma do autofind só que procura por um valor maior ou igual ao da
janela. Ex:
Exemplo1:
(index1 = nome + sobrenome)
ENTRY FUNCIONARIO.NOME NOME {CAPSLOCK}
ENTRY FUNCIONARIO.SOBRENOME SOBRENOME {CAPSLOCK,AUTOFIND_GE}
FILL - substitui valores em branco. Ex:
print hora_in to hora_in {fill="0"} // 09 em vez de 9...
FORCEPUT - força gravar no buffer do arquivo, usado quando por existencia de muitos autofind o
valor do campo esta sendo destruido no buffer.
FORMAT - é usado geralmente pra formatar grupos de janelas. Quando for colocar entry ou accepts
em loops use format, porque em loops a formatação individual não funciona. Ex:
format tela1.1 thru tela1.10 {capslock}
format hora_in {required,range=8,18}
for windowindex from 0 to 9
accept tela1.1& //nao adianta formatar aqui que não funciona!!!
loop
RETAIN - Mantém os dados na janela, mesmo quando apertado o F9 (key.clear). Pra limpar estas
janelas é preciso apertar duas vezes o F9.
RETAINALL - Os dados jamais serão apagados com F9, apenas usando o comando blankform eles
poderão ser apagados.
SKIPFOUND - é uma opção que aparece normalmente com um autofind ou autofind_ge. Sua função é
se caso seja achado um registro, mostrar os dados na janela e pular pra próxima, sem deixar que ela
possa ser modificada.
***KEYPROCS***
Keyprocs são teclas de atalho associadas a labels e indicadores. O dataflex possui teclas de atalho
padrão que podem ser reprogramadas com o dfsetup. Na versão 2.3 funciona assim:
F1 - key.help - ajuda
F2 - backwind - tela anteriror
F3 - superfind - superbusca
F4 - key.print - impressão
F5 - key.calculte - executa calculos na janela (5+4 retorna 9)
F6 - key.delete - deleta registro
F7 - key.user - voce define
F8 - key.user2 - voce define
F9 - key.clear - limpa tela
F10 - key.save - salvar dados
TAB - find - procura
PGUP - key.previous - registro anterior
PGDOWN - key.next - próximo registro
-> - key.right - seta pra direita
<- - key.left - seta pra esquerda
- key.up - seta pra cima
- key.down - seta pra baixo
ENTER - key.return - confirmação
Na programação no final de tudo colocamos as keyprocs, exemplos:
//====[ definição das keyprocs ]=========
keyproc key.help
page telahelp
pause ""
entagain
return
Keyproc Key.print
gosub imprime_relatorio
return
keyproc key.save //aqui desativamos key.save e o usuario só pode
entagain //salvar registro dando enter nos campos até o fim
return
keyproc key.delete
move "Deseja deletar o registro? (S/N)" to mens
move "N" to resp //defaut
accept resp {capslock,check="SN"}
if resp eq "S" begin
delete arquivo
return entrysec //label da macro enter (próximo capitulo)
end
entagain
return
Obs. O comando KEYPROC OFF desabiluta as keyprocs e KEYPROC ON as habilitam.
Mesmo sem definir estas teclas funcionam automaticamente na macro enter como veremos no próximo
capítulo.
Capítulo 8 - Algumas dicas de dataflex 2.3 e 3.0
//== usando indice por data:
clear arquivo
move data_de to arquivo.dt_cadastro //inicialização opcional
repeat
find gt arquivo by index.3 //supondo indice3 é por data
[ found ] indicate found as arquivo.dt_cadastro le data_ate
[ found ] begin
<comandos>
indicate found true //usado quando o found é alterado no bloco
end
until [ ~found ]
Esta contrução acima é muito usada no dataflex, observe que se chegar no final do arquivo dará
[ ~found ] e sairá do loop automaticamente.
OBS: sempre que voce for ler um arquivo a partir de um certo ponto não esqueça de inicializar a chave,
é muito mais rápido que ler todo o arquivo. Os campos que voce não especificar na inicialização serão
preenchidos com zeros ou string vazia.
//== percorrendo arquivo pelo recnum:
clear arquivo
repeat
find gt arquivo by recnum
[ found ] begin
<comandos>
end
until [ ~found ]
Usar o recnum como indice é muito usado em ferramentas que alteram registros mudando campos que
compõe o indice exclusivo. Lembre que normalmente não é correto ler e gravar novos registros pelo
mesmo indice.
//=== percorrendo arquivo pelo recnum e deletando registros
integer registro
clear arquivo
repeat
find gt arquivo by recnum
[ found ] move arquivo.recnum to registro
[ found ] if data_cad eq "10/10/2002" begin
delete arquivo
move registro to arquivo.recnum //ISTO É NECESSÁRIO!!!
end
until [ ~found ]
Quando voce lê pelo recnum e deleta é preciso salva-lo senão da bug (o recnum volta pro zero), mas
usando outros indices isto nao é necessario.
//=== Salvar o recnum (como no exemplo anterior) é uma técnica muito usada quando voce esta lendo
um arquivo e chama uma subrotina que lê o mesmo arquivo por outro indice. Ex:
integer registro
clear clientes
repeat
find gt clientes by index.1
[ found] begin
...
move clientes.recnum to registro //salva o recnum
gosub novo_loop_do_arquivo //loop no MESMO arquivo
findkey eq clientes by recnum ;
for clientes.recnum eq registro //recupera o recnum
indicate found true //recupera o found
end;
until [~found]
...
novo_loop_do_arquivo:
clear clientes
move data_de to clientes.dt_cad
repeat
find gt clientes by index.2 //indice por data
[ found ] indicate found as clientes.dt_cad le data_ate
[ found ] begin
...
end
until [~found]
return
//=== posicionar no primeiro registro lendo pelo indice 1
clear arquivo
find gt arquivo by index.1
//=== posicionar no ultimo registro
clear arquivo
move 99999999 to arquivo.cod_cli
find lt arquivo by index.1
//=== exportar pra um arquivo texto
integer recs
move 0 to recs
open arquivo
clear arquivo
direct_output "texto.txt"
repeat
find gt arquivo by index.1
[ found ] begin
writeln arquivo.codigo
writeln arquivo.nome
writeln arquivo.data
...
increment recs
show "*" //pra mostrar que ta processando
end;
until [~found]
clearscreen
showln recs " registros exportados"
abort
//=== pra importar de um arquivo texto o código é o mesmo só trocando direct_output por direct_input
e os writeln por readln. Observe que o utilitário READ gera este código automaticamente pra voce.
//=== usar windowindex e fieldindex na mesma expressão
move 0 to fieldindex
for windowindex from 0 to 19
tela1.1& = arquivo1.campo1&
loop
O dataflex distingue o simbolo "&" e percebe quando é windowindex ou fieldindex dependendo se ele
está associado a janela ou campo de arquivo.
//=== usar windowindex com names (muito útil!). Exemplo:
/tela1 //**** matrix 8 X 10 ****
___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
/*
name tela1 val1 val2 val3 val4 val5 val6 val7 val8 val9 val10
// só dou names pra primeira linha
for windowindex from 0 to 79 step 10
accept val1&
accept val2&
accept val3&
...
accept val10&
loop
//=== Criar matrizes e vetores é muito fácil, estas estruturas não existem na linguagem mas podem ser
emuladas com imagens tipo esta do exemplo anterior.
EX:
/vetor_meses
jan fev mar abr mai jun jul ago set out nov dez
___. ___. ___. ___. ___. ___. ___. ___. ___. ___. ___. ___.
Obs: nem todas imagens que voce cria serão mostradas pro usuário, algumas são pra uso interno do
programa.
E-mail: __________________________________________________
Profissao: ___. __________________________________________
Salario Pretendido: ___,___.__
/Telamens
___________________________________________________ _
/Aviso
Este é um exemplo de tela sem
janelas...
/*
//=======[ Inicio da Programação ]===========
//=======[ Includes de arquivos ]============
#include biblioteca.inc
//=======[ Page set das telas ]==============
page set tela1 at 04 03 colors 05 15
page set telamens at 20 00
page set aviso at 06 15
//======[ Abertura de arquivos ]=============
open "empregados" as empregados //***[ Cadastro dos candidatos para vagas
open "cidades" as cidades //***[ Cadastro das cidades
open "profissoes" as profissoes //***[ Cadastro das profissões
//======[ Names das janelas ]================
name tela1 cod_candidato nome_candidato endereco cod_cidade ;
desc_cidade sigla_estado cep data_nasc
name idade ddd_res tel_res ddd_cel ;
tel_cel RG CIC e_mail
name cod_profissao desc_profissao salario
name telamens mens resp
//=========[ definição de variaveis ]=========
integer ultimo
date data
//=========[ page das telas ]=================
//Page tela1 não é necessario pq o entry da page automatico
Page telamens
//=========[ label de inicio ]================
Lb_inicio:
clearform tela1
gosub acha_ultimo
move (ultimo + 1) to cod_candidato
//=========[ inicio da macro enter ]==========
enter empregados
blankform telamens
entry empregados.codigo cod_candidato {autofind,range=1000,50000}
repeat
entry empregados.cic cic
cic_check cic
until [~err]
clear empregados
move 99999999 to empregados.codigo
find lt empregados by index.1
[ found ] move empregados.codigo to ultimo
[~found ] move 0 to ultimo
clear empregados
return
cep_mask:
string str 9 letra 1
integer num //mesmo definindo aqui são variáveis GLOBAIS!
move "" to str
for num from 1 to ( length(cep))
mid str to letra 1 num
if letra ge "0" if letra le "9" append str letra
loop
for num from 1 to ( 8 - length(str))
insert "0" in str at 1
loop
insert "-" in str at 6
move str to cep
return
//========[ definição das keyprocs ]============
Keyproc key.escape
abort
Keyproc key.clear
return lb_inicio
Keyproc key.save
entagain
return
Keyproc key.delete
move "Deseja deletar o registro? (S/N)" to mens
move "N" to resp
accept resp {capslock}
if resp eq "S" begin
delete empregados
return lb_inicio
end
entagain
return
RETURN
ENTER.CLEAR:
//QUANDO LIMPA O BUFFER DO ARQUIVO PRINCIPAL
//ACIONADA PELA KEYPROC KEY.CLEAR
RETURN
ENTER.EXIT:
//QUANDO SAI DA MACRO ENTER
RETURN
ENTEREND
ABORT
A macro enter só pode ser usada uma única vez no programa. Observe que a macro enter é um loop e
as seções enter.save, entry.find e outras são opcionais não precisando ser declaradas quando não vão
ser usadas. Elas podem ser entendidas como sub rotinas padrão da macro enter e são chamadas
automaticamente (parecido com eventos) dependendo do que está acontecendo no programa ou do
pressionameto de keyprocs. Voce pode chama-las explicitamente se quizer tipo com GOSUB
ENTRY.FIND, que as vezes é necessário fazer assim. A macro enter tem alguns indicadores e labels
internos.
ENTRYSEC - label interno da macro enter. Goto entrysec impede que o registro seja gravado.
ENT$QUERY - indicador interno da macro enter que indica se o registro foi alterado. É comum usar
indicate ent$query false antes de autofinds pra evitar bugs em determinados casos.
CONTINUE - indicate continue false impede o loop da macro enter.
ENTER$.DELETE - label pré definido da macro enter, exemplo de uso:
accept resp
if resp eq "S" goto enter$.delete //deleta o registro
Existem outros: ENTER$.SAVE, ENTER$.CLEAR, etc.
RELACIONAMENTOS - Recomendo fazer todos os relacinamentos em tempo de execução usando
comandos de busca em arquivos (find,findkey,searchkey) na entry.find. Dá um pouco mais de trabalho
do que criar relacinamento de arquivos (com o dffile) mas também dá menos dores de cabeça. Lembre-
se: relacionamentos mal feitos geram bugs chatos e difíceis de serem localizados! O relacionamento
funciona do seguinte modo:
Voce cria o relacionamento no DFFILE, relacinando 2 campos iguais, que fazem parte de indices
exclusivos e de arquivos diferentes. Quando voce busca no arquivo o arquivo relacinado traz pro seu
buffer o registro correspondente.
Ex: notasfiscais.cod_cli = relacionado => clintes.cod_cli
e existe indice exclusivo de campo único formado por cod_cli nos 2 arquivos. Quando voce busca um
registro no arquivo de notas fiscais (FILHO) já traz o registro corespondente do arquivo de clientes
(PAI).
USO DE VARIAS MACRO ENTER - As vezes temos programas de ITENS E HEADER (ou itens e
cabeçalho), que são programas que voce cadastra um header e pra ele cadastra vários itens, em arquivos
distintos, tipo o cabeçalho de uma nota fiscal, que tem a razão social da firma, CNPJ, data, numero
nota, endereco, etc. E os items da nota de numero variavel que são os produtos, seus valores unitarios,
valores totais, etc. Como não podemos usar várias macro enter mas apenas uma, fazer este tipo de
programa da forma tradicional é uma coisa chata. Voce poderia usar a entergroup mas também não é o
ideal. O melhor neste caso é trabalhar com dois programas como se fosse um só, usando chain! Aí voce
ficará com uma macro enter pro header, totalmente normal, e o subprograma dos items, com outra
macro enter simples. Pro seu usuário vai parecer que é um programa só, e maior trabalho é passar
alguns parâmetros do programa chamador pro programa filho...
No próximo capítulo falaremos sobre a entergroup.
FALTA CAP 10
/*
//===Abertura arquivos=======
open "setores" as setores //===plasticos, vidros, cosméticos, etc
open "produtos" as produtos
//====Page sets==============
page set tela1 at 05 10
//====Variaveis==============
indicator imp todos
integer num
//====Names de janelas=======
name tela1 setor desc_setor impor copias mens resp
//====Loop principal=========
Inicio:
repeat
blankform tela1
gosub seleciona_dados
for num from 1 to copias
gosub imprime_relatorio
loop
loop
//=====keyprocs==============
keyproc key.escape
abort
keyproc key.clear
return inicio
//=====subrotinas============
Selecina_dados:
repeat
entegroup
entry setores.setor setor {autofind,findreq}
entry setores.desc_setor desc_setor {displayonly}
endgroup
move "N" to impor
accept impor {capslock,check="NIT"}
indicate imp as impor eq "I"
indicate todos as impor eq "T"
move 1 to copias
accept copias {range=1,10}
move "Dados corretos para gerar relatorio?" to mens
move "S" to resp
accept resp {capslock,check="SN"}
until resp eq "S"
return
Imprime_relatorio:
clear produtos
move setor to produtos.cod_setor
//indice.1 = setor + cod_produto
report produtos by index.1 break produtos.setor
[ select ] indicate select as produtos.setor eq setor
[~select ] return end.of.file
[~todos imp] indicate select as produtos.flag_impor eq "I"
[~todos ~imp] indicate select as produtos.flag_impor eq "N"
section header
print pagecount to header.1 {fill="0"}
sysdadte header.2 header.3 header.4
print header.3 to header.3 {fill="0"}
print header.4 to header.4 {fill="0"}
output header
section subheader1
print produtos.cod_setor to subheder1.1
findkey eq setores by index.1 for
setores.setor eq subheader1.1
output subheader1
section body
print produtos.cod_produto to body.1
print produtos.desc_produto to body.2
print produtos.qtd_estoque to body.3
print produtos.val_unit to body.4
output body
section total
print reccount to total.1
output total
reportend
formfeed
outclose
return
//=======fim=================
No próximo capítulo mais exemplos da report.
EXEMPLO1 - Usando a section body pra acumular. Veja esta subrotina que usa a macro report:
IMPRIME_RELATORIO:
CLEAR SCOA233
[ ~TODOS ] MOVE USUARIO TO SCOA233.CODU
[ ~TODOS ] MOVE DATA_DE TO SCOA233.DATA
REPORT SCOA233 BY INDEX.2 BREAK SCOA233.CODU SCOA233.DATA ;
SCOA233.TOT_HS_DECIMAL
[ ~TODOS SELECT ] INDICATE SELECT AS SCOA233.CODU EQ USUARIO
[ ~TODOS SELECT ] INDICATE SELECT AS SCOA233.DATA LE DATA_ATE
[ ~TODOS ~SELECT ] RETURN END.OF.REPORT
[ TODOS ] INDICATE SELECT AS SCOA233.DATA LE DATA_ATE
[ TODOS SELECT ] INDICATE SELECT AS SCOA233.DATA GE DATA_DE
SECTION HEADER
PRINT PAGECOUNT TO HEADER.1
SYSDATE HEADER.2 HEADER.3 HEADER.4
PRINT HEADER.3 TO HEADER.3 {FILL="0"}
PRINT HEADER.4 TO HEADER.4 {FILL="0"}
PRINT DATA_DE TO HEADER.5
PRINT DATA_ATE TO HEADER.6
OUTPUT HEADER
SECTION SUBHEADER1
FINDKEY EQ SGSA004 BY INDEX.1 FOR ;
SGSA004.IDEN EQ SCOA233.CODU
PRINT SGSA004.NOME TO SUBHEADER1.1
FINDKEY EQ FPCE BY INDEX.1 FOR ;
FPCE.CODIGO EQ SCOA233.DEPTO
PRINT FPCE.DESCRICAO TO SUBHEADER1.2
OUTPUT SUBHEADER1
SECTION BODY
PRINT SCOA233.TOT_HS_DECIMAL TO BODY.1 //***Opa! a body não imprime
SECTION SUBTOTAL1 //***ela só acumula...
SUBTOTAL BODY.1 TO SUBTOTAL1.1
RIGHT SUBTOTAL1.1 TO MINUTOS 2
LEFT SUBTOTAL1.1 TO HORAS 3
PRINT HORAS TO SUBTOTAL1.2 {FILL="0"}
MOVE (ROUND ( MINUTOS * 60 / 100)) TO SUBTOTAL1.3
PRINT SUBTOTAL1.3 TO SUBTOTAL1.3 {FILL="0"}
OUTPUT SUBTOTAL1 //***quem imprime é a subtotal
SECTION TOTAL
SUBTOTAL SUBTOTAL1.1 TO TOTAL.1
RIGHT TOTAL.1 TO MINUTOS 2
LEFT TOTAL.1 TO HORAS 3
PRINT HORAS TO TOTAL.2 {FILL="0"}
MOVE (ROUND ( MINUTOS * 60 / 100)) TO TOTAL.3
PRINT TOTAL.3 TO TOTAL.3 {FILL="0"}
OUTPUT TOTAL
REPORTEND
OUTCLOSE
RETURN
EXEMPLO2 - Uma situação que voce quer imprimir varios items pra cada registro, como por exemplo
pra cada nota apacem os items que a compõe no relatório. Voce pode criar loops e subrotinas na report
bem como imprimir imagens sem ser as imagens padrão da report.
EMITE_RELATORIO:
MOVE 0 TO PAGECOUNT
SYSDATE DATAREL HORA MIN
CLEAR SCOLA29
BLANKFORM PRODUTOS
BLANKFORM CONFIRME
REPORT SCOLA29 BY INDEX.4 BREAK SCOLA29.COD_CLIENTE
//***(INDICE.4 = COD_CLIENTE +DATA+ RECNUM)***
[ SELECT] INDICATE SELECT AS SCOLA29.DATA GE DATA_DE
[ SELECT] INDICATE SELECT AS SCOLA29.DATA LE DATA_ATE
SECTION HEADER
OUTPUT HEADER
SECTION BODY
REPEAT
UNTIL [ ~FOUND]
SECTION SUBTOTAL1
SUBTOTAL BODY.5
SECTION TOTAL
SUBTOTAL SUBTOTAL1.1
OUTPUT TOTAL
PRINT CONFIRME.2 TO CONFIRME.2
PRINT CONFIRME.4 TO CONFIRME.4
PRINT CONFIRME.6 TO CONFIRME.6
PRINT CONFIRME.8 TO CONFIRME.8
PRINT CONFIRME.10 TO CONFIRME.10
OUTPUT CONFIRME
REPORTEND
FORMFEED
OUTCLOSE
RETURN
Formulario OK.?.(Y/N).: _
/*
#INCLUDE BIBLIOTE.INC
#INCLUDE TITULO.INC
//===Variaveis
STRING TECLA 1 CEP 9
INTEGER ETIQCORRENTE CONT CONT2
INDICATOR OK
//===Abre arquivo de clientes
OPEN "C:\DF301B\ALAMAR\SCOLA23" AS SCOLA23 //***CLIENTES
//===Redireciona pra impressora padrão
OUTFILE "LST:"
//===Page sets
PAGE SET TELA AT 17 05 COLORS 15 143
INICIO:
PAGE TELA
REPEAT
BLANKFORM TELA
CLEAR SCOLA23
ENTERGROUP
//seleciona um ou então todos clientes
ENTRY SCOLA23.COD_CLIENTE TELA.1 {AUTOFIND}
INDICATE TODOS AS [ ~FOUND]
[ TODOS] BEGIN
MOVE 0 TO TELA.1
MOVE " *** TODOS CLIENTES *** " TO TELA.2
END
ENTRY SCOLA23.FANT_RAZAO_CLI TELA.2 {CAPSLOCK,DISPLAYONLY}
MOVE "S" TO TELA.3
ACCEPT TELA.3 {CAPSLOCK,CHECK="SN"}
INDICATE OK AS TELA.3 EQ "S"
ENDGROUP
//inicializa variaveis
MOVE 1 TO ETIQCORRENTE
MOVE 0 TO PAGEEND //pra não pular de folha no formulario
MOVE 0 TO CONT
UNTIL [ OK ]
BLANKFORM BODY
CLEAR SCOLA23
[ ~TODOS] MOVE TELA.1 TO SCOLA23.COD_CLIENTE //se apenas 1 cliente
REPORT SCOLA23 BY INDEX.1 //***[ INDEX.1 = COD_CLIENTE
[ ~TODOS SELECT ] INDICATE SELECT AS SCOLA23.COD_CLIENTE EQ TELA.1
[ ~SELECT ] RETURN END.OF.REPORT
MOVE (CONT+1) TO CONT
DISPLAY CONT TO TELA.4 //pro usuário ver processando
SECTION BODY
//usa-se windowindex pra facilitar porque são 2 etiquetas
//uma do lado da outra
MOVE (ETIQCORRENTE-1) TO WINDOWINDEX
PRINT SCOLA23.RAZAO_CLI TO BODY.1&
PRINT SCOLA23.ENDER_FAT TO BODY.3&
PRINT SCOLA23.BAIRRO_FAT TO BODY.5&
MOVE ((ETIQCORRENTE-1)*3) TO WINDOWINDEX
PRINT SCOLA23.CEP_FAT_MASC TO BODY.7&
PRINT SCOLA23.CIDADE_FAT TO BODY.8&
PRINT SCOLA23.UF_FAT TO BODY.9&
MOVE ((ETIQCORRENTE-1)*2) TO WINDOWINDEX
IF SCOLA23.CONTATO_FAT NE "" BEGIN
PRINT "ATT: " TO BODY.13&
PRINT SCOLA23.CONTATO_FAT TO BODY.14&
END
ELSE BEGIN
BLANKFORM BODY.13&
BLANKFORM BODY.14&
END
INCREMENT ETIQCORRENTE //proxima etiqueta
IF ETIQCORRENTE GT 2 BEGIN //acabou as etiquetas da linha?
MOVE 1 TO ETIQCORRENTE //posiciona na primeira etiqueta
CALC ( CONT2 + 3 ) TO CONT2
OUTPUT BODY //imprime
MOVE CONT2 TO TELA.5
BLANKFORM BODY // coloca branco nas etiquetas
END
REPORTEND
IF ETIQCORRENTE NE 1 BEGIN
OUTPUT BODY //sobrou alguma etiqueta ? - imprime
IF BODY.1& NE "" MOVE (CONT2+1) TO CONT2
END
FORMFEED
MOVE CONT2 TO TELA.5
OUTCLOSE
PAUSE ""
ABORT
KEYPROC KEY.ESCAPE
ABORT
KEYPROC KEY.CLEAR
BLANKFORM TELA
RETURN INICIO
//---------------
Se fosse uma linha com 3,4 ou mais etiquetas a lógica é a mesma e o uso da windowindex facilita bem.
FALTA CAP 15
integer usuario
clear sysfile
find gt sysfile by recnum
move sysfile.usuario to usuario
if usuario eq 999999 move 0 to usuario
move (usuario + 1) to sysfile.usuario
saverecord sysfile
No final de um relatório o conteudo do temporario é apagado apenas dos registros do usuário que
terminou aquele relatório. Perceba que se não hover quebra no indice por usuário, o temporário
misturará registros gravados por diferentes aplicações.
(3) Campo usuário do sysfile - este é um campo muito util em ambientes multiusuario, que contem um
numero inteiro. Pra cada arquivo temporario a primeira quebra dos indices deve ser o usuário. Porque
assim conseguimos separar os resultados dos relatorios tanto pra consulta dos registros como pra sua
deleção. Lembre que cabe a cada aplicação limpar os registros por ela gravados. Exemplo de rotina:
Limpa_temporario:
gotoxy 20 05
showln "Limpando o temporario..."
clear phtemp
move usuario to phtemp.usuario
repeat
find gt phtemp by index.1
[ found ] indicate found as phtemp.usuario eq usuario
[ found ] delete phtemp
until [ ~found ]
return
(4) Arquivos fantasmas - cria-se com o dffile um arquivo com campos identicos ao original e na
abertura fazemos:
Exemplo:
criamos produtos e produtosfant com o mesmo .def
open "produtos" as produtos
open "produtos" as produtosfant
Isto é muito útil quando queremos ler o arquivo por dois indices diferentes numa mesma rotina.
(5) Estruturação da programação e hidentação do código - isto é bom em qualquer linguagem...
Procure separar o código em gosubs:
/*
page set ...
name ...
open ...
repeat
gosub seleciona_dados
gosub grava_temporario
gosub mostra_grafico
gosub imprime_relatorio
gosub limpa_temporario
loop
keyproc key.escape
abort
hidentação é pra deixar os loop mais visíveis:
subrotina_quaquer:
for cont from 1 to num
repeat
while [ ok]
<comando>
loop
until [~found]
loop
return
Sem hidentação ficaria menos visível e mais dificil a manutenção:
subrotina_quaquer:
for cont from 1 to num
repeat
while [ ok]
<comando>
loop
until [~found]
loop
return
(6) Uso dos indicadores associados as keyprocs. Toda keyproc tem um indicador associado a ela tipo
[ key.save ], [ key.next], [ key.return ] e outros. As vezes precisamos desabilitar as keyprocs e trabalhar
direto com estes indicadores, que indicam se a tecla foi pressionada ou não, mas com a keyproc
desabilitada eles não pulam automaticamente pra rotina da keyproc. Ex:
keyproc off
repeat
<comandos>
[ key.escape ] abort
until [ key.return ]
keyproc on
(7) Criação do efeito hi-ligth, ou seja é tipo uma caixa de seleção do windows ou uma list-box, com
varios items um em cada janela, e voce pressiona seta pra-cima e o hi-ligth vai pro item de cima
deixando ele "selecionado", se voce pressiona seta pra baixo volta pro item de baixo. Ele é feito com
windowindex e screenmode. Se alguem quizer mando esta rotina.
Ufa! por ora acho que este tutorial vai ficar por aqui... Sei que tá faltando coisas mas tenham paciência!
Vou melhorando se surgiirem duvidas.
Duvidas => phbm@webcable.com.br
Esse eh um fonte do jogo torre de hanoi feito em dataflex. Fez sucesso na firma que eu trabalhava
hehehe.
/INICIO
<F1> HELP DO JOGO
/TORRE
ABC
ÚÄ¿ ÚÄ¿ ÚÄ¿
³³³³³³
_______³_³_______ _______³_³_______ _______³_³_______
³³³³³³
_______³_³_______ _______³_³_______ _______³_³_______
³³³³³³
_______³_³_______ _______³_³_______ _______³_³_______
³³³³³³
_______³_³_______ _______³_³_______ _______³_³_______
³³³³³³
_______³_³_______ _______³_³_______ _______³_³_______
³³³³³³
_______³_³_______ _______³_³_______ _______³_³_______
³³³³³³
_______³_³_______ _______³_³_______ _______³_³_______
³³³³³³
³³³³³³
ÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄ
MOVIMENTOS ===> ___.
JOGADA =======> _ PARA _
___________________________________ _
/MATRIZ
_. _. _.
_. _. _.
_. _. _.
_. _. _.
_. _. _.
_. _. _.
_. _. _.
/AUX
_______ _______ _. ___. _
/RECORD
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ºº
º ____________________ voce º
ºº
º conseguiu escrever um novo º
ºº
º RECORD de ___. movimentos º
ºº
º na categoria de _. discos. º
ºº
º Parabens!!! º
ºº
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
/HELP
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º <F6 > Reseleciona opcoes º
º <ESC> Sai do jogo º
º <F9 > Reinicia o jogo º
ºº
º O objetivo e tirar todos º
º discos do cone "A" nunca º
º deixando cone maior sobre º
º cone menor. Aperte ENTER º
º para executar as jogadas. º
º EX: A <ENTER> B <ENTER> º
ºº
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
/VITORIA
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ºº
ºº
º Voce venceu esta º
ºº
º tente outra vez... º
ºº
º Parabens!!! º
ºº
ºº
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
/LINHA
_________________________
_________________________
_________________________
_________________________
_________________________
/RECORDES
MOSTRA_RECORDES:
//***Rotina que le os recordes do arquivo texto torre.dat
DIRECT_INPUT "torre.dat"
FOR WINDOWINDEX FROM 0 TO 4
READLN LINHA.1&
LOOP
OUTCLOSE
LEFT LINHA.1 TO RECORDES.2 4
LEFT LINHA.2 TO RECORDES.4 4
LEFT LINHA.3 TO RECORDES.6 4
LEFT LINHA.4 TO RECORDES.8 4
LEFT LINHA.5 TO RECORDES.10 4
MID LINHA.1 TO RECORDES.1 20 5
MID LINHA.2 TO RECORDES.3 20 5
MID LINHA.3 TO RECORDES.5 20 5
MID LINHA.4 TO RECORDES.7 20 5
MID LINHA.5 TO RECORDES.9 20 5
PAGE RECORDES
GOTOXY 23 28
PAUSE "Tecle algo para continuar..."
RETURN
ESCREVE_RECORDES:
//*****Rotina que grava o arquivo de recordes
INTEGER ANTIGO
KEYPROC OFF
MOVE ( INICIO.1 - 3 ) TO WINDOWINDEX
LEFT LINHA.1& TO ANTIGO 4
INDICATE NOVO_RECORD AS TORRE.64 LT ANTIGO
[ NOVO_RECORD ] BEGIN
MOVE INICIO.2 TO RECORD.1
MOVE TORRE.64 TO RECORD.2
MOVE INICIO.1 TO RECORD.3
PAGE RECORD
PAUSE ""
MOVE "" TO LINHA.1&
PRINT TORRE.64 TO AUX.4 {FILL="0"}
APPEND LINHA.1& AUX.4 INICIO.2
DIRECT_OUTPUT "torre.dat"
FOR WINDOWINDEX FROM 0 TO 4
WRITELN LINHA.1&
LOOP
OUTCLOSE
END
[ ~NOVO_RECORD ] PAGE VITORIA
[ ~NOVO_RECORD ] PAUSE ""
KEYPROC ON
RETURN
INICIA_MATRIZ:
//****Rotina de inicializacao
FOR WINDOWINDEX FROM 0 TO 20
MOVE 0 TO MATRIZ.1&
LOOP
INDICATE FIM FALSE
IF INICIO.1 EQ 7 BEGIN
MOVE 1 TO MATRIZ.1
MOVE 2 TO MATRIZ.4
MOVE 3 TO MATRIZ.7
MOVE 4 TO MATRIZ.10
MOVE 5 TO MATRIZ.13
MOVE 6 TO MATRIZ.16
MOVE 7 TO MATRIZ.19
END
IF INICIO.1 EQ 6 BEGIN
MOVE 1 TO MATRIZ.4
MOVE 2 TO MATRIZ.7
MOVE 3 TO MATRIZ.10
MOVE 4 TO MATRIZ.13
MOVE 5 TO MATRIZ.16
MOVE 6 TO MATRIZ.19
END
IF INICIO.1 EQ 5 BEGIN
MOVE 1 TO MATRIZ.7
MOVE 2 TO MATRIZ.10
MOVE 3 TO MATRIZ.13
MOVE 4 TO MATRIZ.16
MOVE 5 TO MATRIZ.19
END
IF INICIO.1 EQ 4 BEGIN
MOVE 1 TO MATRIZ.10
MOVE 2 TO MATRIZ.13
MOVE 3 TO MATRIZ.16
MOVE 4 TO MATRIZ.19
END
IF INICIO.1 EQ 3 BEGIN
MOVE 1 TO MATRIZ.13
MOVE 2 TO MATRIZ.16
MOVE 3 TO MATRIZ.19
END
RETURN
DESENHA_MATRIZ:
//****Desenha a matriz na tela dependendo do tipo de jogo (3 a 7 discos)
FOR WINDOWINDEX FROM 0 TO 20
IF MATRIZ.1& EQ 1 GOSUB POE1
IF MATRIZ.1& EQ 2 GOSUB POE2
IF MATRIZ.1& EQ 3 GOSUB POE3
IF MATRIZ.1& EQ 4 GOSUB POE4
IF MATRIZ.1& EQ 5 GOSUB POE5
IF MATRIZ.1& EQ 6 GOSUB POE6
IF MATRIZ.1& EQ 7 GOSUB POE7
LOOP
RETURN
MOVIMENTO:
//***Toda a logica do movimento de disco de uma torre p/outra
INDICATE OK AS TORRE.65 NE TORRE.66
[~OK ] RETURN
IF TORRE.65 EQ "A" INDICATE OK AS MATRIZ.19 NE 0
[~OK ] RETURN
IF TORRE.65 EQ "B" INDICATE OK AS MATRIZ.20 NE 0
[~OK ] RETURN
IF TORRE.65 EQ "C" INDICATE OK AS MATRIZ.21 NE 0
[~OK ] RETURN
GOSUB ACHA_ORIGEM
GOSUB ACHA_DESTINO
INDICATE OK AS VALOR_ORIGEM LT VALOR_DESTINO
[~OK ] INDICATE OK AS VALOR_DESTINO EQ 0
[~OK ] RETURN
GOSUB DESENHA_MOVIMENTO
GOSUB VERIFICA_FINAL
PAGE TORRE
CLEARFORM TORRE.65
CLEARFORM TORRE.66
RETURN
VERIFICA_FINAL:
//****Verifica se voce terminou
IF MATRIZ.19 EQ 0 IF MATRIZ.20 EQ 0 INDICATE FIM TRUE
IF MATRIZ.19 EQ 0 IF MATRIZ.21 EQ 0 INDICATE FIM TRUE
RETURN
DESENHA_MOVIMENTO:
//***Desenha o movimento do disco de uma torre p/outra
MOVE ORIGEM TO WINDOWINDEX
MOVE MATRIZ.1& TO AUX.3
MOVE 0 TO MATRIZ.1&
MOVE DESTINO TO WINDOWINDEX
MOVE AUX.3 TO MATRIZ.1&
MOVE ( ORIGEM * 3 ) TO WINDOWINDEX
MOVE TORRE.1& TO AUX.1
MOVE TORRE.2& TO AUX.5
MOVE TORRE.3& TO AUX.2
BLANKFORM TORRE.1&
BLANKFORM TORRE.2&
BLANKFORM TORRE.3&
MOVE ( DESTINO * 3 ) TO WINDOWINDEX
MOVE AUX.1 TO TORRE.1&
[~VER] MOVE "Û" TO TORRE.2&
[ VER] MOVE AUX.5 TO TORRE.2&
MOVE AUX.2 TO TORRE.3&
MOVE ( 1 + TORRE.64 ) TO TORRE.64
PAGE TORRE
RETURN
//****Rotinas auxiliares
ACHA_ORIGEM:
IF TORRE.65 EQ "A" MOVE 0 TO WINDOWINDEX
IF TORRE.65 EQ "B" MOVE 1 TO WINDOWINDEX
IF TORRE.65 EQ "C" MOVE 2 TO WINDOWINDEX
MOVE MATRIZ.1& TO VALOR_ORIGEM
WHILE MATRIZ.1& EQ 0
CALC ( WINDOWINDEX + 3 ) TO WINDOWINDEX
MOVE MATRIZ.1& TO VALOR_ORIGEM
LOOP
MOVE WINDOWINDEX TO ORIGEM
RETURN
ACHA_DESTINO:
IF TORRE.66 EQ "A" MOVE 18 TO WINDOWINDEX
IF TORRE.66 EQ "B" MOVE 19 TO WINDOWINDEX
IF TORRE.66 EQ "C" MOVE 20 TO WINDOWINDEX
MOVE 0 TO VALOR_DESTINO
WHILE MATRIZ.1& NE 0
MOVE MATRIZ.1& TO VALOR_DESTINO
CALC ( WINDOWINDEX - 3 ) TO WINDOWINDEX
LOOP
MOVE WINDOWINDEX TO DESTINO
RETURN
POE7:
MOVE WINDOWINDEX TO WIND
CALC ( WINDOWINDEX * 3 ) TO WINDOWINDEX
MOVE "ÛÛÛÛÛÛÛ" TO TORRE.1&
[~VER] MOVE "Û" TO TORRE.2&
[ VER] MOVE "7" TO TORRE.2&
MOVE "ÛÛÛÛÛÛÛ" TO TORRE.3&
MOVE WIND TO WINDOWINDEX
RETURN
POE6:
MOVE WINDOWINDEX TO WIND
CALC ( WINDOWINDEX * 3 ) TO WINDOWINDEX
MOVE " ÛÛÛÛÛÛ" TO TORRE.1&
[~VER] MOVE "Û" TO TORRE.2&
[ VER] MOVE "6" TO TORRE.2&
MOVE "ÛÛÛÛÛÛ " TO TORRE.3&
MOVE WIND TO WINDOWINDEX
RETURN
POE5:
MOVE WINDOWINDEX TO WIND
CALC ( WINDOWINDEX * 3 ) TO WINDOWINDEX
MOVE " ÛÛÛÛÛ" TO TORRE.1&
[~VER] MOVE "Û" TO TORRE.2&
[ VER] MOVE "5" TO TORRE.2&
MOVE "ÛÛÛÛÛ " TO TORRE.3&
MOVE WIND TO WINDOWINDEX
RETURN
POE4:
MOVE WINDOWINDEX TO WIND
CALC ( WINDOWINDEX * 3 ) TO WINDOWINDEX
MOVE " ÛÛÛÛ" TO TORRE.1&
[~VER] MOVE "Û" TO TORRE.2&
[ VER] MOVE "4" TO TORRE.2&
MOVE "ÛÛÛÛ " TO TORRE.3&
MOVE WIND TO WINDOWINDEX
RETURN
POE3:
MOVE WINDOWINDEX TO WIND
CALC ( WINDOWINDEX * 3 ) TO WINDOWINDEX
MOVE " ÛÛÛ" TO TORRE.1&
[~VER] MOVE "Û" TO TORRE.2&
[ VER] MOVE "3" TO TORRE.2&
MOVE "ÛÛÛ " TO TORRE.3&
MOVE WIND TO WINDOWINDEX
RETURN
POE2:
MOVE WINDOWINDEX TO WIND
CALC ( WINDOWINDEX * 3 ) TO WINDOWINDEX
MOVE " ÛÛ" TO TORRE.1&
[~VER] MOVE "Û" TO TORRE.2&
[ VER] MOVE "2" TO TORRE.2&
MOVE "ÛÛ " TO TORRE.3&
MOVE WIND TO WINDOWINDEX
RETURN
POE1:
MOVE WINDOWINDEX TO WIND
CALC ( WINDOWINDEX * 3 ) TO WINDOWINDEX
MOVE " Û" TO TORRE.1&
[~VER] MOVE "Û" TO TORRE.2&
[ VER] MOVE "1" TO TORRE.2&
MOVE "Û " TO TORRE.3&
MOVE WIND TO WINDOWINDEX
RETURN
//***********************************
//***JOGO FEITO POR PAULO MIRANDA ***
//***E-MAIL: PHBM@WEBCABLE.COM.BREste endereço de e-mail está protegido contra
spambots. Você deve habilitar o JavaScript para visualizá-lo. ***
//***********************************
Exemplo de um codigo usando a macro enter para fazer um cadastro. O arquivo deve ser salvo com a
extendão ".frm".
/TELA2
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ºº
º EMPRESA : __. º
ºº
º RAZAO : ________________________________________ º
ºº
º FANTASIA : ___________ º
ºº
º CGC : __________________ IE : ____________________ º
ºº
ºÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ĺ
ºº
º ENDERECO : ________________________________________ º
ºº
º BAIRRO : _______________ º
ºº
º MUNICIPIO : ______________________ UF : __ º
ºº
º CEP : _________ º
ºº
ºÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ĺ
ºº
º DDD : _____ FONE : __________ FAX : __________ º
ºº
º EMAIL : ______________________________ º
ºº
ºÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ĺ
ºº
º DATA CAD. : __/__/____ DT.ULT.ALT : __/__/____ º
ºº
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
/RESP
_
/AUX
_____________. __________. ___0___.
/CEP
_______.
/TELAHELP
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º TELA DE HELP º
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
º <SHIFT+F4> Imprime <F5> -> Limpa Tela º
º <SHIFT+F2> Exclui <F2> -> Grava º
º <F8> Ä> Proximo Reg. <F7> -> Reg. Anterior º
ºº
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
/TELAIMP
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Û ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Û
Û ³ÛÛÛÛÛÛÛ MODO DE IMPRESSAO ÛÛÛÛÛÛ ³ Û
Û ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ´ Û
Û ³ Codigo da Impressora ³ _. ³ Û
Û ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄ´ Û
Û ³ ______________________________ ³ Û
Û ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ Û
Û ³ Formulario Ok? <___> <___> ³ Û
Û ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Û
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
/*
//==========================[ INCLUSAO DE BIBLIOTECAS ]
=========================
#INCLUDE TITULO.INC
#INCLUDE BIBLIOTE.INC
LB_ENTRA_TELA2:
BLANKFORM TELA2
MOVE "" TO RESP.1
CLEAR SCOLA24
ENTRY SCOLA24.EMPRESA EMPRESA {AUTOFIND}
[ ~FOUND] BLANKFORM TELA2.2 THRU TELA2.16
INDICATE EXISTE STATUS SCOLA24
ENTRY SCOLA24.RAZAO_EMPRESA RAZAO_EMPRESA {CAPSLOCK}
ENTRY SCOLA24.FANT_EMPRESA FANT_EMPRESA {CAPSLOCK}
LB_CGC:
INDICATE OK TRUE
ENTRY SCOLA24.CNPJ CNPJ
FOR CONT FROM 1 TO 18
MID CNPJ TO NUMERO 1 CONT
INDICATE OK AS NUMERO IN "0123456789 ./-"
[~OK] INDICATE OK AS NUMERO EQ ""
LOOP
[ OK ] CGC_CHECK CNPJ
[~OK ] BEGIN
MENSA "CARACTERES INVALIDOS NO CGC!!"
PAUSE ""
MENSA " "
END
[~OK ] GOTO LB_CGC
[~ERR] GOSUB LB_CNPJ_MASC
[ ERR ] BEGIN
MENSA "CGC INVALIDO,DIGITE OUTRA VEZ !!"
PAUSE ""
MENSA " "
END
[ ERR] GOTO LB_CGC
LB_CONFIRMA:
MENSA " DADOS CORRETOS S/N ? "
MOVE "S" TO RESP.1
ACCEPT RESP.1 {CAPSLOCK,CHECK="SN "}
MENSA " "
IF RESP.1 EQ "N" GOTO ENTRYSEC
RETURN
ENTEREND
ABORT
KEYPROC KEY.ESCAPE
ABORT
KEYPROC KEY.SAVE
IF FONE EQ "" BEGIN
MENSA "NAO DEIXE CAMPOS EM BRANCO!"
PAUSE ""
MENSA " "
RETURN
END
RETURN LB_CONFIRMA
KEYPROC KEY.DELETE
MENSA "TECLA DE DELETAR DESATIVADA"
PAUSE ""
MENSA " "
RETURN
KEYPROC KEY.PRINT
MENSA "TECLA DE IMPRIMIR DESATIVADA"
PAUSE ""
MENSA " "
RETURN
//--------
//
LB_CNPJ_MASC:
REPLACE "." IN CNPJ WITH ""
REPLACE "." IN CNPJ WITH ""
REPLACE "/" IN CNPJ WITH ""
REPLACE "-" IN CNPJ WITH ""
PRINT CNPJ TO AUX.1 {FILL="0"}
MOVESTR AUX.1 TO CNPJ
INSERT "." IN CNPJ AT 3
INSERT "." IN CNPJ AT 7
INSERT "/" IN CNPJ AT 11
INSERT "-" IN CNPJ AT 16
RETURN
LB_CEP_MASC:
PARAMETROS DE SELE€ŽO
ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
³³³³
Per¡odo ..........: ³ __/__/____ ³ at‚ ³ __/__/____ ³
³³³³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
³³
C¢digo do Produto : ³ _____. ³ ( <Enter> p/ Todos )
³³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
80 COL.
/HEADER RESIDENT
ALAMAR Tecno Cient¡fico Ltda
|=========|====================================================|
==================|
| SCOLR8 | RELA€ŽO DE ENTRADA E SAIDA DOS | P gina: ___. |
|* BRUNO *| MATERIAIS DIVERSOS | __/__/____ __:__ |
|=========|====================================================|
==================|
|---------------------------------------------------------------+----------------------------------
+-------------------------------------|
||ENTRADA|SAIDA|
|CODIGO DESCRI€ŽO |----------------------------------|-------------------------------------|
| | N§ Ped. | Qtde. | Data | Dep. Dest. | Qtde. | Data |
|---------------------------------------------------------------|---------|---------|--------------|------------|---------|----
----------|
/BODY
|_____. _______________________________________________________| _____. | ____.__ |
__/__/____ | __________ | ____.__ | __/__/____ |
/TOTAL RESIDENT
||||||||
|
=========================================================================
===============================================================|
| T O T A I S .............................................. | | ____.__ | | | ____.__ | |
|
=========================================================================
===============================================================|
/*
//*************[ COMANDOS P/ CHAMAR A TELA ALAMAR E A PARTE GRAFICA ]******
GRAPHIC ON 3
#INCLUDE TITULO.INC
TITULAR "SCOLR8 - ENTRADA E SAIDA DOS MATERIAIS DIVERSOS"
//***************************************************************************
//*************[ ABERTURA DE ARQUIVOS ]************************************
OPEN "SCOLA18" AS SCOLA18 //---[ ENTRADA/SAIDA PRODUTOS ESTOQUE ]*
OPEN "SCOLA12" AS SCOLA12 //---[ MATERIAL DE ESCRITORIO ]*********
//***************************************************************************
//*************[ NOMES AS JANELAS DA TELA ]****************************
NAME TELA DATA_INI DATA_FIN CODIGO
//***************************************************************************
//*************[ PAGE DAS TELAS ]************************************
PAGE SET TELA AT 18 11 COLORS 31 112
PAGE SET RESP AT 54 50 COLORS 31 143
//***************************************************************************
//*************[ DEFINICAO DAS VARIAVEIS ]**************************
INDICATOR TODOS
//*************[ INICIO DA PROGRAMACAO ]***************************
//
LB_SELECAO:
ENTERGROUP
GOSUB LB_MONTA_TELA
SCREENMODE 31
GOTOXY 54 03
SHOW " "
BLANKFORM TELA
MOVE 0 TO PAGECOUNT
REPEAT
ACCEPT DATA_INI {RANGE=01/01/1900,31/12/2020}
GOTOXY 54 03
SHOW " "
SECTION HEADER
PRINT PAGECOUNT TO HEADER.1
SYSDATE HEADER.2 HEADER.3 HEADER.4
IF HEADER.3 LT 10 INSERT "0" IN HEADER.3 AT 1
IF HEADER.4 LT 10 INSERT "0" IN HEADER.4 AT 1
OUTPUT HEADER
SECTION BODY
BLANKFORM BODY
OUTPUT BODY
SECTION TOTAL
SUBTOTAL BODY.4 TO TOTAL.1
SUBTOTAL BODY.7 TO TOTAL.2
OUTPUT TOTAL
REPORTEND
FORMFEED
GOTO LB_SELECAO
ABORT
//*************[ FIM DA MACRO REPORT ]*****************************
//*************[ DEFINICAO DAS TECLAS DE FUNCAO ]****************
KEYPROC KEY.ESCAPE
GRAPHIC OFF
ABORT
KEYPROC KEY.CLEAR
BLANKFORM TELA
ENTAGAIN
RETURN LB_SELECAO
//*************[ FIM DA DEFINICAO DAS TECLAS DE FUNCAO ]*****
//*************[ SUB-ROTINAS USADAS NO PROGRAMA ]************************
//
LB_MONTA_TELA:
PAGE TELA
SET_LINE_STYLE 1 3
GRXY 134 665 // ESQUERDA E BAIXO
LINE 877 665 0 // DIREITA E BAIXO
LINE 877 298 0 // DIREITA E CIMA
LINE 134 298 15 // ESQUERDA E CIMA
LINE 134 665 15 // ESQUERDA E BAIXO
RETURN
//*************[ FIM DA PROGRAMACAO ]********************************