Você está na página 1de 69

DATAFLEX

Captulo 1- Introduo ao Dataflex O Dataflex uma linguagem de programao e acesso a banco de dados (tambm Dataflex), voltada para o desenvolvimento rpido de arquivos de dados e ferramentas de consulta, cadastro, relatrios, e muitas outras voltadas a esta base de dados. Suas principais vantagens so a facilidade de desenvolvimento de aplicativos com grande portabilidade para diferentes sistemas operacionais (Windows, DOS, Unix, AIX, Linux, Solaris,etc), bastando apenas a recompilao dos arquivos fontes. Para os usarios do sistema exitem as vantagens da facilidade de uso, rapidez de cadastro, velocidade e confiabilidade no acesso aos dados, interface agradvel podendo ser grfica ou modo texto. Existe o Visual Dataflex para windows, mas nesta apostila falaremos apenas do dataflex para DOS e UNIX verses 3.0 e 2.3 usando lgica de programao procedural (a 3.0 suporta P.O.O. e procedural). Com o dataflex vem diversos aplicativos, eis os principais deles que sero explicados com maiores detalhes mais adiante: DFCOMP - Compilador dataflex que compila o arquivo texto de extenso (.FRM por padro) para um arquivo executvel de extenso .FLX. Usa-se DFCOMP <nome do programa + extenso>. DFRUN - Executa um programa dataflex. Note que o FLX no pode rodar sozinho precisa do programa dfrun para poder executar. Um programa dataflex s funciona numa mquina que tenha pelo menos instalado o run-time do dataflex. Mas se a empresa precisa frequentemente mexer nos programas ai vai precisar do dataflex verso desenvolvedor (completo e mais caro).Usa-se: DFRUN <nome do programa sem extenso> DFFILE - Usado para criar arquivos de dados (.DAT) , arquivos de indices (.K1,.K2,etc) e tambm relacionamentos. Com este utilitrio voce cria todos os campos do arquivo e depois cria os indices. Voce tambm pode gerar arquivo de dados (vazio claro!) tambm a partir de definies de arquivos (.DEF) que so arquivos textos. DFQUERY - Consultas rpidas a arquivos. Voce v a estrutura do arquivo, campos, indices, quantidade de registros e pode selecionar padres de consulta comparando um ou vrios campos com faixas de valores que voce fixa (semelhante a clasula where do SQL). As consultas podem ser direcionadas para arquivos texto, vdeo ou impressora e podem ser ordenadas por um indice opcionalmente. muito usado este utilitrio na exportao (gerando arquivo texto) e conferncia dos dados. READ - importa arquivos textos pra arquivo de dados em formatos separados por linhas ou ponto e virgla. usado para gerar programas de importao de dados. ENTERDEF - Gera executveis de entrada de dados com macro enter automaticamente a partir de arquivos texto de definio de arquivo(.DEF) DFINDEX - Ferramenta para reindexar arquivos de dados. DFSETUP - Utilitrio para alterar configuraes internas do dataflex. AUTODEF - utilitrio pra se criar uma aplicao de cadastro (macro enter) atravs de uma imagem. MENUDEF - usado pra se criar menus e sub-menus. Ex: menu pricipal, menu da expedio, menu da vendas, etc. Note que o banco de dados dataflex (verses 3.0 e 2.3) no relacional. Para um nico arquivo de

dados (.DAT) criado so criados alguns arquivos adicionais como indices(.K1,.K2,.K3,etc) definio de arquivo(.DEF), "apelidos" de campos de arquivos usados na compilao (.FD), arquivo de dados compactado da verso 3.0 (.VLD), arquivo de nomes de campos de arquivos (.TAG). Veremos adiante mais detalhes sobre estes arquivos. Tenha em mente que o dataflex uma exelente ferramenta multi-sistema operacinal, com grande confiabilidade e velocidade de acesso. Eu trabalhei alguns anos com esta linguagem num ambiente Unix com servidor RISC da IBM com a verso 2.3 com terminais e micros emulando terminias numa firma de grande volume de cadastros e consultas, com cerca de 100 usurios, 500 arquivos alguns com quase 1 milho de registros e nunca tive problemas srios com arquivos (bom o RISC ajudou muito...). Os problemas que raramente ocorreram foram nada que no pudesse ser resolvido com simples reindexao de arquivo. Bom ai quem gosta de horas-extras em CPD vai preferir outras tecnologias "modernas"... No dataflex voce trabalha com um registro por vez do arquivo em disco que lido no buffer do arquivo (na memria) e do buffer pra tela, segundo o esquema abaixo: TELA(Campos de entrada ou janelas) <=> buffer do arquivo <=> arquivo disco Quando voce edita ou grava um registro voce esta fazendo isto na tela mas atravs de um comando (entry) que ja tambem edita o buffer e depois no final da entrada ou edio vem a gravao fsica dos dados no HD. Isto a nvel do usurio muito pratico porque ele vai colocando os dados e apertando enter at receber uma mensagem de confirmao (opcional) e com novo enter grava os dados. As busca por valores so extremamente simples tambm. O usurio preenche uma entrada parcialmente (desde que ele faa parte de um indice) e aperta F8 ou TAB e j vem o registro mais prximo para a tela que esta pronto pra ser editado. Aps a edio de um campo aperta F10 e salva os dados ou aperta F9 e limpa a tela tudo sem a lentido do mouse. Voce j percebeu como lento cadastrar procurando os campos com o mouse? Ou como complicado usar aquelas barras de navegao com inmeros botes, tipo o dbnavigator do delphi? Pro usurio o dataflex permite uma enorme facilidade e desempenho tanto no cadastro, na edio e na busca por registros. Outra vantagem so a versatibilidade da linguagem que permite relatrios de qualquer tipo e tambm grficos na tela ou impressos, alm de leitura e impresso de cdigo de barras. Bom com o decorrer do tempo voce ver como o dataflex uma tima ferramenta com grande produtividade e aceitao pelos usurios! I see you later!

Captulo 2 - Criando a base de dados O utilitrio para criao e edio de arquivos o DFFILE. Assim o primeiro passo para a criao de um programa verificar quais arquivos ele vai usar e com o dffile imprimir uma listagem de cada arquivo. A listagem de um arquivo impressa (que o .DEF do arquivo) fica mais ou menos assim: ----------------------------------------------------------------------------DATA: 28/05/2002 HORA: 14:50 PAGINA: 1 DEFINICAO PARA O ARQUIVO: PRODUTOS (# 4) ----------------------------------------------------------------------------NOME BASE : PRODUTOS NOME PARA USUARIO : PRODUTOS NOME PARA DATAFLEX : PRODUTOS ----------------------------------------------------------------------------TAMANHO DO REGISTRO : 256 (USADO: 178 )

No. MAXIMO DE REGISTROS : 16711679 (USADO: 12520) COMPRESSAO DO ARQUIVO : Rapida REUTILIZAR ESPACOS EXC. : Sim RELEITURA MULTI-USUARIA : Sim ----------------------------------------------------------------------------NUM NOME DO CAMPO TIPO TAM OFFST IN RELACIONA AO ARQUIVO.CAMP --- --------------- ---- ----- ----- -- --------------------------------1 COD_TIPO NUM 6.0 1 1 TIPOS.CAMPO_1 (2,1) 2 COD_PRODUTO ASC 12 4 1 3 DESC_PRODUTO ASC 40 16 2 4 FLG_INATIVO ASC 1 56 5 ESTOQUE_ATUAL NUM 6.2 57 6 ESTOQUE_MINIMO NUM 6.2 61 7 ESTOQUE_MAXIMO NUM 6.2 65 8 PRECO_ATUAL NUM 8.2 69 9 PRECO_MINIMO NUM 8.2 74 10 VALOR_IPI NUM 4.2 79 11 EMBALAGEM ASC 10 82 12 UNIDADE ASC 20 92 13 CONSER ASC 9 112 14 PESO_LIQ NUM 4.4 121 15 COD_FISCAL ASC 14 125 16 DT_CAD DAT 3 139 17 DT_ULT_ALT DAT 3 142 18 QUANT_PEND NUM 6.2 145 19 COD_INT NUM 10.0 149 4 20 REF_INT ASC 15 154 21 FLG_IMPORTADO ASC 1 169 22 FORN1 NUM 6.0 170 23 FORN2 NUM 6.0 173 24 FORN3 NUM 6.0 176 INDIC# CAMPOS DES MAI TAMANHO NIVEIS SEGMENTO MODO ------ --------------- --- --- ------- ------ -------- ------1 COD_TIPO Nao Nao 18 5 2 On line COD_PRODUTO Nao Nao 2 COD_TIPO Nao Nao 46 7 3 On line DESC_PRODUTO Nao Nao RECNUM Nao Nao 3 COD_PRODUTO Nao Nao 15 5 2 On line RECNUM Nao Nao 4 COD_INTER Nao Nao 8 5 2 On line RECNUM Nao Nao

Bem acima est a data e hora de criao do arquivo. Depois vem sua posio no FILELIST que um numero que corresponde geralmente a ordem de criao do arquivo e que o dataflex utiliza internamente, junto com o numero do campo. Com relao aos campos temos o numero do campo que sequencial, depois o nome do campo, depois o tipo do campo, seu tamanho, a posio, o indice a qual ele faz parte e finalmente a qual outro campo de outro arquivo que ele est relacionado. O Filelist mais ou menos assim: 1 - Produtos - arq001 2 - Unidades - arq002 3 - Embalagens - embs01 etc... Existem os seguintes tipos de campos de arquivo: ASCII - alpha-numrico ou string ate 255 caracteres NUM - numricos que pode ser inteiro ou ponto flutuante. Exemplo: COD_INT NUM 10.0 inteiro de dez dgitos tipo 1020400231 PRECO_ATUAL NUM 8.2 float de 8 dgitos na parte inteira e 2 decimais tipo 12560,50 DATE - campos para data no formato "dd/mm/aaaa" TEXT - campo para texto sem formatao (na verso 2.3 no existe) BLOB - campo para grandes objetos tipo fotos (na verso 2.3 no existe) OVERLAP - campo de juno de campos usado para diminuir o tamanho de indices Logo depois dos campos vem as informaes sobre indices. No caso acima o indice 1 exclusivo porque no aparece nele o recnum. Quando voce deseja tirar a exclusividade de um indice acrescente no final dele o recnum. RECNUM um campo tipo numero inteiro (>0) que corresponde geralmente a ordem de criao do registro, tipo o primeiro registro gravado tem recnum= 1 o segundo registro gravado tem recnum= 2 e assim por diante. O recnum um campo que sempre existe num arquivo e tem valor exclusivo. Mesmo se um arquivo for criado sem indices o recnum pode ser usado como indice. Quando voce deleta um registro aquele recnum reutilizado pelo dataflex numa futura insero de registro. Em arquivos onde no se deleta registros o recnum pode ser usado como um cdigo sequencial exclusivo. Bom falamos no caso do arquivo j estar criado. Se no existir o arquivo que voce quer muito fcil cria-lo usando o DFFILE, porque ele um utlitario que cria tudo passo a passo sem codificao. Recomendaes: 1-Use nome de campos claros tipo COD_PRODUTO e nao CPR, vai te facilitar a vida e dos outros programadores. 2-Use o mesmo nome do campo em diferentes arquivos, exemplo: PRODUTOS.COD_PRODUTO e MOVIMENTOS.COD_PRODUTO pois tambm facilita! 3-Procure colocar os campos principais que faro parte do indice principal no comeo do arquivo na mesma ordem que vo aparecer no indice. 4-Evite indices com muitos campos grandes, use overlaps. 5-Crie indices inteligentes e s os crie na medida da necessidade.

6-No duplique informao desnecessariamente gravando a mesma informao em dois arquivos, normalize os arquivos. 7-No crie muitos indices exclusivos prefira indices no exclusivos. 8-Lembre que o FILELIST comporta 255 arquivos no crie arquivos desnecessariamente. 9-Crie os arquivos que no existem, imprima as definies de todos os arquivos que sero abertos no programa e s ai comece a programar.

Captulo 3 - Telas de um programa dataflex (procedural) //************************************** //programa P-001 //sistema: agencia de empregos //finalidade: cadastro de profissionais //feito por Paulo Miranda 17/01/2003 //atualizado por Simone 25/02/2003 //************************************** /Tela1 Codigo: _________. Nome: __________________________________________________ Endereco: __________________________________________________ Cidade: ___. _____________________________ UF: __ CEP: _________ Data Nasc: __/__/____ Anos: _. Res: (__.) _________ Cel: (__.) _________ RG: _______________ CIC: _______________ E-mail: __________________________________________________ Profissao: ___. __________________________________________ Salario Pretendido: _______.__ /Telamens ___________________________________________________ _ /Aviso Este um exemplo de tela sem janelas... /* //****Exemplo de comentrio em Dataflex****

Acima temos o exemplo da declarao de 3 telas em dataflex. Observe que o nome da tela deve comear 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 grfico ento nem se fala. Todo programa comea com as telas e depois vem o simbolo "/*" colocado sempre totalmente a esquerda e depois das telas pra iniciar o cdigo. Janelas so chamados os locais de entradas de dados (diferente de janela no windows). Por exemplo "____.__" uma janela para entrada numrica de 4 inteiros e dois decimais. Tipos de janelas: ASCII: ______________________ So para entradas de dados ascii Numricas: _________. 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 prtica 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 padro que depois podero ser redefinidos. A nomenclatura funciona assim: TELA1.1 seria o codigo TELA1.2 a primeira janela que corresponde ao nome. TELA1.3 o endereo 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 usurio estiver usando o programa ele inserir uma informao 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 programaao. Recomendaes: 1-Capriche no layout das telas e procure seguir padres que seus usuarios ficaram satisfeitos. Evite telas muito carregadas de janelas e tambm evite programas com muitas telas pra entrada de dados. No proximo captulo veremos um pouco de cdigo, calma...

Capitulo 4- Comeando a programar

No capitulo anterior fizemos as telas do nosso primeiro programa. Agora vamos comear a codificar. Logo aps o simbolo "*\" comearemos cdigo: /* //=======[ Inicio da Programao ]=========== // Usa-se barra barra para comentrio! //=======[ Includes de arquivos ]============ #include biblioteca.inc #include fmar.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 profisses At aqui parece que d pra entender no ? INCLUDE para incluir bibliotecas com seus prprios comandos. Falaremos como criar comandos depois. PAGE SET o comando que posiciona a tela no vdeo. Aqui estamos usando modo texto de 80 colunas X 25 linhas. OPEN pra abrir o arquivo e AS opcional. Depois vem: //======[ 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 Esta parte de names opcional mas bom sempre colocar, procurando colocar o nome da janela igual o nome do campo de arquivo. Observe que isto ir facilitar a programao mas a janela pode ter o nome que voce quizer menos nome de comando ou palavras reservadas do dataflex. Se voce bom observador precebeu que coloquei name tela1 na primeira linha e depois acaba com ponto e vrgula. O ponto e virgula pra string no dataflex continuar na outra linha. O comando name aceita uma string com um mximo de 255 caracteres por isso depois eu coloco outro NAME pras prximas janelas pra no estourar o tamanho da string de comando, observando que no repito o nome da tela porque o dataflex entende que estou me referindo a tela1. Se eu no colocar names nas janelas quando precisar inserir uma janela ser necessrio varias alteraes no programa. Observe: Se no tenho names os nomes padro ficam tela1.1, tela1.2, tela1.3 at tela1.19. Imagine que eu queira

inserir uma nova janela entre tela.4 e tela.5, esta janela passar a ser a tela.5, a tela.5 passa ser a tela.6 e assim por diante. Como no dataflex muitos comandos fazem referencias a nomes de janelas se eu tiver muito cdigo no programa precisarei fazer muitas alteraes porque na insero da tela.5 nova todas as janelas seguintes mudaram seu names. Ento USE SEMPRE NAMES! Vamos continuar com nosso programa exemplo: //=========[ definio de variaveis ]========= integer num cont number valor preco_unitario string linha letra 1 frase 20 ; outra_linha date data data2 indicator ok existe //============================================ TIPOS DE VARIAVEIS NO DATAFLEX: INTEGER - Numero inteiro positivo ou negativo na faixa de +/- 2,147,483,647. NUMBER - Numero com ponto flutuante tipo o float do C. STRING - String de tamanho padro 80 caracteres se voce cita o comprimento depois do nome da string voce redefine este valor, observe que no existe o tipo char ento quando se usa uma string de tamanho 1 como um char. Ex: string letra 1 DATE - Data no formato dd/mm/aaaa. O dataflex suporta todas operaes com datas, tipo somar data com inteiro e outras. INDICATOR - o tipo booleano de valor FALSE ou TRUE, so de grande utilidade no controle do fluxo do programa. No proximo captulo veremos laos e comandos bsicos no dataflex.

Capitulo 5 - Laos, indicadores, operadores lgicos e mais alguns comandos No dataflex como toda linguagem de programao que se preze existem laos, antes porm vamos dizer mais sobre indicadores, que so importantes controladores de fluxo nos programas. Declaramos indicadores assim: INDICATOR meu_indicador outro_indicador Pra mudar seu valor (quando criado esta falso) usamos o comando indicate: INDICATE meu_indicador TRUE INDICATE outro_indicador FALSE Podemos atribuir o valor de um indicador ao valor do outro:

INDICATE meu_indicador AS [ outro_indicador ] na sentena acima o valor de meu_indicador (true ou false) ser o mesmo do valor de outro_indicador. No exemplo acima meu_indicador ser false aps a sentena porque ele copiou o valor de outro_indicador que era false. Ou atribuimos indicadores comparando de outras formas: INDICATE dados_ok AS resp.1 EQ "S" INDICATE salario_certo AS salario LE 300 Podemos usar tambm INDICATE outro_indicador AS [ ~meu_indicador ] que o simbolo "~" significa NOT e no caso acima outro_indicador recebe o valor oposto de meu_indicador ou not meu_indicador. No programa o indicador aparece entre colchetes tipo [ MEU_INDICADOR ] quando esta controlando blocos de cdigo, laos, ou depois do AS. Falaremos deles muito mais vezes no se preoculpe. Mas observe que um indicador SEMPRE contm um valor que falso (false) ou verdadeiro (true). INDICADORES ANTES DE COMANDOS: [ meu_indicador ] comando_x [~meu_indicador ] comando_y Se meu_indicador estiver true s o comando_x ser excutado caso contrrio s o comando_y ser executado. INDICADORES ANTES DE BLOCOS DE COMANDOS: [ meu_indicador ] BEGIN comando_x comando_y [ outro_indicador ] BEGIN comando_z comando_k END END INDICADORES COMBINADOS: [ meu_indicador outro_indicador ] comando_k [ meu_indicador ~outro_indicador ] comando_w [~meu_indicador ] comando_x Podemos combinar inmeros indicadores mas o usual usar uns 2 ou 3 no mximo numa sentena pra evitar uma programao confusa e ilegvel. Voce acabou de ver tambm que os blocos de comando so delimitados por BEGIN e END como no pascal. Vamos aos operadores lgicos agora: EQ o igual (= no pascal e == no C) NE o diferente (<> no pascal e != no C) LT o menor (<) LE o menor ou igual (<=)

GT o maior (>) GE o maior ou igual (>=) NOT a negao e tambm representado por ~ dependendo do caso. OR o ou (or no pascal e || no C) Obs: infelizmente o AND no exite e tem que ser feito com if ou indicadores. O comando MOVE usado pra mover valores pra vriveis, janelas e campos de arquivos. bom frisar que uma grande vantagem do dataflex que podemos mover dados de inmeras formas, como por exemplo variavel pra uma janela, somar variavel com campo de arquivo, somar janela data com inteiro, e muito mais. Sintaxe do move: MOVE valor TO variavel MOVE valor TO janela MOVE valor TO arquivo.campo Exemplos: MOVE TELA1.1 TO CODIGO MOVE PRECO TO MENS MOVE 10201 TO CLIENTES.CODIGO MOVE "PAULO" TO TELA.2 MOVE TELA.1 TO TELA.2 MOVE PRODUTOS.COD_PRODUTO TO MOVIMENTOS.COD_PRODUTO MOVE "" TO TELA.3 Agora os LAOS: (1) IF - pode ser usado de vrias formas mas sua lgica IF <condiao> comando sua traduao se a condiao for verdadeira executado o comando. exemplos: IF numero LT 10 BEGIN <COMANDOS> END ELSE BEGIN <COMANDOS> END IF numero GE 10 IF numero LE 30 comando_x OBS: Podemos usar no mximo 3 ifs por sentena tipo if condio1 if condio2 if condio3 comando_ou_bloco (2) REPEAT ... UNTIL repete comandos at a condio ser verdadeira exemplos: REPEAT comando_x comando_y

UNTIL [ MEU_INDICADOR ] REPEAT comando_z UNTIL numero LE 10 (3) FOR ... LOOP exemplos: FOR num FROM 1 TO 50 comando_x comando_y comando_z LOOP FOR valor FROM 20 DOWN 0 STEP 2 <comandos> LOOP down significa que esta decrescendo e step o valor que a vriavel de controle decrementada (o default 1) FOR num FROM 0 TO 100 STEP 10 <comandos> LOOP se dentro do for forarmos a variavel de controle chegar no valor limite isto uma forma de sair do for. Ex acima: move 100 to num (4) WHILE .. LOOP exemplos: WHILE [ indicador ] comando_x comando_y LOOP WHILE valor1 LT valor2 <comandos> LOOP (5) REPEAT .. LOOP este o lao infinito. (6) GOTO Label um recurso que existe mas deve ser usado com cuidado, procure usar os outros laos que daro mais legibilidade e coerencia para os seus programas. exemplos: LB_INICIO: <comandos>

IF resp EQ "N" GOTO LB_INICIO (7) CASE usado da mesma forma que o switch do C ou case do pascal Exemplo: CONDITIONAL CASE MES EQ 1 <COMANDOS> CASEEND CASE MES EQ 2 <COMANDOS> CASEEND CASE MES EQ 3 <COMANDOS> CASEEND CASEELSE <COMANDOS> CASEEND CONDITIONALEND (8) ON variavel_inteira GOSUB sub1 sub2 sub3 ... se a variavel inteira contm 1 vai pra rotina sub1 se contm 2 vai pra segunda rotina e assim por diante. (9) ON variavel_inteira GOTO label1 label2 label3 ... Mesma coisa do on gosub s que com desvio em vez de sub-rotina. Evite usar... No prximo capitulo veremos mais comandos... no entrei em detalhes nos laos porque voce deve telos visto em outras linguagens espero.

Capitulo 6 - Mais comandos dataflex (os mais usados) ABORT - este comando termina um programa dataflex e volta pro programa pai que pode ser um menu dataflex, outro programa ou o sistema operacional. 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 padro da resposta accept resp {Capslock,check="SN"} //opa isso de capslock falaremos depois if resp eq "N" goto inicio <comandos>

abort //fim do programa APPEND - appenda uma string ou mais na primeira. Ex. append str tela.10 str2 cliente.nome 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 varivel. Veja CHARACTER. BACKFIELD - faz o cursor voltar pra janela anterior. BLANKFORM - limpa tela, janela, ou intervalo de janelas (usa c/THRU).Ex: blankform tela1 //limpa todas janelas da tela1 blankform tela1.1 //limpa 1 unica janela blankform tela.5 THRU tela.10 //limpa 6 janelas obs: se usar CLEARFORM sero limpas as janelas mas os caracteres "_" sero mantidos. CALC - executa um calculo no destino pra uma fonte. Exemplos: calc ( (10.23 * tela.1) + (arquivo_taxas.IPI * valor ) / taxa ) TO tela.2 calc (10 + tela.5) to tela.5 CHARACTER - var_int to str. Obtem o caracter ascii correspondente ao inteiro e quarda-o numa variavel string. CIC_CHECK, CGC_CHECK testam a validade do cic e do cgc e devovlvem o resultado em ERR = true se invlido, ERR = false se vlido. Ex: repeat entry clientes.cgc cgc cgc_check cgc until [~err] CLEAR - limpa o buffer de arquivo. CLEARFORM - veja blankform.

CLEARSCREEN - limpa a tela de video. CMDLINE - pega parametros do programa pai ou chamador, exemplo: <programa pai> string programa move "" to programa append programa "filho " cod_cliente " " data_cad " " cgc_cli <programa filho> cmdline cod_cli cmdline data_cadastro cmdline cgc_cliente OBS: as variaveis que vo receber os parametros precisam ser do mesmo tipo do parametro passado pelo pai ou chamador. COPYFILE <nome_arq_fonte> TO <nome_arq_dest>, copia o arquivo. CURRENT_WINDOW - varivel inteira interna do dataflex que guarda o valor da janela corrente. CURRENT_IMAGE - varivel inteira interna do dataflex que guarda o valor da imagem (tela) corrente. DISPLAY - sintaxe: display <arquivo.campo> to janela. Mostra o conteudo do campo com formataes diferentes do entry. (signrt,fill,float$,etc) ENTDISPLAY - mostra os campos nas janelas com entrys, geralmente aps 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 no deve ser usado no meior de entrys. ENTRY - opa este um comando importante que mostraremos com detalhes nos prximos captulos. Ele faz a ligao 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 no tiver registro mostra erro. Usa-se delete nome_arquivo DIRECT_INPUT - abre um arquivo texto ou dispositivo pra leitura.CLOSE_INPUT fecha. DIRECT_OUTPUT - abre um arquivo texto ou dispositivo pra escrita.CLOSE_OUTPUT fecha. ENTAGAIN - impede que o cursor avance de janela. ENTER - macro enter, proporciona um ambiente completo de entrada de dados, ser vista em breve. ENTERGROUP - ser vista posteriormente. ERASEFILE - deleta arquivo, usa-se erasefile <nome_arquivo> ERR - indicador pr-definido do dataflex setado por alguns comandos. ERROR - Da uma mensagem de erro pro usurio com numero e com beep. Ex: error 200 "Codigo invalido!" FIELDINDEX - funciona igual windowindex s que pra campo de arquivo. Ex: arquivo: campo1 campo2 ... campoN usa-se: for fieldindex from 0 to (N-1) move valor to arquivo.campo1& //usa-se "&" pra acessar loop FIND, FINDKEY, SEARCHKEY - So comandos de busca de registros no dataflex que setam found e finderr aps 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 prximo 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 esto preenchidos (3) searchkey ge produtos by index.4 ; comparing produtos.cod_inter eq cod_inter searchkey usado para indices no exclusivos FINDERR - indicador pr-definido que indica se foi achado registro numa busca. Se no acho finderr = true. Juntamente com o found setado aps um comando de busca em arquivo (find,findkey,searchkey). FOUND - indicador pr-estabelecido que indica se foi achado registro ou no aps um comando de busca tipo find, findkey, searchkey etc. Quando chega no final do arquivo de dados o found = false e finderr = true. FORMFEED - faz a impressora avanar de folha. GOSUB - subrotinas so muito boas pra dar legibilidade e facilitar a manuteno dos seus programas, infelizmente na verso 2.3 elas no retornam valores, devendo trabalhar sempre com variveis 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. GOTOXY - Poe o cursor numa posicao na tela, tipo gotoxy 10 15 GRAPHIC ON/OFF - Entra / sai do modo grfico. 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 posio de inicio pra mover. So comandos muito uteis. IFCHANGE - indicador predefinido que indica se houve alterao. Ex: ifchange tela1.1 begin <comandos> end INCREMENT - incrementa de 1 uma variavel inteira. Ex: increment num O contrrio de DECREMENT que decrementa uma varivel inteira. IN - indica se uma substring contida na string. EX: string uf 2 regiao if uf in "SPxRJxESxMG" move "SUL" to regiao 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 posio determinada. Ex. insert substr IN str AT 04 KEYCHECK - verifica se uma tecla foi pressinada, usado em loops. Ex: repeat <comandos> until keycheck KEYPROC OFF/ KEYPROC ON - desabilita ou habilita as keyprocs. LENGTH - retorna o tamanho de uma string. Ex: For num from 1 to length(str)

MOVESTR, MOVE - so comandos usados pra mover dados. S que o movestr move exatamente o dado sem formatalo. OPEN e OPEN .. AS - abre arquivo pra leitura/gravao. 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 padro, fecha com OUTCLOSE. Ex: outfile "arquiv1.txt" outfile "LST:", pra impressora OUTPUT - manda uma tela pra saida padro 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 digitao e mostrando uma mensagem pro usurio. 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 tambm. (found = true se achou) PRINT - opo de mover pra janela com formatao. Ex: print tela.1 to tela.1 {fill="0"} //proximo capitulo t explicado 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 no 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 relatrios, ser estudada c/detalhes posteriormente. REREAD - rele o buffer de registro do arquivo. RETURN - volta de um gosub, se usarmos RETURN RETURN volta da subrotina e da rotina que chamou aquela subrotina (2 nveis). ROUND <expresso> - arredonda o valor da expresso. RUNPROGRAM - excuta um outro programa externo e no 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 secundrios salvando-os em seguida. Nunca use save dentro da macro enter ou entergroup, pois os dados no 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 no move os dados do arquivo principal pros arquivos relacionados secundrios. Ex: SAVERECORD CLIENTES No use saverecord dentro de macro enter ou entergroup pelo mesmo motivo do comando save. SCREEMMODE - ajusta o modo de video. Ex: screenmode 31 SEQEOF - indicador pr definido que indica final de arquivo texto. repeat readln linha ... until [ seqeof ] SHOW e SHOWLN pra mostrar uma mensagem direto na tela sem janelas. STATUS - indica se existe registro no buffer do arquivo. Ex:

indicate existe status clientes ou if status clientes begin <comandos> end SUBTOTAL - comando usado na macro report pra totalizar. Ser visto mais adinate com detalhes. Ex: subtotal body.2 to subtotal1.1 SYSDATE - captura a data e hora do sistema em uma variavel, janela ou campo. formato sysdate [data] {hora} {minuto} {segundo} Ex: sysdate tela.1, sysdate clientes.dt_cadastro hora_cad min_cad SYSTEM - sai para o sistema operacional direto. TRIM - elimina os espacos em branco de uma string. Ex: trim str to str UPPERCASE - converte pra letras maisculas. Usa-se uppercase str WINDOWINDEX - variavel que contm o indice da janela, seu uso facilita muito a programaao.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 WRITE e WRITELN - escreve linha em arquivo texto.Veremos exemplo depois. ZEROFILE <nome_arq_dados> apaga todos os registros de um arquivo de dados. No prximo captulo veremos formatao de janelas.

Captulo 7 - Formatao de janelas, keyprocs. No dataflex verses 2.3 e 3.0 a integridade dos dados dependente das aplicaes de cadastro. Bons

programas de cadastro resultam num bom banco de dados. Claro que voce pode criar uma ferramenta pra atualizar a base de dados mas o ideal os dados serem o mais coerentes possveis j na entrada. ***FORMATAES DE JANELAS *** So usadas aps comandos como entry e accept ou no comando format. Sempre usamos os simbolos "{" e "}" para as formataes, tipo {formatao1,formatao3,...formataoN} DISPLAYONLY - quando a janela s de leitura. O displayonly a combinaco de noenter com noput. Ex. ENTRY PRODUTOS.DESC DESC {DISPLAYONLY} NOENTER - impede um enter na janela mas grava seu valor no buffer. usado quando temos 2 ou mais entrys numa janela, para evitar que o usuario tenha que apertar mais de uma vez a tecla enter numa mesma janela. Ex. ENTRY PRODUTOS.COD_PRODUTO COD_PRODUTO {AUTOFIND,FINDREQ} ENTRY MOVIMENT.COD_PRODUTO COD_PRODUTO {NOENTER} ENTRY NOTAS_FI.COD_PRODUTO COD_PRODUTO {NOENTER} observe que a janela cod_produto esta relacionada com 3 arquivos. NOPUT - impede que o conteudo da janela seja colocado no buffer do arquivo. CAPSLOCK - faz com que tudo que o usurio digite seja convertido pra letras mausculas. Ex. ENTRY CLIENTES.ENDERECO ENDERECO {CAPSLOCK} REQUIRED - impede o cursor de sair da janela sem que o usurio digite algo. Ex: ENTRY CLIENTES.ENDERECO ENDERECO {CAPSLOCK,REQUIRED} CHECK - checa se o conteudo da janela esta contido na string de checagem. Ex. ACCEPT RESP {CAPSLOCK,CHECK="SN"} e resp uma janela ascii de tamanho 1. ACCEPT UF {CAPSLOCK,CHECK="SPxRJxMGxES"} e uf janela de tamanho 2. RANGE - impe um limite inferior e superior. Ex. ACCEPT IDADE {RANGE=18,40} //idade janela _. AUTORETURN - quando o usurio preeche o contedo da janela o cursor pula pra prxima janela, sem precisar apertar o enter. AUTOFIND - usado em janelas associadas a um campo que chave exclusiva, pra quando o usurio digitar e apertar enter se o registro existir j trazido pra tela. Todos os campos do indice devem estar completos. Ex. Exemplo1: (index1 = codigo) ENTRY CLIENTES.CODIGO CODIGO {AUTOFIND} Exemplo2: (index1 = cod_tipo + cod_produto) ENTRY PRODUTOS.COD_TIPO COD_TIPO ENTRY PRODUTOS.COD_PRODUTO COD_PRODUTO {AUTOFIND} Exemplo3: (index3 = bairro + rua + numero + apto) ENTRY CLIENTE.BAIRRO BAIRRO ENTRY CLIENTE.RUA RUA ENTRY CLIENTE.NUMERO NUMERO

ENTRY CLIENTE.APTO APTO {AUTOFIND} Quando o indice exclusivo usado possuir mais de um segmento, a opp autofind deve estar no ultimo campo do ndice. Se usarmos AUTOFIND,FINDREQ ser obrigatrio o usurio entrar na janela com uma entrada que seja existente no arquivo. Observe que o findreq impede o usurio de gravar novos regitros porque ele exige que j exista o registro. Exemplo 4: (index2 = cod_inter + cod_material) ENTRY MATERIAL.COD_INTER TELA.2 ENTRY MATERIAL.COD_MATERIAL TELA.3 {CAPSLOCK,AUTOFIND,FINDREQ} AUTOFIND_GE - sua funo 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 - fora 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 formatao individual no 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 no funciona!!! loop RETAIN - Mantm 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 sero apagados com F9, apenas usando o comando blankform eles podero ser apagados. SKIPFOUND - uma opo que aparece normalmente com um autofind ou autofind_ge. Sua funo se caso seja achado um registro, mostrar os dados na janela e pular pra prxima, sem deixar que ela possa ser modificada. ***KEYPROCS*** Keyprocs so teclas de atalho associadas a labels e indicadores. O dataflex possui teclas de atalho padro que podem ser reprogramadas com o dfsetup. Na verso 2.3 funciona assim: F1 - key.help - ajuda F2 - backwind - tela anteriror F3 - superfind - superbusca

F4 - key.print - impresso 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 - prximo registro -> - key.right - seta pra direita <- - key.left - seta pra esquerda - key.up - seta pra cima - key.down - seta pra baixo ENTER - key.return - confirmao Na programao no final de tudo colocamos as keyprocs, exemplos: //====[ definio 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 (prximo 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 prximo captulo.

Captulo 8 - Algumas dicas de dataflex 2.3 e 3.0 //== usando indice por data: clear arquivo move data_de to arquivo.dt_cadastro //inicializao 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 contruo 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 no esquea de inicializar a chave, muito mais rpido que ler todo o arquivo. Os campos que voce no especificar na inicializao sero 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 compe o indice exclusivo. Lembre que normalmente no 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 NECESSRIO!!! end until [ ~found ] Quando voce l pelo recnum e deleta preciso salva-lo seno da bug (o recnum volta pro zero), mas usando outros indices isto nao necessario. //=== Salvar o recnum (como no exemplo anterior) uma tcnica 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 cdigo o mesmo s trocando direct_output por direct_input e os writeln por readln. Observe que o utilitrio READ gera este cdigo automaticamente pra voce. //=== usar windowindex e fieldindex na mesma expresso 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 fcil, estas estruturas no 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 sero mostradas pro usurio, algumas so pra uso interno do programa.

Captulo 9 - A macro enter (entrada de dados) e relacionamentos Voce lembra daquele programa exemplo da agencia de empregos do capitulo 3 e 4, agora podemos

termina-lo. Seu cdigo ser este: //************************************** //programa P-001 //sistema: agencia de empregos //finalidade: cadastro de profissionais //feito por Paulo Miranda 17/01/2003 //atualizado por Simone 25/02/2003 //************************************** /Tela1 Codigo: _________. Nome: __________________________________________________ Endereco: __________________________________________________ Cidade: ___. _____________________________ UF: __ CEP: _________ Data Nasc: __/__/____ Anos: _. Res: (__.) _________ Cel: (__.) _________ RG: _______________ CIC: _______________ E-mail: __________________________________________________ Profissao: ___. __________________________________________ Salario Pretendido: ___,___.__ /Telamens ___________________________________________________ _ /Aviso Este um exemplo de tela sem janelas... /* //=======[ Inicio da Programao ]=========== //=======[ 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 profisses //======[ 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 //=========[ definio de variaveis ]========= integer ultimo date data //=========[ page das telas ]================= //Page tela1 no 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} if cod_candidato gt (ultimo+1) move (ultimo+1) to cod_candidato entry empregados.nome nome_candidato {capslock,required} entry empregados.endereco endereco {capslock,required} entry cidades.cod_cidade cod_cidade {autofind,findreq} entry empregados.cod_cidade cod_cidade {noenter} entry cidades.desc_cidade desc_cidade {displayonly} entry empregados.uf sigla_estado {capslock,check="SPxRJxMG"} entry empregados.cep cep gosub cep_mask entry empregados.data_nasc data_nasc {required} sysdate data calc (( data - data_nasc ) / 365.25 ) to idade entry empregados.idade idade {noenter}

entry empregados.ddd_res ddd_res entry empregados.tel_res tel_res entry empregados.ddd_cel ddd_cel entry empregados.tel_cel tel_cel entry empregados.rg rg repeat entry empregados.cic cic cic_check cic until [~err] entry empregados.email email {capslock} entry profissoes.cod_profissao cod_profissao {autofind,findreq} entry empregados.cod_profissao cod_profissao {noenter} entry profissoes.desc_profissao desc_profissao {displayonly} entry empregados.salario salario {range=250,5000} print salario to salario move "Dados corretos para gravar? (S/N)" to mens move "S" to resp accept resp {capslock,check="S/N"} if resp eq "N" goto entrysec return entry.find: findkey eq cidades by index.1 for; cidades.cod_cidade eq cod_cidades [ found ] move cidades.desc_cidade to desc_cidade findkey eq profissoes by index.1 for; profissoes.cod_profissao eq cod_profissao [ found ] move profissoes.desc_profissao to desc_profissao return enterend abort //========[ subrotinas do programa ]============ acha_ultimo: 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 so variveis 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 //========[ definio 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 //========[ fim do programa ]=================== A macro enter fornece um ambiente de entrada de dados, vamos analisar sua estrutura: ENTER ARQUIVO_PRINCIPAL

//SECAO ENTRY DA MACRO ENTER: ENTRY ARQUIVO_PRINCIPAL.CAMPO_1 JANELA_1 {FORMATAO} ENTRY ARQUIVO_PRINCIPAL.CAMPO_2 JANELA_2 {FORMATAO} ENTRY ARQUIVO_PRINCIPAL.CAMPO_3 JANELA_3 {FORMATAO} ... ENTRY ARQUIVO_PRINCIPAL.CAMPO_N JANELA_N {FORMATAO} //MENSAGEM DE CONFIRMAAO OPCIONAL PRA SALVAR O REGISTRO RETURN //fecha o loop da macro enter //SECOES POST-ENTRY OPCIONAIS DA MACRO ENTER: ENTRY.FIND: //BUSCAS EM ARQUIVOS RETURN ENTER.SAVE: //PRA SALVAR OU ATUALIZAR OUTROS REGISTROS DE OUTROS ARQUIVOS ARQUIVOS //O ARQUIVO PRINCILAL SALVO AUTOMATICAMENTE!!! //ACIONADA PELA KEYPROC KEY.SAVE RETURN ENTER.DELETE: //PRA DELETAR OU ATUALIZAR REGISTROS EM OUTROS ARQUIVOS //ACIONADA PELA KEYPROC KEY.DELETE 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 sees enter.save, entry.find e outras so opcionais no precisando ser declaradas quando no vo ser usadas. Elas podem ser entendidas como sub rotinas padro da macro enter e so 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 necessrio 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 execuo 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 tambm d menos dores de cabea. Lembrese: relacionamentos mal feitos geram bugs chatos e difceis 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 cabealho), que so programas que voce cadastra um header e pra ele cadastra vrios itens, em arquivos distintos, tipo o cabealho de uma nota fiscal, que tem a razo social da firma, CNPJ, data, numero nota, endereco, etc. E os items da nota de numero variavel que so os produtos, seus valores unitarios, valores totais, etc. Como no podemos usar vrias macro enter mas apenas uma, fazer este tipo de programa da forma tradicional uma coisa chata. Voce poderia usar a entergroup mas tambm no 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 usurio vai parecer que um programa s, e maior trabalho passar alguns parmetros do programa chamador pro programa filho... No prximo captulo falaremos sobre a entergroup.

FALTA CAP 10

Captulo 11 - A macro report

Do mesmo modo que a macro enter nos fornece vrias facilidades para cadastros a macro report vai facilitar muito a criao de relatrios simples ou complexos. Mas tambm poderemos fazer relatrios sem usar a macro report, escrevendo muito mais cdigo... Do mesmo modo que a macro enter a report aparece uma nica vez no programa. Sintaxe: OUTFILE "LST:" //redireciona saida pra impressora CLEAR arquivo //sempre aparece //INICIALIZAAO OPCIONAL DO ARQUIVO //move valor1 to arquivo.campox //move valor2 to arquivo.campoy REPORT arquivo BY index.n { BREAK campox, campoy, ... campon } [ SELECT ] INDICATE SELECT AS... [ SELECT ] INDICATE SELECT AS... [~SELECT ] RETURN END.OF.REPORT INDICATE SELECT AS... [ SELECT ] INDICATE SELECT AS... SECTION HEADER <COMANDOS> OUTPUT HEADER SECTION SUBHEADERX <COMANDOS> OUTPUT SUBHEADERX SECTION SUBHEADERY <COMANDOS> OUTPUT SUBHEADERY SECTION BODY <COMANDOS> OUTPUT BODY SECTION SUBTOTALX <COMANDOS> SECTION SUBTOTALX SECTION SUBTOTALY <COMANDOS> SECTION SUBTOTALY SECTION TOTAL <COMANDOS> OUTPUT TOTAL REPORTEND

FORMFEED //Geralmente aparece aqui, pra saltar de pgina OUTCLOSE //Geralmente aparece tambm A macro report composta por sections opcionais: SECTION HEADER - o cabecalho da pgina, impresso a header toda vez que iniciamos uma nova pgina. SECTION SUBHEADER1 - impressa toda vez que o primeiro campo do indice inicia. SECTION SUBHEADER2 - impressa toda vez que o segundo campo do indice inicia. SECTION BODY - impressa a cada novo registro. SECTION SUBTOTAL1 - impressa quando ocorre quebra no indice1. SECTION SUBTOTAL2 - impressa quando ocorre quebra no indice2. SECTION FOOTER - o rodap de cada pagina. SECTION TOTAL - Aparece no final do relatrio, s na ltima pgina. OBS1: Observe que como um indice tem at nove campos no mximo podemos ter at a SUBHEADER9 e SUBTOTAL9 num relatrio. OBS2: Para cada section declarado (opcionalmente) deve haver obrigatoriamente uma tela correspondente com o mesmo nome! Ex. Section Body ==> /BODY Section Header ==> /HEADER A macro report tem algumas variveis, labels e indicadores internos, as vezes ser preciso mudar seus valores. So eles: PAGEEND - varivel inteira que contem o mumero de linhas por pgina. PAGECOUNT - varivel inteira que contm o numero da pgina atual. LINECOUNT - varivel inteira que contm o numero da linha atual. RECCOUNT - varivel inteira que contm o numero de registros selecionados. END.OF.REPORT - label do fim do relatrio. Uas-se return end.of.report pra encerrar o relatrio. SELECT - indicador interno que indica se um registro foi selecionado ou no. No final do arquivo select fica false. SUBTOTAL - comando pra totalizar. Ex: Subtotal body.4 to susbtota1.2 Exemplo de relatrio simples com a report: /header |============|=============================================| ================| | *REL001* | Nome da Empresa | Pag ___. | | Paulo | Relatorio do Estoque de Produtos |__/__/____ _.:_.| |============|=============================================|

================| | Codigo | Descrio | Qt.Est.| Val. Unit | |--------------+---------------------------------------+--------+-----------| /subheader1 | Setor: ___. ___________________________ | || /body | ____________ | _____________________________________ | _____. | __,___.__ | /total |---------------------------------------------------------------------------| || | Produtos Lidos ==> _____. | | ========================================================================= ==| /tela1 setor: ___. __________________________________ importados? _ (N)acionais,(I)mportados,(T)odos copias: _. _______________________________________ _ /* //===Abertura arquivos======= open "setores" as setores //===plasticos, vidros, cosmticos, 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 prximo captulo mais exemplos da report.

Captulo 12 - Mais exemplos com a report TEORIA: (1) Uso do BREAK: No dataflex o comando break opcional e significa que quando o indice quebrar, uma imagem sera impressa. Sintaxe: REPORT arquivo BY index.n {BREAK arquivo.campox,arquivo.campoy,...} Vamos exemplificar: Suponha um arquivo de items de notas fiscais cujo index.3 composto dos campos: setor+cod_produto+val_item+recnum. Se quizermos usar report items_nfs by index.3 break cod_produto teremos que definir uma section subtotal2 porque cod_produto o segundo campo do indice. Sempre seguiremos est lgica. E quando no houver breaks, no existiro sections subtotal nem subheader. (2) Quando criamos uma janela tipo body.1 o dataflex automaticamente aloca uma variavel body.1% que acumula o valor dessa janela, pra que esse valor possa ser retornado com o comando subtotal, na section subtotal1 por exemplo. A sintaxe seria SUBTOTAL body.1 TO subtotal1.1 (3) Quando voce precisar de um relatrio com vrias opes de formato, e leituras do arquivo com diferentes indices, o melhor a fazer criar varios subprogramas, usando chain pra executar cada um a partir das opcoes selecionadas no programa principal. Assim voce pode usar vrias macro report usadas de forma simples em cada subprograma. Exemplo: string programa parametros move "relprod" to programa accept opcao {capslock,check="ABCDEF"} //cada opcao um tipo de relatorio append programa opcao parametros chain wait programa ... (4) Pro programa funcionar melhor declare todas as imagens da report como RESIDENT. Exemplo /body resident

__. ______________ /total resident Bom acredito que a melhor forma de aprender a usar a report vendo sua aplicao na prtica, ento vamos l: 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 no 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 situao que voce quer imprimir varios items pra cada registro, como por exemplo pra cada nota apacem os items que a compe no relatrio. Voce pode criar loops e subrotinas na report bem como imprimir imagens sem ser as imagens padro 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 PRINT PAGECOUNT TO HEADER.1 {FILL="0"} PRINT DATAREL TO HEADER.2 PRINT HORA TO HEADER.3 {FILL="0"} PRINT MIN TO HEADER.4 {FILL="0"} PRINT DATA_DE TO HEADER.5 PRINT DATA_ATE TO HEADER.6 OUTPUT HEADER SECTION BODY FINDKEY EQ SCOLA23 BY INDEX.1 FOR SCOLA23.COD_CLIENTE EQ ; SCOLA29.COD_CLIENTE PRINT SCOLA23.RAZAO_CLI TO BODY.1 PRINT SCOLA23.UF_FAT TO BODY.2 PRINT SCOLA29.NF TO BODY.3 MOVE SCOLA29.NF TO NOTA PRINT SCOLA29.DATA TO BODY.4 PRINT SCOLA29.VAL_NF TO BODY.5 MOVE 0 TO FIELDINDEX

REPEAT IF FIELDINDEX NE 0 BLANKFORM BODY PRINT SCOLA29.VAL1& TO BODY.6 IF SCOLA29.VAL1& EQ 0 BLANKFORM BODY.6 PRINT SCOLA29.VENC1& TO BODY.7 PRINT SCOLA29.PGTO1& TO BODY.8 CALC ( 1 + FIELDINDEX ) TO FIELDINDEX OUTPUT BODY UNTIL SCOLA29.VAL1& EQ 0 CLEAR SCOLA30 MOVE NOTA TO SCOLA30.NF INDICATE SAIR FALSE REPEAT FIND GT SCOLA30 BY INDEX.1 [ FOUND ] INDICATE FOUND AS SCOLA30.NF EQ NOTA [ FOUND ] BEGIN PRINT SCOLA30.COD_PRODUTO TO PRODUTOS.1 SEARCHKEY GE PRODUTOS BY INDEX.1 COMPARING ; PRODUTOS.COD_TIPO EQ SCOLA30.COD_TIPO ; PRODUTOS.COD_PRODUTO EQ SCOLA30.COD_PRODUTO PRINT PRODUTOS.DESC_PRODUTO TO PRODUTOS.2 PRINT SCOLA30.QTD_PRODUTO TO PRODUTOS.3 MOVE SCOLA30.VAL_UNIT TO PRODUTOS.4 CALC ( PRODUTOS.3 * PRODUTOS.4 ) TO PRODUTOS.5 GOSUB ACUMULA_PRODUTOS PRINT PRODUTOS.4 PRINT PRODUTOS.5 INDICATE FOUND TRUE END [ ~FOUND] OUTPUT PRODUTOS 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

Captulo 13 - Exemplo de impresso de etiquetas Como a impresso de etiquetas muito comum vamos dar um exemplo de impresso de etiquetas pra mala direta de clientes em impressora de formulrio contnuo. //Cria-se uma tela de seleo como voce j sabe. /TELA

Cliente .: _____. - ________________________________________ Formulario OK.?.(Y/N).: _

Quantidade de Etiquetas Lidas ...: _____. Quantidade de Etiquetas Impressas: _____.

//Cria-se a tela onde vai o texto na etiqueta, isto um pouco trabalhoso //porque temos que ajustar o layout pra sair bom na etiqueta. /BODY RESIDENT ________________________________________ ________________________________________ ________________________________________ ________________________________________ ______________________________ ______________________________ _________ ______________________________ __ _________ ______________________________ __

_____ ______________________________ _____ ______________________________ /* #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 padro 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 ento 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 no 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 usurio ver processando SECTION BODY //usa-se windowindex pra facilitar porque so 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 lgica a mesma e o uso da windowindex facilita bem.

Captulo 14 - Criando comandos Bom j vimos muitos comandos do dataflex e agora chegou a hora de ver como criar nossos prprios comandos. O comando pode ser definido no prprio programa, mas o melhor criar uma biblioteca, que nada mais que um arquivo texto contendo os comandos. Depois se voce precisar daquele comando que voce criou, voce da um include da biblioteca que deve ter extenso ".inc". Tipo nossos programas aparece #include biblioteca.inc mas poderia ser #include sua_biblioteca.inc ou qualquer nome. Antes de mais nada precisamos ver algumas diretivas de compilao do dataflex. Diretivas de compilao do informaes pro DFCOMP de como o nosso programa deve ser compilado. Outra coisa legal do comando: ele aceita vrios parmetros (9 no maximo) e pode modificar todos estes parametros. Sintaxe do comando: #COMMAND nome_do_comando <COMANDOS> #ENDCOMMAND DIRETIVAS DE COMPILADOR: (sempre comeam com "#") #IF - if de compilador

#ELSE - mesma coisa do else normal #ENDIF - usa-se pra delimitar o bloco if de compilador #IFDEF - se j foi definida varivel #IFNDEF - se no foi definida a varivel #IFSAME - se um parametro o memo que... ACESSO AOS PARAMETROS: !0 - numero de parametros !1 - primeiro parametro !2 - segundo parametro !3 - terceiro parametro e assim por diante at !9 EXEMPLO 1 - Este comando usado pra depurar, porque mostra o conteudo de 1 a 9 variveis na tela e da um pause Exemplo de uso: marbreak clientes.cod_cliente valor data #COMMAND MARBREAK //AUTOR: MARCIO LUIZ OLIVEIRA GOTOXY 24 12 //posiciona o cursor SHOW !1 " | " !2 " | " !3 " | " !4 " | " !5 " | " !6 " | " !7 " | " !8 " | " !9 //mostra os parmetros na tela PAUSE "" //faz uma pausa at uma tecla ser pressionada #ENDCOMMAND EXEMPLO 2 - Liga o cursor com CURSOR ON e desliga com CURSOR OFF #COMMAND CURSOR //AUTOR: MARCIO LUIZ OLIVEIRA GOTOXY 23 77 #IFSAME !1 OFF //se o parametro 1 igual OFF SHOW " [?25l [.0" //sequencia de escape pra desligar o cursor #ELSE SHOW " [?25h [.3" //sequencia pra deixa-lo visvel #ENDIF GOTOXY 23 77 SHOW " " #ENDCOMMAND EXEMPLO 3 - Exelente comando pra formatar e desmembrar datas, seu cdigo mais complexo que os anteriores. Lembre-se o dataflex usa internamente a data como um inteiro que o numero de dias desde 01/01/0001. #COMMAND DATA_CHECK // Sintaxe : DATA_CHECK (DATA) [DIA] [MES] [ANO] [DESCRICAO DO MES] //AUTOR DESCONHECIDO #IFDEF DATA_VAR //se j esta definida a variavel DATA_VAR no faz nada #ELSE

INTEGER DATA_VAR //seno cria a varivel #ENDIF MOVE !1 TO DATA_VAR //move o parametro 1 pra data_var IF (LENGTH(!1)) EQ 5 ; IF DATA_VAR LT 693975; IF DATA_VAR GE 10958; CALC (DATA_VAR + 693975) TO !1 IF (LENGTH(!1)) EQ 4 ; IF DATA_VAR LT 10958 IF DATA_VAR GT 1 ; CALC (DATA_VAR + 730500) TO !1 IF !1 NE "" ; IF !1 LT "01/01/1900" BEGIN SHOW " " SHOW " " SHOW " " GOTOXY 21 14 SHOW "ATENCAO !! DATA NAO PODE SER INFERIOR A 01/01/1900." GOTOXY 21 14 PAUSE "" SHOW " " END IF !1 GE "01/01/1900" BEGIN #IF !0>1 LEFT !1 TO !2 2 #IF !0>2 MID !1 TO !3 2 4 #ENDIF #IF !0>3 RIGHT !1 TO !4 4 #ENDIF #IF !0>4 MOVE "" TO !5 IF !3 EQ 1 APPEND !5 !2 " de Janeiro de " !4 IF !3 EQ 2 APPEND !5 !2 " de Fevereiro de " !4 IF !3 EQ 3 APPEND !5 !2 " de Marco de " !4 IF !3 EQ 4 APPEND !5 !2 " de Abril de " !4 IF !3 EQ 5 APPEND !5 !2 " de Maio de " !4 IF !3 EQ 6 APPEND !5 !2 " de Junho de " !4 IF !3 EQ 7 APPEND !5 !2 " de Julho de " !4 IF !3 EQ 8 APPEND !5 !2 " de Agosto de " !4 IF !3 EQ 9 APPEND !5 !2 " de Setembro de " !4 IF !3 EQ 10 APPEND !5 !2 " de Outubro de " !4 IF !3 EQ 11 APPEND !5 !2 " de Novembro de " !4 IF !3 EQ 12 APPEND !5 !2 " de Dezembro de " !4 #ENDIF

#ENDIF END #ENDCOMMAND OBS: Voce pode chamar comandos do dataflex e tambm seus prprios comandos dentro de 1 comando seu. Mas se um comando usa uma imagem ela obrigatoriamente tem que ser definida no programa seno d erro de compilao. Infelizemte na verso 2.3 uma imagem no pode ser definida dentro de um comando (na 3.0 j possivel!). DICAS: - Ao declarar variveis em comandos procure usar nomes pouco provveis de alguem querer usar tipo confirma$_ok,ou $$$_num_x por exemplo. - Crie comandos o mais independente possivel do seu programa assim eles podero facilmente ser usados em vrios programas. - Evite uso de comandos associados a imagems dentro dos seus comandos, prefira usar show, pause, inkey que so comandos que no usam imagens. - Tenha uma unica biblioteca pra todos os programadores, assim evita de existir comandos diferentes pra fazer a mesma coisa. - Comandos podem fazer tudo que feito no programa, como abrir arquivos usar laos e tudo mais, mas procure cria-los apenas pra resolver coisas que se repetem frequentemente, poupando seu tempo no futuro.

FALTA CAP 15

Capitulo 16 - Outras tcnicas (1) Sysfile - muito util deixar o primeiro arquivo de cada filelist como um sysfile, ou seja, um arquivo de apenas um registro que contem algumas informes do sistema como nmero de sequencia de notas fiscais, numero do usurio, etc. (2) Arquivo temporrio - arquivo que usado por vrios relatrio pra acumular dados. Tanto seus campos como seus indices devem ser o mais reutilizveis possivel e deve usar nome de campos genrico. Exemplo: arquivo: phtemp usuario number 6.0 //sempre o numero do usuario aqui campo_ascii ascii 10 campo_date date campo_float number 8.2 ... index.1 <1> <2> <3> <4> index.2 <1> <3> ... index.3 <1> ... //Todos indices quebram no campo do usurio ...

Cada relatorio abre o sysfile pega o numero do usurio e o incrementa salvando novamente no sysfile. 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 relatrio o conteudo do temporario apagado apenas dos registros do usurio que terminou aquele relatrio. Perceba que se no hover quebra no indice por usurio, o temporrio misturar registros gravados por diferentes aplicaes. (3) Campo usurio 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 usurio. Porque assim conseguimos separar os resultados dos relatorios tanto pra consulta dos registros como pra sua deleo. Lembre que cabe a cada aplicao 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) Estruturao da programao e hidentao do cdigo - isto bom em qualquer linguagem... Procure separar o cdigo 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 hidentao pra deixar os loop mais visveis: subrotina_quaquer: for cont from 1 to num repeat while [ ok] <comando> loop until [~found] loop return Sem hidentao ficaria menos visvel e mais dificil a manuteno: 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 no, mas com a keyproc desabilitada eles no pulam automaticamente pra rotina da keyproc. Ex: keyproc off repeat <comandos> [ key.escape ] abort until [ key.return ] keyproc on (7) Criao do efeito hi-ligth, ou seja tipo uma caixa de seleo 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 pacincia! 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 Voce pode jogar a TORRE DE HANOI com 3 a 7 discos. O objetivo do jogo e mudar todos os discos do cone "A" para outro cone nunca deixando cone maior sobre cone menor. Boa sorte... Com quantos discos deseja jogar? _. Digite seu nome: ____________________ Deseja ver numero nos discos? (S/N) _ Jogo feito por Paulo Miranda e-mail: phbm@webcable.com.brEste endereo de e-mail est protegido contra spambots. Voc deve habilitar o JavaScript para visualiz-lo. /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 Estes sao os recordistas: 3 discos ===> ____________________ ( ____ movimentos ) min=007 4 discos ===> ____________________ ( ____ movimentos ) min=015 5 discos ===> ____________________ ( ____ movimentos ) min=031 6 discos ===> ____________________ ( ____ movimentos ) min=063 7 discos ===> ____________________ ( ____ movimentos ) min=127 Tente quebrar os records !!! /* PAGE SET HELP AT 08 22 PAGE SET RECORD AT 07 22 PAGE SET RECORDES AT 04 10 PAGE SET VITORIA AT 08 22

INDICATOR OK FIM VER NOVO_RECORD INTEGER ORIGEM DESTINO WIND VALOR_ORIGEM VALOR_DESTINO REPEAT //***Loop do conjunto de partidas OPCOES: ACCEPT INICIO.1 {RANGE=3,7} ACCEPT INICIO.2 {CAPSLOCK,REQUIRED} ACCEPT INICIO.3 {CAPSLOCK,CHECK="SN"} INDICATE VER AS INICIO.3 EQ "S" BLANKFORM TORRE BLANKFORM MATRIZ GOSUB MOSTRA_RECORDES REINICIA: GOSUB INICIA_MATRIZ GOSUB DESENHA_MATRIZ PAGE TORRE REPEAT //***Loop da partida REPEAT //***Loop da jogada ACCEPT TORRE.65 {CAPSLOCK,CHECK="ABC"} ACCEPT TORRE.66 {CAPSLOCK,CHECK="ABC"} GOSUB MOVIMENTO [~OK ] BEGIN MOVE "Erro, jogada invalida!" TO TORRE.67 PAGE TORRE PAUSE "" BLANKFORM TORRE.67 PAGE TORRE END UNTIL [ OK ] [ FIM ] GOSUB ESCREVE_RECORDES UNTIL [ FIM ] LOOP //*******TECLAS DE ATALHO******** KEYPROC KEY.ESCAPE CLEARSCREEN //**se o chefe chegar e bom... ABORT KEYPROC KEY.UP KEYPROC KEY.LEFT BACKFIELD RETURN

KEYPROC KEY.CLEAR IF TORRE.64 GT 0 BEGIN BLANKFORM TORRE RETURN REINICIA END ENTAGAIN RETURN KEYPROC KEY.DELETE RETURN OPCOES KEYPROC KEY.HELP PAGE HELP PAUSE "" ENTAGAIN RETURN 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 endereo 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 extendo ".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 //==========================[ ABERTURA DE ARQUIVOS ] ============================ OPEN "SCOLA24" AS SCOLA24 //==== EMPRESAS OPEN "SCOLA23" AS SCOLA23 //==== CLIENTES //==========================[ DEFINICAO DE VARIAVEIS ] ========================= STRING NUMERO 1 INTEGER CONT INDICATOR CEPOK EXISTE //===========================[ PAGE SET DAS TELAS ] ============================

PAGE SET TELA2 AT 16 10 COLORS 14 15 PAGE SET RESP AT 54 55 COLORS 14 15 PAGE SET TELAHELP AT 20 14 COLORS 07 07 //===========================[ NOMES DA TELA ]============================ NAME TELA2 EMPRESA RAZAO_EMPRESA FANT_EMPRESA CNPJ IE ENDERECO BAIRRO MUNICIPIO UF; CEP_MASC DDD FONE FAX EMAIL DT_CAD DT_ULT_ALT //===========================[ PROGRAMA PRINCIPAL ] ============================ TITULAR "PAULO - SCOLA24 - CADASTRO DE EMPRESAS" ENTER SCOLA24 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 ENTRY SCOLA24.IE IE {CAPSLOCK} ENTRY SCOLA24.ENDERECO ENDERECO {CAPSLOCK} ENTRY SCOLA24.BAIRRO BAIRRO {CAPSLOCK} ENTRY SCOLA24.MUNICIPIO MUNICIPIO {CAPSLOCK} ENTRY SCOLA24.UF UF {CAPSLOCK} ENTRY SCOLA24.CEP_MASC CEP_MASC {CAPSLOCK} GOSUB LB_CEP_MASC ENTRY SCOLA24.CEP CEP.1 {NOENTER} ENTRY SCOLA24.DDD DDD {CAPSLOCK} ENTRY SCOLA24.FONE FONE {CAPSLOCK} ENTRY SCOLA24.FAX FAX {CAPSLOCK} ENTRY SCOLA24.EMAIL EMAIL {CAPSLOCK} [~EXISTE] SYSDATE DT_CAD [ EXISTE] ENTRY SCOLA24.DT_CAD DT_CAD {NOENTER} [ EXISTE] BEGIN SYSDATE DT_ULT_ALT IFCHANGE SCOLA24 ; ENTRY SCOLA24.DT_ULT_ALT DT_ULT_ALT {NOENTER} END 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 //===========================[ Teclas de Funcao ]============================== KEYPROC KEY.HELP PAGE TELAHELP MENSA "AJUDA DO SISTEMA" PAUSE ""

MENSA " " ENTAGAIN RETURN 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: REPLACE "-" IN CEP_MASC WITH ""

PRINT CEP_MASC TO AUX.3 INDICATE CEPOK AS AUX.3 GE 100000 [CEPOK] INDICATE CEPOK AS AUX.3 LE 99999999 [CEPOK] MOVESTR AUX.3 TO CEP_MASC [CEPOK] INSERT "-" IN CEP_MASC AT 06 RETURN ///==========================[ FIM DO PROGRAMA ]=========================

Esse exemplo usa a macro entergroup para a tela de selecao de dados do relatorio e a macro report para imprimi-lo. /RESP _ /TELA PARAMETROS DE SELEO

Perodo ..........: __/__/____ at __/__/____ Cdigo do Produto : _____. ( <Enter> p/ Todos ) 80 COL. /HEADER RESIDENT ALAMAR Tecno Cientfico Ltda |=========|====================================================| ==================| | SCOLR8 | RELAO DE ENTRADA E SAIDA DOS | P gina: ___. |

|* BRUNO *| MATERIAIS DIVERSOS | __/__/____ __:__ | |=========|====================================================| ==================| |---------------------------------------------------------------+---------------------------------+-------------------------------------| ||ENTRADA|SAIDA| |CODIGO DESCRIO |----------------------------------|-------------------------------------| | | 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 " " ACCEPT DATA_FIN {RANGE=01/01/1900,31/12/2020} IF DATA_FIN LT DATA_INI BEGIN MENSA " A Data Final no Pode Ser Menor que a Data Inicial" SHOW " " END UNTIL DATA_FIN GE DATA_INI ENTRY SCOLA12.CODIGO CODIGO {AUTOFIND} [ERR] SCREENMODE 31 IF CODIGO EQ 0 INDICATE TODOS TRUE MENSA " Confirma Seleo ? (S/N)" MOVE "S" TO RESP.1 ACCEPT RESP.1 {CAPSLOCK,CHECK="SN"} IF RESP.1 EQ "N" GOTO LB_SELECAO CLEAR SCOLA18 MOVE DATA_INI TO SCOLA18.DTMOV [~TODOS] MOVE CODIGO TO SCOLA18.COD_PROD

OUTFILE "LST:" ENDGROUP //*********[ FIM DA ENTRADA DE DADOS ]*********** //*************[ INICIO DA MACRO REPORT ]************************** REPORT SCOLA18 BY INDEX.2 BREAK SCOLA18.DTMOV INDICATE SELECT AS SCOLA18.DTMOV GE DATA_INI [ SELECT] INDICATE SELECT AS SCOLA18.DTMOV LE DATA_FIN [~SELECT] RETURN END.OF.REPORT [~TODOS ] INDICATE SELECT AS SCOLA18.COD_PROD EQ CODIGO 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 PRINT SCOLA18.COD_PROD TO BODY.1 PRINT SCOLA12.DESCRICAO TO BODY.2 IF SCOLA18.TIPO_ES EQ "E" BEGIN PRINT SCOLA18.NPED TO BODY.3 PRINT SCOLA18.QUANT TO BODY.4 PRINT SCOLA18.DTMOV TO BODY.5 END IF SCOLA18.TIPO_ES EQ "S" BEGIN PRINT SCOLA18.DEPTO_DEST TO BODY.6 PRINT SCOLA18.QUANT TO BODY.7 PRINT SCOLA18.DTMOV TO BODY.8 END 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 ]********************************

Você também pode gostar