Clipper On Line • Ver Tópico - Erros comuns - Clipper e Harbour

Erros comuns - Clipper e Harbour

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

 

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 22 Jul 2019 19:28

Tava aqui pensando com meus botões... kkkkk
O cara tá preocupado com GUI, com mouse, com Harbour, com não sei o que....
às vezes até troca pra LIB gráfica e resolve problemas sem nem saber que o problema era seu fonte.

DO WHILE ! RLock()
ENDDO


O computador tem mais o que fazer, principalmente o Windows e a rede.
Testar centenas de vezes por segundo se o registro tá liberado... isso é acabar com Windows e com a rede.
Vai resolver passando pra Harbour... aí ferrou de vez... ao invés de centenas de vezes por segundo, serão milhares de vezes por segundo.

Em Harbour.... ajuda muuuuuuito um Inkey(1)
Em Clipper.... ajuda o Inkey(1), mas ajuda mais alguma LIB pra liberar tempo para Windows, e mais ainda se for OSLIB e se ficar chamando OL_Yield() no intervalo de espera.

Explicação:
A cada teste, a rede é pesquisada, então há tráfego de informação pela rede.
O programa testando, está usando tempo de processamento do computador, e será que faz diferença centenas ou milhares de vezes por segundo?
OL_Yield() é uma função da OSLIB, é como se fosse uma pausa momentânea no processamento do aplicativo, e avisa para o Windows fazer alguma outra coisa enquanto está em pausa. Talvez milésimos de segundo, que seja, quanto mais chamar, mais tempo para o Windows, e menos tempo desperdiçado pelo aplicativo.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 22 Jul 2019 19:54

Inkey(0)

Isso espera o usuário apertar alguma tecla?

ERRADÍSSIMO, com todas as letras maiúsculas.

Isso vale para teclado e mouse: na prática o programa fica vasculhando a cada milésimo/milionésimo de segundo se há alteração no teclado e mouse.
Em Harbour tudo bem, a linguagem de programação já está preparada pra não sobrecarregar o Windows.
Mas em Clipper.... naquela época isso de multitarefa não existia, por isso ele pode sobrecarregar o Windows só de ficar parado !!!!
Sério isso... é como se o programa estivesse a 1.000 por hora, quando na verdade está parado.

Por isso em Clipper é obrigatório usar alguma LIB pra liberar tempo ao Windows.
Eu sempre usei OSLIB.
Ela tem o modo automático e o modo manual.
O modo automático é pra onde não se tem opção de mexer - por exemplo a GETSYS original.
O modo manual permite liberar o máximo que puder.

É sério.

nKey := Inkey(0)


nKey := 0
DO WHILE nKey == 0
   OL_AutoYield()
ENDDO


Olhando assim, qual das duas consome mais CPU?
A segunda, porque fica processando o tempo todo?
Não... a primeira, porque fica vasculhando o teclado o tempo todo.
Na segunda há um "aviso para o Windows" de que o programa está parado e que pode aproveitar esse tempo extra, portanto o aplicativo acaba consumindo menos CPU.

Por isso nos meus aplicativos em Clipper eu usava um MyInkey() no lugar de Inkey(n), porque coloquei esse tratamento de "tempo para o Windows".
O Windows também lê/grava DBFs, roubar tempo do Windows é roubar tempo também do aplicativo, porque ele depende das informações do Windows.

E mouse é pior que teclado, consome mais CPU ainda !!!!!
Antes de pensar em colocar mouse no Clipper, pense nisso do uso de CPU.
Dá pra colocar? Sim, mas tem que deixar preparado pra não consumir muita CPU.

Novamente: o Harbour já é pra Windows, ele já tem tratamentos pra isso. Mas o Clipper... não existia Windows na época dele... era só o aplicativo e mais nada, por isso ele precisa de ajustes para o Windows...

Outro ponto importante:
consumir CPU também significa FRITAR PROCESSADOR.
Sim... se o Clipper usa 100% de CPU, significa que a CPU está na velocidade máxima... aonde ela ferve e pode até queimar.
O que salva hoje em dia é que temos processadores QuadCore, 4 núcleos, então o Clipper vai ferver só um núcleo, e já não corre tanto risco de fritar tudo

Saída para o Clipper:
alguma LIB pra "dar tempo ao Windows".
Alterar mais fundo, pra OL_Yield() da OSLIB por exemplo.... talvez pra curiosidade.

Melhor avaliar direito se é melhor gastar tempo com o Clipper pra resolver essas coisas, ou se é melhor gastar esse tempo pra já usar Harbour aonde tudo isso está resolvido.
Isso depende de cada um.
Eu usava isso antes de 2008, compensou, porque ANTES dessa época o Harbour ainda tinha alguns bugs.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 22 Jul 2019 20:13

NTX ou CDX?

Duas diferenças básicas entre NTX e CDX

- NTX é de apenas um índice. Pra ter 5 índices são 5 arquivos
- CDX é múltiplo: basta 1 único arquivo

Por acaso deixou de usar índices pra não estourar o limite de arquivos?
Já imaginou precisar de 50 índices para um único arquivo?

Vamos lá, um exemplo fictício: 10 arquivos com 30 índices cada.
Com NTX: 1 DBF + 30 NTX = 31 arquivos X 10 = 310 arquivos - já era.... o DOS não aceita isso
Com CDX: 1 DBF + 1 CDX = 2 arquivos X 10 = 20 arquivos - até o DOS aceita

abertura de um arquivo desses em NTX:

USE ARQUIVO
SET INDEX TO ntx1, ntx2, ntx3, ntx4, ntx5, ntx6, ntx8, ntx9, ntx10, ntx11, ntx12, ntx13, ntx14, .....mais 16 ainda
xi... faltou o ntx7... fud... vai corromper índice

em CDX

USE ARQUIVO
SET INDEX TO arquivo // já abriu os 30 índices em arquivo.CDX

Bom... essa foi a primeira vantagem: quantidade de arquivos envolvidos, segurança na abertura de arquivos/índices, mais longe das limitações do sistema operacional, menos arquivos pro sistema operacional "tomar conta", menos arquivos corrompidos, etc. etc. etc

A segunda: índice CDX é compactado

Isso significa menos espaço em disco.... e.... menos tráfego de rede

No caso do Clipper convém destacar o seguinte:

- Diz a literatura que CDX do Clipper 5.2 não é muito bom, melhor usar SIXCDX com ele, já o CDX do Clipper 5.3 é mais eficiente (as RDDs são de terceiros, apesar de fazerem parte do Clipper, e cada versão era de um "fabricante" diferente)
- O uso de CDX tem mais recursividade. Pode ser interessante usar o Blinker e indicar isso no linqueditor, antes de adotar o CDX

Nota: lembrando que se o aplicativo Clipper funcionou até hoje, mais interessante passar pra Harbour primeiro, e só depois pensar no CDX.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 22 Jul 2019 20:32

Memória:

Harbour nem precisa comentar. em 32 bits limita a 4GB de memória, e em 64 bits nem me preocupo em saber.

O Clipper já teve o PLINK86, o RTLINK, o EXOSPACE e o BLINKER.
Acho que todos eram produtos de terceiros, mesmo vindo no Clipper.

Aqui o RTLINK 7, que comprei na época, que liberava mais memória

2010-06-04-DSC00143.JPG


Assim como o RTLINK, o BLINKER também tem versão independente.
Não confunda o que faz parte do Clipper com o que é vendido separado.

PLINK86: limitado a 640KB de memória, mas permitindo o uso de overlay, pra carregar um pedaço do programa por vez

RTLINK: uso de overlay automático. Por ser automático, carregar um pedaço do programa por vez, facilitou, mas ainda limitado aos 640KB de memória

RTLINK7 separado: mais opções de até dividir o Clipper em pedaços e liberar mais memória

EXOSPACE: sem overlays, e uso de até 8MB de memória. Na prática nem tanto, mas de qualquer jeito muito mais do que os outros linqueditores

BLINKER: híbrido, permitindo overlay ou não, e até DLL !!!! Até 16MB de memória, tranquilidade em compilar.

Importante também:

O Clipper permite o uso de arquivo CLP, e muita gente fez/faz uso disso, ou até do Clipper "puxar" automático os outros PRGs.
Isso é errado, porque o OBJ fica grande e precisa ser carregado todo de uma vez.
Lembram acima: overlay... rtlink... carregar um pedaço de cada vez... pois é... criando um OBJ com tudo junto, está impedindo que isso aconteça, está atrapalhando o Clipper ao invés de ajudar.

O default do Harbour é -m, pra compilar cada fonte separado.
Quem precisa muito disso é o Clipper. No final, quem sente dificuldade com isso é porque faz/fazia errado no Clipper.
O EXE final é o mesmo, a diferença é "durante" a execução.

do jeito errado:

arquivo.clp
prg1.prg
prg2.prg
prg3.prg

clipper @arquivo.clp
rtlink fi arquivo.obj

do jeito certo:

clipper prg1 -m
clipper prg2 -m
clipper prg3 -m
rtlink fi prg1, prg2, prg3

Nota: aqui mostrando referente ao parâmetro -m, não significa que seja o único necessário

Em Harbour os limites são maiores, mas nada impede de continuar fazendo igual.
Pode ser bom até pra LIBs, pra quando linqueditar trazer somente o necessário.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 22 Jul 2019 20:49

Faltou no post anterior, talvez até melhor ter ficado separado:

O BLINKER permite usar até 16MB de memória, linqueditando no modo EXTENDED.
Isso o produto em separado, não o produto que vém no Clipper.

Não é automático, só faz isso se colocar os comandos pra fazer isso.

Importante também:

nem todas as LIBs permitem o uso em modo EXTENDED.
Se ainda usa Clipper, se achou interessante o Blinker, linquedite primeiro pra confirmar se suas LIBs aceitam esse modo EXTENDED.

Este ainda compensa usar no Clipper, porque altera apenas o comando pra linqueditar, e deixa o Clipper aproveitar muuuita memória.

Não lembro se era no W95/W98.... não se podia misturar EXEs de EXOSPACE e BLINKER na mesma máquina, porque a forma de configurar memória era diferente.
Uma vez a memória se configurando automático para EXOSPACE, não funcionava para BLINKER, e vice-versa.
Na prática já não lembro mais os detalhes, ou se era mesmo BLINKER e EXOSPACE, ou se precisava DEVICE=algumacoisa.sys...
Eu lembro do DOS=HIGH,UMB, que liberava um pouco mais de memória, por mover parte do command.com pra acima de 640KB.
Lembro do DEVICE=HIMEM.SYS, mas já não lembro mais pra que servia.... e hoje em dia nem importa mais...
E o DEVICE=COUNTRY.SYS, pra configurar a codepage do DOS... que o Clipper tinha arquivos pra codepage também...
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 22 Jul 2019 21:06

clipper.png


Que pena que não entendi isso antes....

Olhem lá no Clipper: parâmetro W - habilitar warnings

Significa permitir que o Clipper mostre alertas sobre possíveis problemas !!! possível fonte errado !!!

Em outras palavras: o default do Clipper era NÃO se importar se estava certo ou errado, ele podia te ajudar mas o default sempre foi SEM ajuda, SEM avisos.

O Harbour e o XHarbour também tem isso.

Vai de cada um, vai de fazer isso agora... ou pelo menos para fontes novos...

Convém destacar: mostra lá ano de 1995.... 24 anos atrás já existia essa ajuda
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 22 Jul 2019 23:38

Sobre a compilação usando -n

Isso é para desprezar o nome do arquivo em disco, e usar somente o conteúdo.

exemplo:

----programa.prg---
PROCEDURE yx

Se compilar esse fonte com -n, no EXE vai entrar a PROCEDURE yx
Já se compilar sem -n, no EXE vão entrar duas procedures: programa e yx, o nome do prg acaba sendo uma rotina

Se dentro do prg não especificar nada, então o fonte recebe o nome do PRG, e com -n não é aceito porque o conteúdo não tem nome.

Muita gente deixa isso pra depois, mas.... tenho uma novidade:
o Clipper tem limites, mas o Harbour não. O Harbour pode ser usado pra corrigir o PRG !!!
Este é um erro de muitos, esquecer de usar o Harbour pra ajudar.

Vamos lá... o que precisa?
Pegar o nome do PRG, e colocar dentro do fonte, como PROCEDURE...

#include "directry.ch"
PROCEDURE Main

LOCAL aList, aDetails, cNomePrg, cNomeProc, cTxt

   aList := Directory( "*.prg" )
   FOR EACH aDetails IN aList
      cNomePrg := aDetails[ F_NAME ]
      cNomeProc := Substr( cNomePrg, 1, At( ".", cNomePrg ) - 1 )
      cTxt := "PROCEDURE " + cNomePrg + hb_Eol()
      cTxt += hb_Eol()
      cTxt += MemoRead( cNomePrg )
      hb_MemoWrit( cNomePrg, cTxt )
   NEXT

   RETURN


Pronto, resolvido.
Vai pegar cada fonte, e usar o nome do PRG pra colocar a declaração de PROCEDURE dentro do arquivo.
O nome da procedure é o mesmo nome do arquivo, mas sem a extensão ".prg"
Agora é executar o programa de ajuste, e depois retirar dos lugares que não precisava.

Neste caso... o erro é esquecer de usar a programação para se ajudar, pra acelerar "as coisas".
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 23 Jul 2019 12:05

PACK

Parece que muita gente não presenciou isso.
Em Clipper acontecia de um PACK duplicar/triplicar registros.
Não era muito comum, mas acontecia.

Campo MEMO

EU TIVE esse problema.
Só de existir um campo memo no arquivo, o índice gerava erro interno.
INDEX ON código TO arquivo

O campo memo nem fazia parte do índice, e gerava erro no uso, logo após ter sido criado.
Ao remover o campo memo, tudo resolvido.

Nunca procurei saber sobre isso no Harbour, porque já estava acostumado a não usar mais.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 27 Jul 2019 11:38

Em outro post "enxerguei" outro erro comum:

fonte/DO WHILE linguição - muitas linhas de fonte !!!!

Ambiente GUI obriga a dividir em partes, acho que muitos atribuem a facilidade da programação em GUI, e nem percebem que uma grande diferença é essa !!!!

O programador começa com DO WHILE, um dentro do outro, e vai, e o fonte fica com milhares de linhas com um único DO WHILE.
A partir daí, deixa de formatar o fonte pra ele ficar mais magrinho, o fonte fica ainda pior de entender.
A partir daí, vai poluindo e enchendo cada vez mais de anotações, piorando mais a cada vez.

E o linguição numa janela do EDIT do DOS então... já era... fica difícil enxergar tudo e consertar alguma coisa.

Divida em partes/assuntos, vai ficar extremamente mais simples.

Uma opção é usar variáveis PRIVATE... fazer o quê.... e outra é passar variáveis por referência, ou até mesmo #define com constantes - mas é importantíssimo compilar usando -w3 -es2 pra não ter imprevistos.

Aliás... reforçando isso: se tem um fonte de trocentas mil linhas...

- primeiro adote compilação -w3 -es2, dá trabalho, mas vale a pena
- só depois divida em partes, porque a compilação -w3 -es2 vai estar te ajudando a evitar fazer besteira

Vai querer evitar as mensagens de erro, e vai começar a fazer certo só por causa disso.
E com o tempo vai entender que é realmente o modo certo de se fazer.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 27 Jul 2019 12:25

Aproveitar o fonte que foi postado.
É de principiante... principiante pode... programador com mais de 20 anos de experiência não pode...
Mas é um bom exemplo pra mostrar como organizar, e como usar -w3 -es2 pra ajudar na organização.


Do While .t.
   Clear

   Set Date to British
   Set Century On
  // Set Delimiters On
//   Set Delimiters to "[]"

   //VARIAVEIS GERAIS
   nOrdemServico         := 1 //contador autom tico
   cNomeCliente          := space(50)
   cNomeTecnico          := space(40)
   cDescricaoEquipamento := space(50)
   dDataOrdemServico     := Date()
   dDataCompra           := Ctod("")
   nLinha                := 11
   cTipoOrdem            := space(1)
   nProdutoFinalG        := 0
   nServicoFinalG        := 0
   cTotal                := "Total a pagar:"

   //VARIAVEIS GARANTIA

   //VARIAVEIS VALOR TOTAL
   nProdutoFinal  := 0
   nServicoFinal  := 0
   nComissaoTotal := 0

   @ 01,01 say "ORDEM DE SERVICO N:"
   @ 01,22 say nOrdemServico
   @ 03,01 say "Cliente:"
   @ 04,01 say "Tecnico:"
   @ 05,01 say "Descricao do Equipamento:"
   @ 06,01 say "Data da Compra:"
   @ 06,30 say "Data do Servi‡o:"
   @ 07,01 say "Digite P para produto ou S para servico:"

   @ 03,10 Get cNomeCliente          Picture "@!" Valid !Empty(cNomeCliente)
   @ 04,10 Get cNomeTecnico          Picture "@!" Valid !Empty(cNomeTecnico)
   @ 05,27 Get cDescricaoEquipamento Picture "@!" Valid !Empty(cDescricaoEquipamento)
   @ 06,17 Get dDataCompra                        Valid !Empty(dDataCompra)
   @ 06,47 say dDataOrdemServico
   @ 07,41 Get cTipoOrdem            Picture "@!" Valid ((cTipoOrdem = "P") .or. (cTipoOrdem = "S"))
   Read

   //VARIAVEL NOME PRODUTO
   cDescricaoProduto := space(30)
   Do While cTipoOrdem = "P"

      //VARIAVEIS PRODUTO
      nQuantidade       := 0
      nPrecoUnitario    := 0
      nDescontoProduto  := 0

   // Total com  Desconto :Total - (Total*Desconto/100)

      @ 09,01 say "Descricao do Produto:"
      @ 09,23 Get cDescricaoProduto    Picture "@!"                 Valid !Empty(cDescricaoProduto)

      @ 10,01 say "Quantidade"
      @ 10,14 say "Preco Unit."
      @ 10,35 say "Desconto"
      @ 10,50 say "Total"
      @ 16,01 say "Total Final:"

      @ nLinha,01 Get nQuantidade      Picture "99999"               Valid nQuantidade      >= 1
      @ nLinha,14 Get nPrecoUnitario   Picture "@E 9,999,999,999.99" Valid nPrecoUnitario   >= 1
      @ nLinha,35 Get nDescontoProduto Picture "99999.99"            Valid nDescontoProduto >= 0
      Read

      //TOTAL UNITARIO
      nTotalProduto := (nPrecoUnitario * nQuantidade)-((nPrecoUnitario * nQuantidade)*(nDescontoProduto/100))
      @ nLinha,50 say +AllTrim(Transform(nTotalProduto, "@E 999,999,999,999.99"))

      //TOTAL FINAL
      nProdutoFinal := nProdutoFinal + nTotalProduto

      If nLinha > 16
         @ nLinha,01 Clear to 15,70
         nLinha := 11
      Endif

      nGarantiaProduto := dDataOrdemServico - dDataCompra // 2 anos (730 ou 731 dias)

      If nGarantiaProduto <= 731
         @ 17,01 say cTotal
         @ 17,16 say nProdutoFinalG Picture "@E 9,999.99"
      else
         @ 17,01 say cTotal
         @ 17,16 say nProdutoFinal  Picture "@E 999,999,999.99"
      Endif

      If LastKey() == 27
         nAviso1 := Alert("O que deseja fazer?",{"Finalizar e inicar outro chamado","Apenas Finalizar", "Cancelar"})
         If nAviso1 = 1
            @ 16,13 say nProdutoFinal Picture "@E 999,999,999.99"
            @ 07,01 say "Digite P para produto ou S para servico:"
            @ 07,41 Get cTipoOrdem            Picture "@!" Valid ((cTipoOrdem = "P") .or. (cTipoOrdem = "S"))
            Read
         elseif nAviso1 = 2
            @ 16,13 say nProdutoFinal Picture "@E 999,999,999.99"
         else
            exit
         Endif
      Endif

      nLinha++
   Enddo

   //VARIAVEL NOME SERVICO
   cDescricaoServico := space(30)
   Do While cTipoOrdem = "S"

      //VARIAVEIS SERVI€O
      nDescontoServico  := 0
      nComissaoTecnico  := 0
      nValorServico     := 0

      @ 09,01 say "Descricao do Servico:"
      @ 09,23 Get cDescricaoServico Picture "@!"   Valid !Empty(cDescricaoServico)
      Read

      @ 10,01 say "Valor"
      @ 10,25 say "Desconto"
      @ 10,35 say "Comissao"
      @ 10,55 say "Total"
      @ 16,01 say "Total Final:"

      @ nLinha,01 Get nValorServico     Picture "@E 999,999,999.99" Valid nValorServico    >=1
      @ nLinha,25 Get nDescontoServico  Picture "99999.99"          Valid nDescontoServico >= 1
      @ nLinha,35 Get nComissaoTecnico  Picture "99999.99"          Valid nComissaoTecnico >= 0
      Read

      nTotalServico := nValorServico + (nValorServico*(nComissaoTecnico/100)) - (nValorServico*(nDescontoServico/100))
      @ nLinha,55 say +AllTrim(Transform(nTotalServico, "@E 999,999,999,999.99"))

      nComissaoTotal := nComissaoTotal + (nValorServico*(nComissaoTecnico/100))
      nServicoFinal := nServicoFinal + nTotalServico

      @ 18,01 say "Total Comissao:"
      @ 18,18 say Transform (nComissaoTotal, "@E 999,999.99")

      If nLinha > 16
         @ nLinha,01 Clear to 15,70
         nLinha := 11
      Endif

      If LastKey() == 27
         nAviso2 := Alert("Deseja finalizar a ordem de servico?",{"Sim","Nao"})
         If nAviso2 = 1
         @ 16,13 say nServicoFinal Picture "@E 999,999,999.99"
         else
            loop
         Endif
      Endif

      nGarantiaServico := dDataOrdemServico - dDataCompra // 1 ano  (365 ou 366 dias)

      If nGarantiaServico <= 366
         @ 17,01 say cTotal
         nProdutoFinalG := 0
         @ 17,16 say nServicoFinalG Picture "@E 9,999.99"
      else
         @ 17,01 say cTotal
         @ 17,16 say nServicoFinal  Picture "@E 999,999,999.99"
      Endif
      nLinha++
   Enddo
   If LastKey() == 27
      nAviso := Alert("Deseja mesmo cancelar?", {"Sim","Nao"})
      If nAviso = 1
         Exit
      Endif
   EndIf

   nOrdemServico += 1
   nOrdemServico++

Enddo


Qualquer erro que for procurar... complicou... tem que ficar paginando tudo pra cima e pra baixo.
Vamos começar compilando com -w3 -es2.

d:\temp>hbmk2 codos -w3 -es2
hbmk2: Processing environment options: -comp=mingw
hbmk2: Processing configuration: d:\harbour\bin\hbmk.hbc
Harbour 3.4.0dev (8289a47fd1) (2019-06-07 14:14)
Copyright (c) 1999-2019, https://github.com/JoseQuintas/harbour34/
Compiling 'codos.prg'...
codos.prg(4) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(4) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(12) Warning W0001 Ambiguous reference 'NORDEMSERVICO'
codos.prg(13) Warning W0001 Ambiguous reference 'CNOMECLIENTE'
codos.prg(14) Warning W0001 Ambiguous reference 'CNOMETECNICO'
codos.prg(15) Warning W0001 Ambiguous reference 'CDESCRICAOEQUIPAMENTO'
codos.prg(16) Warning W0001 Ambiguous reference 'DDATAORDEMSERVICO'
codos.prg(17) Warning W0001 Ambiguous reference 'DDATACOMPRA'
codos.prg(18) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(19) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(20) Warning W0001 Ambiguous reference 'NPRODUTOFINALG'
codos.prg(21) Warning W0001 Ambiguous reference 'NSERVICOFINALG'
codos.prg(22) Warning W0001 Ambiguous reference 'CTOTAL'
codos.prg(30) Warning W0001 Ambiguous reference 'NPRODUTOFINAL'
codos.prg(31) Warning W0001 Ambiguous reference 'NSERVICOFINAL'
codos.prg(32) Warning W0001 Ambiguous reference 'NCOMISSAOTOTAL'
codos.prg(35) Warning W0001 Ambiguous reference 'NORDEMSERVICO'
codos.prg(43) Warning W0001 Ambiguous reference 'CNOMECLIENTE'
codos.prg(43) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(43) Warning W0001 Ambiguous reference 'CNOMECLIENTE'
codos.prg(43) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(44) Warning W0001 Ambiguous reference 'CNOMETECNICO'
codos.prg(44) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(44) Warning W0001 Ambiguous reference 'CNOMETECNICO'
codos.prg(44) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(45) Warning W0001 Ambiguous reference 'CDESCRICAOEQUIPAMENTO'
codos.prg(45) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(45) Warning W0001 Ambiguous reference 'CDESCRICAOEQUIPAMENTO'
codos.prg(45) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(46) Warning W0001 Ambiguous reference 'DDATACOMPRA'
codos.prg(46) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(46) Warning W0001 Ambiguous reference 'DDATACOMPRA'
codos.prg(46) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(47) Warning W0001 Ambiguous reference 'DDATAORDEMSERVICO'
codos.prg(48) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(48) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(48) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(48) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(48) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(49) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(49) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(49) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(53) Warning W0001 Ambiguous reference 'CDESCRICAOPRODUTO'
codos.prg(54) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(57) Warning W0001 Ambiguous reference 'NQUANTIDADE'
codos.prg(58) Warning W0001 Ambiguous reference 'NPRECOUNITARIO'
codos.prg(59) Warning W0001 Ambiguous reference 'NDESCONTOPRODUTO'
codos.prg(65) Warning W0001 Ambiguous reference 'CDESCRICAOPRODUTO'
codos.prg(65) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(65) Warning W0001 Ambiguous reference 'CDESCRICAOPRODUTO'
codos.prg(65) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(73) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(73) Warning W0001 Ambiguous reference 'NQUANTIDADE'
codos.prg(73) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(73) Warning W0001 Ambiguous reference 'NQUANTIDADE'
codos.prg(73) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(74) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(74) Warning W0001 Ambiguous reference 'NPRECOUNITARIO'
codos.prg(74) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(74) Warning W0001 Ambiguous reference 'NPRECOUNITARIO'
codos.prg(74) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(75) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(75) Warning W0001 Ambiguous reference 'NDESCONTOPRODUTO'
codos.prg(75) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(75) Warning W0001 Ambiguous reference 'NDESCONTOPRODUTO'
codos.prg(75) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(76) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(76) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(76) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(79) Warning W0001 Ambiguous reference 'NPRECOUNITARIO'
codos.prg(79) Warning W0001 Ambiguous reference 'NQUANTIDADE'
codos.prg(79) Warning W0001 Ambiguous reference 'NPRECOUNITARIO'
codos.prg(79) Warning W0001 Ambiguous reference 'NQUANTIDADE'
codos.prg(79) Warning W0001 Ambiguous reference 'NDESCONTOPRODUTO'
codos.prg(79) Warning W0001 Ambiguous reference 'NTOTALPRODUTO'
codos.prg(80) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(80) Warning W0001 Ambiguous reference 'NTOTALPRODUTO'
codos.prg(83) Warning W0001 Ambiguous reference 'NPRODUTOFINAL'
codos.prg(83) Warning W0001 Ambiguous reference 'NTOTALPRODUTO'
codos.prg(83) Warning W0001 Ambiguous reference 'NPRODUTOFINAL'
codos.prg(85) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(86) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(86) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(87) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(90) Warning W0001 Ambiguous reference 'DDATAORDEMSERVICO'
codos.prg(90) Warning W0001 Ambiguous reference 'DDATACOMPRA'
codos.prg(90) Warning W0001 Ambiguous reference 'NGARANTIAPRODUTO'
codos.prg(92) Warning W0001 Ambiguous reference 'NGARANTIAPRODUTO'
codos.prg(93) Warning W0001 Ambiguous reference 'CTOTAL'
codos.prg(94) Warning W0001 Ambiguous reference 'NPRODUTOFINALG'
codos.prg(96) Warning W0001 Ambiguous reference 'CTOTAL'
codos.prg(97) Warning W0001 Ambiguous reference 'NPRODUTOFINAL'
codos.prg(101) Warning W0001 Ambiguous reference 'NAVISO1'
codos.prg(102) Warning W0001 Ambiguous reference 'NAVISO1'
codos.prg(103) Warning W0001 Ambiguous reference 'NPRODUTOFINAL'
codos.prg(105) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(105) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(105) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(105) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(105) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(106) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(106) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(106) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(107) Warning W0001 Ambiguous reference 'NAVISO1'
codos.prg(108) Warning W0001 Ambiguous reference 'NPRODUTOFINAL'
codos.prg(115) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(115) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(119) Warning W0001 Ambiguous reference 'CDESCRICAOSERVICO'
codos.prg(120) Warning W0001 Ambiguous reference 'CTIPOORDEM'
codos.prg(123) Warning W0001 Ambiguous reference 'NDESCONTOSERVICO'
codos.prg(124) Warning W0001 Ambiguous reference 'NCOMISSAOTECNICO'
codos.prg(125) Warning W0001 Ambiguous reference 'NVALORSERVICO'
codos.prg(129) Warning W0001 Ambiguous reference 'CDESCRICAOSERVICO'
codos.prg(129) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(129) Warning W0001 Ambiguous reference 'CDESCRICAOSERVICO'
codos.prg(129) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(130) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(130) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(130) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(138) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(138) Warning W0001 Ambiguous reference 'NVALORSERVICO'
codos.prg(138) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(138) Warning W0001 Ambiguous reference 'NVALORSERVICO'
codos.prg(138) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(139) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(139) Warning W0001 Ambiguous reference 'NDESCONTOSERVICO'
codos.prg(139) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(139) Warning W0001 Ambiguous reference 'NDESCONTOSERVICO'
codos.prg(139) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(140) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(140) Warning W0001 Ambiguous reference 'NCOMISSAOTECNICO'
codos.prg(140) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(140) Warning W0001 Ambiguous reference 'NCOMISSAOTECNICO'
codos.prg(140) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(141) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(141) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(141) Warning W0001 Ambiguous reference 'GETLIST'
codos.prg(143) Warning W0001 Ambiguous reference 'NVALORSERVICO'
codos.prg(143) Warning W0001 Ambiguous reference 'NVALORSERVICO'
codos.prg(143) Warning W0001 Ambiguous reference 'NCOMISSAOTECNICO'
codos.prg(143) Warning W0001 Ambiguous reference 'NVALORSERVICO'
codos.prg(143) Warning W0001 Ambiguous reference 'NDESCONTOSERVICO'
codos.prg(143) Warning W0001 Ambiguous reference 'NTOTALSERVICO'
codos.prg(144) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(144) Warning W0001 Ambiguous reference 'NTOTALSERVICO'
codos.prg(146) Warning W0001 Ambiguous reference 'NCOMISSAOTOTAL'
codos.prg(146) Warning W0001 Ambiguous reference 'NVALORSERVICO'
codos.prg(146) Warning W0001 Ambiguous reference 'NCOMISSAOTECNICO'
codos.prg(146) Warning W0001 Ambiguous reference 'NCOMISSAOTOTAL'
codos.prg(147) Warning W0001 Ambiguous reference 'NSERVICOFINAL'
codos.prg(147) Warning W0001 Ambiguous reference 'NTOTALSERVICO'
codos.prg(147) Warning W0001 Ambiguous reference 'NSERVICOFINAL'
codos.prg(151) Warning W0001 Ambiguous reference 'NCOMISSAOTOTAL'
codos.prg(153) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(154) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(154) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(155) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(159) Warning W0001 Ambiguous reference 'NAVISO2'
codos.prg(160) Warning W0001 Ambiguous reference 'NAVISO2'
codos.prg(161) Warning W0001 Ambiguous reference 'NSERVICOFINAL'
codos.prg(167) Warning W0001 Ambiguous reference 'DDATAORDEMSERVICO'
codos.prg(167) Warning W0001 Ambiguous reference 'DDATACOMPRA'
codos.prg(167) Warning W0001 Ambiguous reference 'NGARANTIASERVICO'
codos.prg(169) Warning W0001 Ambiguous reference 'NGARANTIASERVICO'
codos.prg(170) Warning W0001 Ambiguous reference 'CTOTAL'
codos.prg(171) Warning W0001 Ambiguous reference 'NPRODUTOFINALG'
codos.prg(172) Warning W0001 Ambiguous reference 'NSERVICOFINALG'
codos.prg(174) Warning W0001 Ambiguous reference 'CTOTAL'
codos.prg(175) Warning W0001 Ambiguous reference 'NSERVICOFINAL'
codos.prg(177) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(177) Warning W0001 Ambiguous reference 'NLINHA'
codos.prg(180) Warning W0001 Ambiguous reference 'NAVISO'
codos.prg(181) Warning W0001 Ambiguous reference 'NAVISO'
codos.prg(186) Warning W0001 Ambiguous reference 'NORDEMSERVICO'
codos.prg(186) Warning W0001 Ambiguous reference 'NORDEMSERVICO'
codos.prg(187) Warning W0001 Ambiguous reference 'NORDEMSERVICO'
codos.prg(187) Warning W0001 Ambiguous reference 'NORDEMSERVICO'


Normal, declarar variáveis....
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 27 Jul 2019 12:28

PROCEDURE Main

LOCAL nOrdemServico, cNomeCliente, cNomeTecnico, cDescricaoEquipamento
LOCAL dDataOrdemServico, dDataCompra, nLinha, cTipoOrdem
LOCAL nProdutoFinalG, nServicoFinalG, cTotal, nComissaoTecnico
LOCAL nValorServico, nDescontoServico, nServicoFinal, nComissaoTotal
LOCAL nTotalServico, nAviso2, nGarantiaServico, nAviso, cDescricaoServico
LOCAL nDescontoProduto, nPrecoUnitario, nQuantidade, nGarantiaProduto
LOCAL nAviso1, nProdutoFinal, cDescricaoProduto, nTotalProduto
LOCAL GetList := {}


Variáveis declaradas

Compiling 'codos.prg'...
codos.prg(200) Warning W0032 Variable 'GETLIST' is assigned but not used in function 'MAIN(10)'
codos.prg(200) Warning W0032 Variable 'NPRODUTOFINALG' is assigned but not used in function 'MAIN(180)'
codos.prg(200) Warning W0032 Variable 'NORDEMSERVICO' is assigned but not used in function 'MAIN(196)'


Nem é tão grande o fonte, mas confirmar sobre essas linhas serem inúteis vai ser trabalhoso.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 27 Jul 2019 12:35

Até que nem tanto.....

Do While .t.
   nOrdemServico := 1
...
   nOrdemServico += 1
   nOrdemServico++
Enddo


Se está sendo sempre atribuído 1 ao número, somar 1 não serve pra nada...
Estar somando 1 duas vezes não foi indicado como erro, porque pode acontecer...

Legal aqui. Só de declarar variáveis já encontramos erro no fonte.
Como eu já disse, -w3 -es2 avisa sobre possíveis problemas, é como um ajudante conferindo o fonte , mas baseado nas informações que colocamos no fonte - declaração de variáveis.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 27 Jul 2019 16:59

apenas didivido, e variáveis PRIVATE.

MEMVAR nOrdemServico
MEMVAR cNomeCliente, cNomeTecnico, cDescricaoEquipamento
MEMVAR dDataOrdemServico, dDataCompra, nLinha, cTipoOrdem
MEMVAR nProdutoFinalG, nServicoFinalG, cTotal, nComissaoTecnico
MEMVAR nValorServico, nDescontoServico, nServicoFinal, nComissaoTotal
MEMVAR nTotalServico, nAviso2, nGarantiaServico, nAviso, cDescricaoServico
MEMVAR nDescontoProduto, nPrecoUnitario, nQuantidade, nGarantiaProduto
MEMVAR nAviso1, nProdutoFinal, cDescricaoProduto, nTotalProduto, nDigita
MEMVAR nAlert

PROCEDURE Main

   PRIVATE nOrdemServico := 1
   PRIVATE cNomeCliente          := Space(50)
   PRIVATE cNomeTecnico          := Space(40)
   PRIVATE cDescricaoEquipamento := Space(50)
   PRIVATE dDataOrdemServico     := Date()
   PRIVATE dDataCompra           := Ctod("")
   PRIVATE nLinha                := 11
   PRIVATE cTipoOrdem            := Space(1)
   PRIVATE nProdutoFinalG        := 0
   PRIVATE nServicoFinalG        := 0
   PRIVATE cTotal                := "Total a pagar:"

   CLS

   SET DATE to British
   SET CENTURY ON
   // Set Delimiters On
   //   Set Delimiters to "[]"

   DO WHILE .T.

      DigitaOS()
      nAlert := Alert( "Digita mais OS", { "Sim", "Nao" } )
      IF nAlert = 2
         EXIT
      ENDIF
      nOrdemServico += 1
   ENDDO

   RETURN

STATIC FUNCTION DigitaOS()

   LOCAL GetList := {}
   //VARIAVEIS GERAIS

   //VARIAVEIS GARANTIA

   //VARIAVEIS VALOR TOTAL
   nProdutoFinal  := 0
   nServicoFinal  := 0
   nComissaoTotal := 0

   @ 01,01 SAY "ORDEM DE SERVICO N:"
   @ 01,22 SAY nOrdemServico
   @ 03,01 SAY "Cliente:"
   @ 04,01 SAY "Tecnico:"
   @ 05,01 SAY "Descricao do Equipamento:"
   @ 06,01 SAY "Data da Compra:"
   @ 06,30 SAY "Data do Servi‡o:"
   @ 07,01 SAY "Digite P para produto ou S para servico:"

   @ 03,10 GET cNomeCliente          PICTURE "@!" Valid !Empty(cNomeCliente)
   @ 04,10 GET cNomeTecnico          PICTURE "@!" Valid !Empty(cNomeTecnico)
   @ 05,27 GET cDescricaoEquipamento PICTURE "@!" Valid !Empty(cDescricaoEquipamento)
   @ 06,17 GET dDataCompra                        Valid !Empty(dDataCompra)
   @ 06,47 SAY dDataOrdemServico
   @ 07,41 GET cTipoOrdem            PICTURE "@!" Valid ((cTipoOrdem = "P") .OR. (cTipoOrdem = "S"))
   READ

   DO WHILE .T.
      nAlert := Alert( "Digita Produto", "Digita Servico", "Encerra" )
      IF nDigita = 3
         EXIT
      ENDIF
      IF nDigita != 1 .AND. nDigita != 2
         LOOP
      ENDIF
      IF nDigita == 2
         DigitaProduto()
      ELSE
         DigitaServico()
      ENDIF
   ENDDO

   RETURN NIL

STATIC FUNCTION DigitaProduto()

   LOCAL GetList := {}

   //VARIAVEL NOME PRODUTO
   cDescricaoProduto := Space(30)
   DO WHILE cTipoOrdem = "P"

      //VARIAVEIS PRODUTO
      nQuantidade       := 0
      nPrecoUnitario    := 0
      nDescontoProduto  := 0

      // Total com  Desconto :Total - (Total*Desconto/100)

      @ 09,01 SAY "Descricao do Produto:"
      @ 09,23 GET cDescricaoProduto    PICTURE "@!"                 Valid !Empty(cDescricaoProduto)

      @ 10,01 SAY "Quantidade"
      @ 10,14 SAY "Preco Unit."
      @ 10,35 SAY "Desconto"
      @ 10,50 SAY "Total"
      @ 16,01 SAY "Total Final:"

      @ nLinha,01 GET nQuantidade      PICTURE "99999"               Valid nQuantidade      >= 1
      @ nLinha,14 GET nPrecoUnitario   PICTURE "@E 9,999,999,999.99" Valid nPrecoUnitario   >= 1
      @ nLinha,35 GET nDescontoProduto PICTURE "99999.99"            Valid nDescontoProduto >= 0
      READ

      //TOTAL UNITARIO
      nTotalProduto := (nPrecoUnitario * nQuantidade)-((nPrecoUnitario * nQuantidade)*(nDescontoProduto/100))
      @ nLinha,50 SAY +AllTrim(Transform(nTotalProduto, "@E 999,999,999,999.99"))

      //TOTAL FINAL
      nProdutoFinal := nProdutoFinal + nTotalProduto

      IF nLinha > 16
         @ nLinha,01 CLEAR TO 15,70
         nLinha := 11
      ENDIF

      nGarantiaProduto := dDataOrdemServico - dDataCompra // 2 anos (730 ou 731 dias)

      IF nGarantiaProduto <= 731
         @ 17,01 SAY cTotal
         @ 17,16 SAY nProdutoFinalG PICTURE "@E 9,999.99"
      ELSE
         @ 17,01 SAY cTotal
         @ 17,16 SAY nProdutoFinal  PICTURE "@E 999,999,999.99"
      ENDIF

      IF LastKey() == 27
         nAviso1 := Alert("O que deseja fazer?",{"Finalizar e inicar outro chamado","Apenas Finalizar", "Cancelar"})
         IF nAviso1 = 1
            @ 16,13 SAY nProdutoFinal PICTURE "@E 999,999,999.99"
            @ 07,01 SAY "Digite P para produto ou S para servico:"
            @ 07,41 GET cTipoOrdem            PICTURE "@!" Valid ((cTipoOrdem = "P") .OR. (cTipoOrdem = "S"))
            READ
         ELSEIF nAviso1 = 2
            @ 16,13 SAY nProdutoFinal PICTURE "@E 999,999,999.99"
         ELSE
            EXIT
         ENDIF
      ENDIF

      nLinha++
   ENDDO

   RETURN NIL

STATIC FUNCTION DigitaServico()

   LOCAL GetList := {}

   //VARIAVEL NOME SERVICO
   cDescricaoServico := Space(30)
   DO WHILE cTipoOrdem = "S"

      //VARIAVEIS SERVI€O
      nDescontoServico  := 0
      nComissaoTecnico  := 0
      nValorServico     := 0

      @ 09,01 SAY "Descricao do Servico:"
      @ 09,23 GET cDescricaoServico PICTURE "@!"   Valid !Empty(cDescricaoServico)
      READ

      @ 10,01 SAY "Valor"
      @ 10,25 SAY "Desconto"
      @ 10,35 SAY "Comissao"
      @ 10,55 SAY "Total"
      @ 16,01 SAY "Total Final:"

      @ nLinha,01 GET nValorServico     PICTURE "@E 999,999,999.99" Valid nValorServico    >=1
      @ nLinha,25 GET nDescontoServico  PICTURE "99999.99"          Valid nDescontoServico >= 1
      @ nLinha,35 GET nComissaoTecnico  PICTURE "99999.99"          Valid nComissaoTecnico >= 0
      READ

      nTotalServico := nValorServico + (nValorServico*(nComissaoTecnico/100)) - (nValorServico*(nDescontoServico/100))
      @ nLinha,55 SAY +AllTrim(Transform(nTotalServico, "@E 999,999,999,999.99"))

      nComissaoTotal := nComissaoTotal + (nValorServico*(nComissaoTecnico/100))
      nServicoFinal := nServicoFinal + nTotalServico

      @ 18,01 SAY "Total Comissao:"
      @ 18,18 SAY Transform (nComissaoTotal, "@E 999,999.99")

      IF nLinha > 16
         @ nLinha,01 CLEAR TO 15,70
         nLinha := 11
      ENDIF

      IF LastKey() == 27
         nAviso2 := Alert("Deseja finalizar a ordem de servico?",{"Sim","Nao"})
         IF nAviso2 = 1
            @ 16,13 SAY nServicoFinal PICTURE "@E 999,999,999.99"
         ELSE
            LOOP
         ENDIF
      ENDIF

      nGarantiaServico := dDataOrdemServico - dDataCompra // 1 ano  (365 ou 366 dias)

      IF nGarantiaServico <= 366
         @ 17,01 SAY cTotal
         //nProdutoFinalG := 0
         @ 17,16 SAY nServicoFinalG PICTURE "@E 9,999.99"
      ELSE
         @ 17,01 SAY cTotal
         @ 17,16 SAY nServicoFinal  PICTURE "@E 999,999,999.99"
      ENDIF
      nLinha++
   ENDDO

   RETURN NIL


O ideal, agora que está dividido, é organizar as variáveis.
Por exemplo....
variáveis de produto, só interessam pra rotina de produtos.
variáveis de serviço, só interessam pra rotina de serviços.
E por aí vai.
Acaba sendo não só a divisão de rotinas, mas a divisão das variáveis, cada uma no seu assunto.
E menos variáveis... menos complicação no fonte. (serão as mesmas de antes, mas cada uma aonde é utilizada)
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 27 Jul 2019 17:02

Chamar atenção para uma coisa:
Ao compilar com -w3 -es2, apareceram os erros com variáveis.
Se eu fosse mexer antes disso, poderia parecer que as alterações que causaram problema.
E aí... dá-lhe voltar o fonte anterior pra procurar o que foi mexido.... e lá vai perda de tempo.
Por isso é bom começar pela análise das variáveis, antes de dividir em partes.
O que pareceu perder tempo, é ganho de tempo, porque só tem caminho de ir em frente, sem precisar voltar atrás.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Erros comuns - Clipper e Harbour

Mensagempor JoséQuintas » 27 Jul 2019 17:07

Sobre outro erro do GetList....
É interessante também porque todos esquecem disto.

LOCAL GetList := {}
CLEAR


Isso dá erro em compilação -w3 -es2

Porque?
CLEAR

CLEAR equivale a CLS; GetList := {}
Com isso, estava duas vezes atribuindo valor a GetList.

Pra limpar a tela é CLS.
Pra limpar tela e também gets pendentes é CLEAR.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 11905
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 12 vezes
Mens.Curtidas: 759 vezes

Próximo



Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 2 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro