Clipper On Line • Ver Tópico - Práticas que facilitam programar Clipper/Harbour

Práticas que facilitam programar Clipper/Harbour

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

Moderador: Moderadores

 

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 16:12

A intenção é tentar ajudar a trazer alguns programadores que ficaram pra trás, com técnicas que ajudam no dia a dia e facilitam o trabalho.
Tem coisas que eu achava até um certo tipo de frescura, ou que aparentemente só serviam pra complicar.
Mas conforme o tempo passa ou o aplicativo cresce, vemos que ajuda muito ter isso em prática.

Uma coisa, que já mencionei muito por aqui, é deixar os fontes simples e fáceis - para HUMANOS.
Não adianta ganhar 1 segundo de processamento, se perde minutos ou horas pra entender o que fez depois.
Tem que pensar em você: é você quem vai mexer no fonte, então tem que ser fácil pra você entender.
Quanto mais fácil entende, e mais rápido altera, mais ganha tempo, e mais avança no conhecimento de programar.

Parece brincadeira, mas não é.
Isso depende de acostumar a trabalhar assim.
Se acostumar a fazer fácil de entender, vai sempre tentar fazer do jeito fácil de entender, e vai ter soluções prontas e fáceis de usar.

Fácil não significa não ter trabalho. Às vezes pra ficar fácil temos até mais trabalho.
Mas... ficando fácil... tá fácil.

No ano passado assumi um sistema em Clipper Summer.
Como é fonte totalmente diferente do que estou acostumado a fazer, foi aí que percebi como faz muita diferença algumas técnicas simples.
Serviu pra comprovar que algumas coisas realmente tornam a vida do programador fácil, mesmo dando trabalho.

Dar trabalho pra digitar não é problema, o problema é dar trabalho pra entender.
Pra mexer num sistema, fica mais fácil mexer se tivermos segurança no que estamos fazendo.
Mais do que entender o sistema, é entender os fontes, que podem ter sido feitos por outra pessoa, ou até por nós mesmos tempos atrás.

Vamos lá...
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 16:27

Nomes de variáveis e campos padronizados.

Isso é muito importante.
Chamar uma variável de JUCA, pode ser divertido, até ter que mexer nesse fonte tempos depois, e ter que vasculhar fonte pra descobrir o que contém a veriável.
Então, pra facilitar, é bom usar nomes coerentes com o conteúdo.
Se é opção, pode se chamar OPC.
Se é num relatório pra escolher a ordem, poderia ser OpcOrdem.
Não importa em que parte do fonte está, opcOrdem vai saber que é a opção de ordem.

E se isso se estender aos arquivos, complicou.
Vai ter que se lembrar de cada nome, pra não usar nome de campo de arquivo em nome de variável.
DATA, será que é variável ou campo de arquivo?
E o programa? Quando escrever DATA e existir no arquivo e em variável, qual dos dois ele vai considerar?
É uma coisa simples, mas evita problemas futuros.

Cada um tem seu jeito de padronizar.
Aqui uso duas letras pra identificar o arquivo, exemplo CD pra cadastro. CDCODIGO, CDNOME, etc.
Pra variável uso duas formas diferentes: por exemplo mCDCODIGO, onde m já indica variável, e CDCODIGO porque vai conter o que vai/veio do cadastro de clientes. Pras demais, nCodigo por exemplo para variável numérica contendo código.
No REPLACE fica fácil: REPLACE cdCodigo WITH mcdCodigo, não tem erro.
Na busca também não tem erro: mcdCodigo := cdCodigo

E o mais interessante:
Se um campo de um arquivo estiver com conteúdo errado, por exemplo CDSALDO, é só pesquisar em todos os fontes o nome CDSALDO, e teremos a visão rápida de todos os fontes que mexem com CDSALDO.
O mesmo se quisermos alterar o tamanho de um campo. Sabendo o nome, não vai escapar um.
E por aí vai.

Relacionado a isso temos também o ALIAS do arquivo.

SELECT 1
SELECT 2

Não precisa economizar, pode digitar o ALIAS que não vai afetar velocidade, só vai te ajudar:

SELECT CLIENTES
SELECT PRODUTOS

Também no replace:
REPLACE CLIENTES->cdCodigo WITH mcdCodigo

Mesmo motivo acima: quiser saber fontes que mexem no arquivo CLIENTES, só pesquisar CLIENTES. (nome diferenciado como nome do arquivo também ajuda).
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 16:51

Aqui merece um tópico a parte:

Quantas vezes já não aconteceu de erro em execução por causa de digitar nome errado de variável?
Bem que o compilador poderia verificar isso.... mas ele pode, depende de você.

Não é fácil modificar programa antigo pra isso, mas dá pra fazer.
O Cipper e o Harbour tem a opção de compilar usando -w3 -es2.
Isso não é novidade, os dois tem a opção faz tempo.
Como uma ajuda extra, isso verifica se o nome que digitou está correto.
Mas como custo pra isso, é necessário declarar todas as variáveis e campos usados.
Tudo bem, trabalho a mais pra digitar, mas vai te facilitar sempre que for mexer no fonte.
Perde tempo na hora de fazer, mas ganha tempo sempre.
Simples: geralmente gastamos mais tempo alterando do que criando, então se está facilitando pra alterar, melhor.

É declarar variáveis locais como locais, de preferência só usar esse tipo de variável, e no caso de fontes antigos, que não tem jeito, apenas indicar como MEMVAR.
E no caso de campos de arquivo, FIELDS, até que coloque diretamente no fonte.

temporário:
FIELD cdCodigo
REPLACE cdCodigo WITH mcdCodigo


definitivo:
REPLACE cliente->cdCodigo WITH mcdCodigo
[/code]

O que fiz nesse sistema em Summer, pra facilitar com o fonte velho, foi criar isso via Clipper/Harbour.

Nos fontes:
include "fontevelho.ch"


E uma rotina pra "fabricar" fontevelho.ch, pegando toda a estrutura de todos os arquivos e já declarando como FIELD.
Algo como:
SET ALTERNATE TO fontevelho.ch
SET ALTERNATE ON
SET CONSOLE OFF
oFiles := Directory( "*.dbf" )
FOR nCont = 1 TO Len( oFiles )
   USE ( oFiles[ nCont, 1 ] )
   FOR nCont2 = 1 TO FCount()
      ? "FIELD " + FieldName( nCont2 )
   NEXT
   USE
NEXT


Não é a saída ideal, mas pelo menos te ajuda a usar mais rápido o padrão -w3 -es2 para fontes velhos.
Isso vai deixar tudo que é nome de campo declarado.
O que sobrar de erro na compilação, vai ser declarar como MEMVAR.

Ok. Menos mal, depois disso pode fixar -w3 -es2 como padrão e seguir em frente.
Já vai ter o aviso sempre que digitar nome de variável errado.
A partir daí, conforme for criando ou alterando fontes, pode já usar o "pente fino", e já fazer direito.
A partir daí a idéia vai ser eliminar a necessidade do #include "fontevelho.ch", conforme for sobrando tempo.
Dá pra fazer um fonte de cada vez, deixando o #include até ficar pronto.

Vai de cada um. De repente, eliminar um campo de cada vez do arquivo ch, e já acertar aquele campo em todos os fontes.
Ou deixa como está, e se preocupa só com os novos fontes.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 17:06

Validação

Tem rotinas que reduzem código.
Uma antiga é um tipo de seek em qualquer área com qualquer índice.
Algo como

@ 1, 0 GET cCodigo VALID Lookup( "clientes", 1 )
@ 2, 0 GET cCodigo VALID clientes->( dbSeek( cCodigo ) )


Isso é interessante, mas pode complicar com o tempo, ter opções de aceitar zerado ou não, etc.
Uma coisa que uso fácil, é uma rotina de validação com o nome que interessa.

@ 1, 0 GET cCodigo VALID ClienteValida( @cCodigo )


Qual a rotina de validar cliente? ClienteValida()
Não importa linguagem de programação, se o campo é numérico ou caractere, se aceita em branco ou não, tudo fica centralizado em ClienteValida()
Se vai mexer no tamanho do campo depois, ou qualquer outra coisa, é só alterar ClienteValida().
É caractere e precisa de zeros... ok, altera em ClienteValida()
Tem casos que aceita zero, ok, altere ClienteValida() pra aceitar um parâmetro a mais indicando isso.
E por aí vai.
Para um fonte novo, já vai ter a validação pronta.

E como é uma única validação para o sistema inteiro, o que perderia pra fazer/digitar várias rotinas, já perde fazendo uma rotina caprichada que resolve tudo que é situação que possa aparecer.
Por exemplo, a rotina pode ter que mudar o DBF em uso, pode ter que mudar índice em uso, então já deixa a rotina preparada pra fazer isso e devolver a situação anterior.
Pode acrescentar pra mostrar um texto ou não, pra já servir pra preencher a tela quando o usário digitar o código, etc. etc.

É como eu disse: fazer simples não significa facilitar ou ter menos trabalho.
Vai ter trabalho na criação da rotina.
Mas depois, vai ser só alegria, fáci, fácil.

Melhor do que toda vez perder tempo criando rotina pra validar cliente, ou pra entender um fonte anterior.
É programar pensando em facilitar o futuro.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 17:13

Numa rotina de tela:

@ 1, 0 SAY "codigo..." GET mCodigo
@ 2, 0 SAY "nome..." GET mNome
@ 3, 0 SAY "Endereco..." GET mEndereco
READ


Toda vez que tiver um campo novo, ou quiser mudar a ordem, vai ter que mexer nas linhas.
Pra que complicar, facilite:

@ 1, 0 SAY "codigo..." GET mCodigo
@ Row() + 1, 0 SAY "nome..." GET mNome
@ Row() + 1, 0 SAY "Endereco..." GET mEndereco
READ


Pronto, deu mais trabalho pra digitar, mas pode acrescentar campos à vontade, mudar ordem à vontade, sem precisar mexer no número da linha.
Mas é na frente, e não na linha de baixo.
Tudo bem, use Col() que é a coluna atual.

@ 1, 0 SAY "Intervalo  desde" GET mDesde
@ Row(), Col() + 2 SAY "ate" GET mAte
READ


Pronto, isso já desenha a tela automático, não importa tamanho dos campos.
Já facilita o futuro.

Usa a última linha da tela pra mensagens....
@ 24, 0 SAY Space(80)
@ 24, 0 SAY "mensagem"


Se alterar linhas/colunas da tela, vai ter que mexer no sistema inteiro. Use MaxRow() e MaxCol()

@ MaxRow(), 0 SAY Space( MaxCol() + 1)
@ MaxRow(), 0 SAY "mensagem"


Pronto, pode inventar de mexer na tela à vontade, que o sistema se ajusta automaticamente.

Isso é programar pensando no futuro, pensando em facilitar a vida do programador, que é sua vida.
Dá trabalho pra digitar, mas te facilita sempre.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 17:31

#define

Por muito tempo achei isso uma espécie de complicação ou frescura, porque só aumenta tamanho de fonte.
Mas não é.

Imagine totalizar várias coisas de uma vez.

DECLARE nTotais[3]
Afill( nTotais, 0 )
DO WHILE .NOT. Eof()
   DO CASE
   CASE .NOT. Empty( arquivo->DataPag )
      nTotais[ 1 ] += arquivo->Valor
   CASE .NOT. Empty( arquivo->DataCancel )
      nTotais[ 2 ] += arquivo->Valor
  OTHERWISE
     nTotais[ 3 ] += Arquivo->Valor
   ENDCASE
   SKIP
ENDDO
? "Em aberto :" + Transform( nTotais[ 3 ], "999,999,999.99" )
? "Pagos:" + Transform( nTotais[ 2 ], "999,999,999.99" )
? "Cancelados" + Transform( nTotais[ 2 ], "999,999,999.99" )


Ok. O fonte é pequeno, poucas coisas tá fácil de enxergar.
Mas se digitar o número errado no fonte, sai valor zerrado.
E numa rotina mais complicada.... mais change a erro.
Então vamos facilitar...

Entenda:
Não é porque disseram que precisa disso
Não é porque a linguagem exige
Esquecemos do ponto importante na hora de programar: É pra facilitar pra NÓS !!!!

#define TOTAL_ABERTO        1
#define TOTAL_PAGO           2
#define TOTAL_CANCELADO 3

DECLARE nTotais[3]
Afill( nTotais, 0 )
DO WHILE .NOT. Eof()
   DO CASE
   CASE .NOT. Empty( arquivo->DataPag )
      nTotais[ TOTAL_PAGO ] += arquivo->Valor
   CASE .NOT. Empty( arquivo->DataCancel )
      nTotais[ TOTAL_CANCELADO ] += arquivo->Valor
  OTHERWISE
     nTotais[ TOTAL_ABERTO ] += Arquivo->Valor
   ENDCASE
   SKIP
ENDDO
? "Em aberto :" + Transform( nTotais[ TOTAL_ABERTO ], "999,999,999.99" )
? "Pagos:" + Transform( nTotais[ TOTAL_PAGO ], "999,999,999.99" )
? "Cancelados" + Transform( nTotais[ TOTAL_CANCELADO ], "999,999,999.99" )


Isso reduz a chance de digitar número errado.

E que tal acrescentar 3 colunas: vencido no mes, vencido no mes anterior, vencido há mais de 60 dias
Fazendo do segundo jeito, menos chance de fazer errado, dá pra complicar à vontade, e não nos complicaremos.

E juntando isso à compilação -w3 -es2, se digitarmos o nome errado, vai avisar na compilação, por exemplo digitar VENCDOS ao invés de VENCIDOS.
Vamos ver o erro antes de executar o programa.

Pergunta tradicional: Quando e onde usar isso?

Pergunta correta: Onde isso pode facilitar pra mim?
Reposta: Você decide. Experimente e veja se facilitou.

Não adianta procurar isso em manuais, manuais mostram como usar.
É você que precisa se acostumar a querer facilitar seu trabalho da maneira que achar melhor.

E quem está acostumado com isso, faz tão automático, que acaba nem lembrando porque.
Mas é porque facilita.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 17:42

Ainda nesse exemplo... vamos complicar... pra facilitar

Sempre pode precisar mudar a ordem, acrescentar campos em qualquer ordem, etc.

#define TOTAL_ABERTO    1
#define TOTAL_PAGO     2
#define TOTAL_CANCELADO 3

DECLARE nTotais[3]
Afill( nTotais, 0 )
DECLARE cNomes[3]
cNomes[ TOTAL_ABERTO ] := "TOTAL ABERTO"
cNomes[ TOTAL_PAGO ] := "TOTAL PAGO"
cNomes[ TOTAL_CANCELADO ] := "TOTAL CANCELADO"

DO WHILE .NOT. Eof()
DO CASE
CASE .NOT. Empty( arquivo->DataPag )
   nTotais[ TOTAL_PAGO ] += arquivo->Valor
CASE .NOT. Empty( arquivo->DataCancel )
   nTotais[ TOTAL_CANCELADO ] += arquivo->Valor
OTHERWISE
  nTotais[ TOTAL_ABERTO ] += Arquivo->Valor
ENDCASE
SKIP
ENDDO
FOR nCont = 1 TO Len( nTotais )
   ? cNomes[ nCont ] + Transform( nTotais[ nCont ], "999,999,999.99" )
NEXT


Até que não complicou muito.

Qual a diferença?
Se tiver que mudar a ordem, é só alterar os números em #define.
Se tiver que acrescentar mais campos, ficou mais fácil, só acrescentar o totalizador e o nome.
E se o cliente quiser em ordem diferente, só alterar as primeiras linhas.

Imagine isso multiplicado por várias linhas e várias colunas....
O que seria um fonte complexo pra mexer, fica facilitado, e te ajudando a evitar erros.

Facilita até na hora de fazer.

Apenas estou mostrando opções existentes, e no que pode facilitar.
Cada um tem que achar o próprio caminho.
Nem sempre o que facilita pra um, pode facilitar pra outro.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 19:06

Um de meus fontes, um dos menores....

#include "jpa.ch"
#include "inkey.ch"
#include "hbclass.ch"

PROCEDURE PAUXMIDIA
   LOCAL oFrm := AUXMIDIAClass():New()

   IF .NOT. AbreArquivos( { "jptabel" } )
      RETURN
   ENDIF
   SELECT jptabel
   SET FILTER TO jptabel->axTabela == AUX_MIDIA
   oFrm:Execute()
   CLOSE DATABASES
   RETURN

CREATE CLASS AUXMIDIAClass INHERIT AUXILIARClass
   VAR  cTabelaAuxiliar INIT AUX_MIDIA
   END CLASS


Podemos analisar de diversas formas, mas a principal é: o que tem aí que pode gerar erro
Tá fácil de mexer, aliás, nem tem o que mexer.

Em execução:

telajpa.png


Eu fui deixando de um jeito que fui achando fácil pra mim, demorou pra chegar aí.

Achei mais fácil, por exemplo, o próprio menu montar a tela, com o título, já que o título está na opção do menu.
O módulo não se preocupa em criar tela, apenas usa a que vém pronta.
Usa o meio da tela pra trabalhar.

E o que não tem no fonte, já dá pra imaginar, a classe faz.

Aí vão pensar.... oooohhhh o negócio é classe, pra digitar menos fonte e ter menos trabalho....

Não!
Isso é justamente o que faz dar errado.
Acostume a facilitar seu trabalho.
Se um dia for usar classe, é porque encontrou um jeito de usá-la pra facilitar seu trabalho.
E se estiver facilitando... tudo fica fácil.
Isso faz encarar qualquer dificuldade, mesmo que dê trabalho.

Se for usar porque "acha" que vai facilitar, tudo vai ser complicado.

Como facilitar um cadastro:
- Pode usar aquilo do Row()+1
- Pode fazer uma função de menu genérica
- Pode fazer SAY/GET pra mostrar e digitar, o que reduz fonte

Tem muitas coisas que podem facilitar.
A classe só vai agrupar essas coisas.
Se não costuma facilitar o resto, a classe também não vai facilitar.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 19:14

Outra coisa que facilita... usar recurso de SAY/GET:

FUNCTION TelaDados( lDigita )
   LOCAL mCodigo :+ 0, mNome := Space(30), mEndereco := Space(30)
   lDigita := iif( lDigita == NIL, .F., lDigita )
   @ 1, 0 SAY "Codigo..." GET mCodigo VALID mCodigo > 0
   @ Row() + 1, 0 SAY "Nome..." GET mNome VALID .NOT. Empty( mNome )
   @ Row() + 1, 0 SAY "Endereco...." GET mEndereco VALID .NOT. Empty( mEndereco )
   IF lDigita
      READ
   ELSE
      CLEAR GETS
   ENDIF
   RETURN NIL


O que tem de diferente?

Essa tela serve pra SAY e para GET.

TelaDados()
TelaDados( .T. )


Isso facilita.
O mesmo fonte serve pra mostrar informação e pra digitar.
Ao invés de fazer duas rotinas separadas, basta uma pra tudo.
Na inclusão ou alteração, TelaDados(.T.)
Na consulta ou exclusão, TelaDados(), com a diferença que na exclusão pergunta sim ou não

E montagem de tela... vai estar sempre certinha, com a tela vazia, basta um TelaDados() que aparece tudo sempre no mesmo lugar.

Foi uma das coisas que achei que facilitaria meu trabalho, e acabei adotando.

A classe facilitou meus cadastros?
Se for pensar direito... todo resto é que facilitou, e não a classe.
A classe só serviu pra juntar tudo que eu já usava, e dar um retoque final a tudo.

Repetindo:
É pensar em facilitar o seu trabalho, só deixar acontecer.
Cada um facilita o que usa, do jeito que achar melhor, e na época que achar melhor.
O que vejo na prática é que o pessoal esquece de facilitar pra si próprio, e acaba se complicando, e tendo cada vez mais dificuldade.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 21 Jun 2015 19:49

Fugindo um pouco do Clipper/Harbour... VB.
Acho que minha passagem pelo VB ajudou nisso de deixar programas fáceis.

Aqui a tela de preview do VB, que cheguei a usar no Clipper.

previewvb.png


Opção de zoom, mudar página, etc.
À primeira vista, deve ser um fonte complicado.

Bom... no Clipper eu já usava uma página por arquivo, pra não ter problema com limite de memória.
Então ficou simples.

Para o zoom, só aumentar ou diminuir a letra, somar 1 ou tirar 1.

Private Sub cmdMaisZoom_Click()
   TextPreview.FontSize = Min(30, TextPreview.FontSize + 1)
End Sub

Private Sub cmdMenosZoom_Click()
   TextPreview.FontSize = Max(5, TextPreview.FontSize - 1)
End Sub


Pra página anterior ou seguinte, só somar ou tirar 1, e pra primeira e última, só atribuir 1, ou a quantidade total de páginas.
E em seguida, recarregar o arquivo com o relatório


Private Sub cmdSeguinte_Click()
   If nFileAtu < File1.ListCount - 1 Then nFileAtu = nFileAtu + 1
   ReloadFile
End Sub

Private Sub cmdAnterior_Click()
   If nFileAtu > 0 Then nFileAtu = nFileAtu - 1
   ReloadFile
End Sub

Private Sub cmdPrimeiro_Click()
   nFileAtu = 0
   ReloadFile
End Sub

Private Sub cmdUltimo_Click()
   nFileAtu = File1.ListCount - 1
   ReloadFile
End Sub


Como deu pra perceber, é o programa dividido em blocos, Cada bloco equivale a clicar num botão.
Isso ajudou a enxergar que não precisa fazer fontes gigantes.
Basta pequenas rotinas, cada uma fazendo o que precisa fazer.

Parece brincadeira, mas só depois da passagem pelo VB é que isso me chamou a atenção.
Pequenas rotinas, simples e funcionais, cada uma fazendo seu trabalho.

Acho que nem precisa dizer.... tá com a aparência da minha classe atual em Harbour....

Isso reforça o que eu disse:
É ir trabalhando pra deixar fácil, e tudo vai acontecendo.
É enxergar o que está na frente do nariz, e não damos atenção.

Só comentário:
Trabalhei em VB no estilo Clipper, e em Clipper no estilo VB.
Aproveitei o conhecimento de um para o outro. Nem Harbour usava na época.

Nota: Esses blocos de fonte, apesar de não serem Clipper/Harbour servem como ilustação. O restante do fonte, aí sim, seria fugir totalmente do tópico.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor Toledo » 21 Jun 2015 21:02

José Quintas, parabéns pelas dicas e tutorias que vem postando aqui no fórum, tudo muito bem detalhado e de fácil entendimento!

Muito obrigado por compartilhar seus conhecimentos!

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 22 Jun 2015 00:49

A intenção deste tópico foi mais como sendo um pontapé inicial.
E pra chamar a atenção de algo tão importante, que a gente não percebe.

Com certeza cada um deve ter uma particularidade pra deixar as coisas mais fáceis.
E o tópico vai fazer cada um perceber isso.

Até o Harbour tem exemplo de facilidade:
O HBMK2 pra quem não percebeu, é pra facilitar compilar, e facilitou muito.

E no Clipper, sempre tínhamos uns arquivos BATs pra facilitar.

Então, sempre procuramos facilitar alguma coisa, mas nem sempre percebemos que dá pra fazer isso com fontes também.

É só plantar a semente... e continuar regando, senão ela não cresce.

Dizer a mesma coisa de outro jeito:
Se seu fonte está difícil de mexer hoje, vai continuar difícil amanhã, e depois, e depois.
Ele só vai ficar fácil amanhã, se você deixá-lo fácil hoje.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 22 Jun 2015 01:39

Recentemente, num post não pensado, minhas três funções foram apresentadas como pontos falhos pra se usar ADO:

FUNCTION StringSql( cTexto )
cTexto := StrTran( cTexto, [\], [\\] )
cTexto := StrTran( cTexto, ['], [\'] )
cTexto := ['] + cTexto + [']
RETURN cTexto

FUNCTION DateSql( dDate )
LOCAL cTexto
cTexto := StrZero( Year( dDate ), 4 ) + "-" + StrZero( Month( dDate ), 2 ) + "-" + StrZero( Day( dDate ), 2 )
IF cTexto == "0000-00-00"
cTexto := "NULL"
ELSE
cTexto := StringSql( cTexto )
ENDIF
RETURN cTexto

FUNCTION NumberSql( xValue )
RETURN Ltrim( Str( xValue ) )


São apenas funções pra deixar fonte fácil.
Agora um exemplo em SQLMIX:

? rddInfo( RDDI_EXECUTE, "INSERT INTO ESTOQUE VALUES ( " + Ltrim( Str( nValor ) ) + ", " + Ltrim( Str( nValor ) ) + ", " + Ltrim( Str( nValor ) ) )
? rddInfo( RDDI_EXECUTE, "INSERT INTO CLIENTES VALUES ( '" + mNome + "', '" + mNome + "' , '" + mNome + '" )
? rddInfo( RDDI_EXECUTE, "INSERT INTO DATAS VALUES ( "  + iif( Date() == NIL, "NULL", "'" + Transform( Dtos( Date() ), "@R 9999-99-99" ) ) + "'," + iif( Date() == NIL, "NULL", "'" + Transform( Dtos( Date() ), "@R 9999-99-99" ) ) + "'," + iif( Date() == NIL, "NULL", "'" + Transform( Dtos( Date() ), "@R 9999-99-99" ) ) + "')"


Comparem agora com este, usando as três funções:

? rddInfo( RDDI_EXECUTE( "INSERT INTO ESTOQUE VALUES (" + NumberSql( nValor ) + ", " + NumberSql( nValor ) + "," + NumberSql( nValor ) )
? rddInfo( RDDI_EXECUTE( "INSERT INTO CLIENTES VALUES (" + StringSql( mNome ) + "," + StringSql( mNome ) + "," + StringSql( mNome ) )
? rddInfo( RDDI_EXECUTE( "INSERT INTO DATAS VALUES (" + DateSql( Date() ) + ", " + DateSql( Date() ) + ", " + DateSql( Date() ) )


De certa forma nem são necessárias, mas é apenas questão de deixar o fonte fácil. Evita erro de digitação e deixa tudo mais claro.
É só comparar os dois fontes pra enxergar que elas foram feitas pensando no programador, e não em velocidade ou necessidade.

Criei algo parecido pra quando gero XML.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 23 Jun 2015 10:01

Um outro exemplo interessante para o #define.

Este é um trecho referente a nota fiscal de serviços, e isso se repete por várias partes do fonte.
Ok, tem o código e a anotação a que se refere... em todas as partes do fonte

IF ::pre_CodigoMunicipio == 3303302 // codigo municipio de niteroi - WebIss


Agora com um #define

#define RPS_MUNICIPIO_NITEROI    3303302
...
IF ::pre_CodigoMunicipio == RPS_MUNICIPIO_NITEROI


O que mudou?
O próprio fonte substituiu a anotação, ficou menos poluído, e facilita enxergar outras partes.
De quebra, menos texto digitado, e mais segurança pra não errar no código (pra quem usa -w3 -es2 que faz essa checagem).
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Práticas que facilitam programar Clipper/Harbour

Mensagempor JoséQuintas » 23 Jun 2015 10:41

preview.png


Não tá parecido com o preview do VB?
No momento tenho um único cliente usando matricial, e mantenho esse preview pra matricial.

Lembram do fonte VB?
Rotinas de página anterior, seguinte, primeira, última, rotinas bem simples?

Pois é. Tá igual.

METHOD MoveFirst() CLASS PrintPreviewClass
   ::nPageNumber := 1
   RETURN NIL

METHOD MoveNext()  CLASS PrintPreviewClass
   IF ::nPageNumber < Len( ::acLstFiles )
      ::nPageNumber += 1
   ENDIF
   RETURN NIL

METHOD MovePrevious() CLASS PrintPreviewClass
   IF ::nPageNumber > 1
      ::nPageNumber -= 1
   ENDIF
   RETURN NIL

METHOD MoveLast() CLASS PrintPreviewClass
   ::nPageNumber := Len( ::acLstFiles )
   RETURN NIL


Lembram também do cadastro?
primeiro, anterior, seguinte, último, ...
Pois é. Pensei... será que dá... e usei para esse preview, já que basicamente tem as mesmas opções.
Foi só colocar o código de cada botão.

Comentei sobre Programando em VB estilo Clipper, e em Clipper estilo VB.

Na prática acho que faz parte do "fonte fácil".
O que deixava o fonte fácil fui usando, não importando a linguagem de programação.

Considero mais um exemplo de "enxergar" o que está na frente, e facilitar nosso trabalho.

Isso deixa o fonte grande....
Isso não faz diferença pro compilador, só pra nós mesmos.
Se o fonte estiver grande, mas fácil de mexer, o tamanho nem importa.

Apesar desse bloco ser pequeno, o restante do fonte não.
Isolar esse bloco faz com que o restante do fonte fique mais fácil de enxergar.

Nota:
A linha em destaque é coisa relativamente recente.
Acabei trocando por um tBrowse().
Como é uma página de cada vez, foi só trocar a parte de visualizar. Ficou fácil de alterar, e continua rápido.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 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 19 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
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro