Clipper On Line • Ver Tópico - Rotina pra etiqueta

Rotina pra etiqueta

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

Moderador: Moderadores

 

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 11:55

Hoje montei uma rotina de etiquetas, pra substituir um label form.

Pra quem está acostumado com array, tá simples.

...
PrintBegin()
aEtiqueta := {}
DO WHILE .NOT. Eof()
   IF Len( aEtiqueta ) == 3
      Imprime( aEtiqueta )
      aEtiqueta := {}
   ENDIF
   AAdd( aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
      etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep, "" } )
   SKIP
ENDDO
IF Len( aEtiqueta ) > 0
   Imprime( aEtiqueta )
ENDIF
PrintEnd()
...
STATIC FUNCTION Imprime( aEtiqueta )
   LOCAL nNumLin, nNumCol, nCol
   FOR nNumLin = 1 TO Len( aEtiqueta[ 1 ] ) // baseado na primeira etiqueta
      FOR nNumCol = 1 TO Len( aEtiqueta )
         DO CASE
         CASE nNumCol == 1; nCol := 3
         CASE nNumCol == 2; nCol := 46
         CASE nNumCol == 3; nCol := 89
         ENDCASE
         @ pRow(), nCol SAY aEtiqueta[ nNumCol ] [ nNumLin ]
      NEXT
      @ pRow() + 1, 0 SAY ""
   NEXT
   RETURN NIL


A única dependência da rotina é aEtiqueta, contendo as linhas/colunas.
O ponto interessante é a rotina funcionar "sozinha", pra ajustar a rotina não depende de nenhum nome externo à ela.
PrintBegin() e PrintEnd() é o tradicional set device to print/set device to screen, podendo ter algo mais.

Agora pensei em deixar pronto pra uso geral, talvez até classe.

Começar apenas transformando em classe.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 12:00

...
            oEtiqueta := EtiquetaClass():New()
            GOTO TOP
            PrintBegin()
            aEtiqueta := {}
            DO WHILE .NOT. Eof()
               IF Len( aEtiqueta ) == 3
                  oEtiqueta:Imprime( aEtiqueta )
                  aEtiqueta := {}
               ENDIF
               AAdd( aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )
               SKIP
            ENDDO
            IF Len( aEtiqueta ) > 0
               oEtiqueta:Imprime( aEtiqueta )
            ENDIF
            PrintEnd()
...
CREATE CLASS EtiquetaClass
   METHOD Imprime( aEtiqueta )
   END CLASS
   
METHOD Imprime( aEtiqueta ) CLASS EtiquetaClass
   LOCAL nNumLin, nNumCol, nCol
   FOR nNumLin = 1 TO Len( aEtiqueta[ 1 ] ) // baseado na primeira etiqueta
      FOR nNumCol = 1 TO Len( aEtiqueta )
         DO CASE
         CASE nNumCol == 1; nCol := 3
         CASE nNumCol == 2; nCol := 46
         CASE nNumCol == 3; nCol := 89
         ENDCASE
         @ pRow(), nCol SAY aEtiqueta[ nNumCol ] [ nNumLin ]
      NEXT
      @ pRow() + 1, 0 SAY ""
   NEXT
   @ pRow() + 1, 0 SAY ""
   RETURN NIL


Pronto. Só tem imprime().

O que mais dá pra fazer?
Vamos deixar a variável aEtiqueta na classe
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 12:08

...
            oEtiqueta := EtiquetaClass():New()
            GOTO TOP
            PrintBegin()
            DO WHILE .NOT. Eof()
               IF Len( oEtiqueta:aEtiqueta ) == 3
                  oEtiqueta:Imprime()
                  oEtiqueta:aEtiqueta := {}
               ENDIF
               AAdd( oEtiqueta:aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )
               SKIP
            ENDDO
            IF Len( oEtiqueta:aEtiqueta ) > 0
               oEtiqueta:Imprime()
            ENDIF
            PrintEnd()
...

CREATE CLASS EtiquetaClass
   VAR aEtiqueta INIT {}
   METHOD Imprime( aEtiqueta )
   END CLASS
   
METHOD Imprime( aEtiqueta ) CLASS EtiquetaClass
   LOCAL nNumLin, nNumCol, nCol
   FOR nNumLin = 1 TO Len( ::aEtiqueta[ 1 ] ) // baseado na primeira etiqueta
      FOR nNumCol = 1 TO Len( ::aEtiqueta )
         DO CASE
         CASE nNumCol == 1; nCol := 3
         CASE nNumCol == 2; nCol := 46
         CASE nNumCol == 3; nCol := 89
         ENDCASE
         @ pRow(), nCol SAY ::aEtiqueta[ nNumCol ] [ nNumLin ]
      NEXT
      @ pRow() + 1, 0 SAY ""
   NEXT
   @ pRow() + 1, 0 SAY ""
   RETURN NIL


Pronto. Economizamos uma linha na rotina normal.
E o que mais?
Quando imprime, zera o array. Podemos mover isso pra classe, economizar mais uma linha.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 12:16

            oEtiqueta := EtiquetaClass():New()
            GOTO TOP
            PrintBegin()
            DO WHILE .NOT. Eof()
               IF Len( oEtiqueta:aEtiqueta ) == 3
                  oEtiqueta:Imprime()
               ENDIF
               AAdd( oEtiqueta:aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )
               SKIP
            ENDDO
            IF Len( oEtiqueta:aEtiqueta ) > 0
               oEtiqueta:Imprime( aEtiqueta )
            ENDIF
            PrintEnd()
...
CREATE CLASS EtiquetaClass
   VAR aEtiqueta INIT {}
   METHOD Imprime( aEtiqueta )
   END CLASS

METHOD Imprime( aEtiqueta ) CLASS EtiquetaClass
   LOCAL nNumLin, nNumCol, nCol
   FOR nNumLin = 1 TO Len( ::aEtiqueta[ 1 ] ) // baseado na primeira etiqueta
      FOR nNumCol = 1 TO Len( ::aEtiqueta )
         DO CASE
         CASE nNumCol == 1; nCol := 3
         CASE nNumCol == 2; nCol := 46
         CASE nNumCol == 3; nCol := 89
         ENDCASE
         @ pRow(), nCol SAY ::aEtiqueta[ nNumCol ] [ nNumLin ]
      NEXT
      @ pRow() + 1, 0 SAY ""
   NEXT
   @ pRow() + 1, 0 SAY ""
   ::aEtiqueta := {}
   RETURN NIL


O que mais dá pra fazer....
A rotina principal adiciona elemento ao array, podemos criar um método Add pra isso.
A rotina principal verifica se chegou na quantidade de colunas.... podemos acrescentar isso na classe, no método Add.
A rotina principal, no final de tudo, imprime o que sobrou de etiqueta... podemos acrescentar isso na classe, num método End()
Então, já criamos um Begin() e End() e já transferimos tudo isso pra classe.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 12:24

            oEtiqueta := EtiquetaClass():New()
            oEtiqueta:Begin()
            GOTO TOP
            DO WHILE .NOT. Eof()
               oEtiqueta:Add( oEtiqueta:aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )
               SKIP
            ENDDO
            oEtiqueta:End()
...
CREATE CLASS EtiquetaClass
   VAR aEtiqueta INIT {}
   METHOD Begin()
   METHOD Add( aConteudo )
   METHOD Imprime()
   METHOD End()
   END CLASS

METHOD Begin() Class EtiquetaClass
   PrintBegin()
   RETURN NIL

METHOD End() CLASS EtiquetaClass
   IF Len( ::aEtiqueta ) > 0
      ::Imprime()
   ENDIF
   PrintEnd()
   RETURN NIL

METHOD Add( aConteudo ) CLASS EtiquetaClass
   IF Len( ::aEtiqueta ) == 3
     ::Imprime()
   ENDIF
   AAdd( ::aEtiqueta, aConteudo )
   RETURN NIL

METHOD Imprime() CLASS EtiquetaClass
   LOCAL nNumLin, nNumCol, nCol
   FOR nNumLin = 1 TO Len( ::aEtiqueta[ 1 ] ) // baseado na primeira etiqueta
      FOR nNumCol = 1 TO Len( ::aEtiqueta )
         DO CASE
         CASE nNumCol == 1; nCol := 3
         CASE nNumCol == 2; nCol := 46
         CASE nNumCol == 3; nCol := 89
         ENDCASE
         @ pRow(), nCol SAY ::aEtiqueta[ nNumCol ] [ nNumLin ]
      NEXT
      @ pRow() + 1, 0 SAY ""
   NEXT
   @ pRow() + 1, 0 SAY ""
   ::aEtiqueta := {}
   RETURN NIL


Pronto.
Aproveitei pra corrigir o método Imprime(), que não precisa de parâmetro, porque tá tudo na classe.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 12:37

Mas tem mais código fonte que antes, cadê a vantagem?

Não. Seu código pra etiqueta passou a ser este:

            oEtiqueta := EtiquetaClass():New()
            oEtiqueta:Begin()
            GOTO TOP
            DO WHILE .NOT. Eof()
               oEtiqueta:Add( oEtiqueta:aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )
               SKIP
            ENDDO
            oEtiqueta:End()


A classe EtiquetaClass passa a fazer parte de sua biblioteca, pra usar quando quiser. Ela é totalmente independente.

É... mas... só serve pra esta etiqueta....
Vai ter que ser sempre etiqueta 3 colunas, com altura de 4 linhas, largura 43 colunas, e começando na coluna 3.

Tudo bem.
Agora a classe é independente.
Alteramos pra funcionar com qualquer configuração, mantendo como padrão inicial o que tem hoje, pra continuar funcionando a rotina.
É só criar variáveis pra quantidade, altura, largura, e coluna inicial, e usá-las na classe, lógico.
De quebra, podemos usar o Pad(), para o caso de colocarmos mais texto do que cabe na etiqueta.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 12:50

Variáveis novas, que a classe precisa conhecer, mas não faz diferença pra rotina que já está usando a classe:

   VAR nQuantidade     INIT 3 //  etiquetas por linha
   VAR nAltura         INIT 5 //  altura entre etiquetas
   VAR nColunaInicial  INIT 3 //  primeira coluna
   VAR nLargura        INIT 43 // largura entre etiquetas


A quantidade de etiquetas por linha é usada nesta parte, então foi alterada pra variável.

METHOD Add( aConteudo ) CLASS EtiquetaClass
   IF Len( aEtiqueta ) == ::nQuantidade
      ::Imprime()
      ::aEtiqueta := {}
   ENDIF
   AAdd( ::aEtiqueta, aConteudo )
   RETURN NIL


A largura, e as posições são usadas nesta parte, então uma fórmula equivalente.
Também já usando o Pad() pra limitar o tamanho, deixando um espaço de segurança de 2 letras.

         nCol := nColunaInicial + ( ( nNumCol - 1 ) * nLargura )
         @ pRow(), nCol SAY Pad( ::aEtiqueta[ nNumCol ] [ nNumLin ], nLargura - 2 )


E por fim, a altura. Lembrando que o FOR/NEXT sempre termina com o número + 1, então precisamos usar o -1.

   IF ( nNumLin - 1 ) < ::nAltura
      @ pRow() + ( ::nAltura - ( nNumLin - 1 ) ), 0 SAY ""
   ENDIF
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 12:52

A classe final ficou assim:

CREATE CLASS EtiquetaClass
   VAR aEtiqueta       INIT {}
   VAR nQuantidade     INIT 3 //  etiquetas por linha
   VAR nAltura         INIT 5 //  altura entre etiquetas
   VAR nColunaInicial  INIT 3 //  primeira coluna
   VAR nLargura        INIT 43 // largura entre etiquetas
   METHOD Begin()
   METHOD Add( aConteudo )
   METHOD Imprime()
   METHOD End()
   END CLASS

METHOD Begin() CLASS EtiquetaClass
   PrintBegin()
   RETURN NIL

METHOD End() CLASS EtiquetaClass
   IF Len( ::aEtiqueta ) > 0
      ::Imprime()
   ENDIF
   PrintEnd()
   RETURN NIL

METHOD Add( aConteudo ) CLASS EtiquetaClass
   IF Len( aEtiqueta ) == ::nQuantidade
      ::Imprime()
      ::aEtiqueta := {}
   ENDIF
   AAdd( ::aEtiqueta, aConteudo )
   RETURN NIL

METHOD Imprime() CLASS EtiquetaClass
   LOCAL nNumLin, nNumCol, nCol
   FOR nNumLin = 1 TO Len( ::aEtiqueta[ 1 ] ) // baseado na primeira etiqueta
      FOR nNumCol = 1 TO Len( ::aEtiqueta )
         nCol := nColunaInicial + ( ( nNumCol - 1 ) * nLargura )
         @ pRow(), nCol SAY Pad( ::aEtiqueta[ nNumCol ] [ nNumLin ], nLargura - 2 )
      NEXT
      @ pRow() + 1, 0 SAY ""
   NEXT
   IF ( nNumLin - 1 ) < ::nAltura
      @ pRow() + ( ::nAltura - ( nNumLin - 1 ) ), 0 SAY ""
   ENDIF
   RETURN NIL
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 13:30

E os programas de etiqueta....

Se for a padrão:

            oEtiqueta := EtiquetaClass():New()
            oEtiqueta:Begin()
            GOTO TOP
            DO WHILE .NOT. Eof()
               oEtiqueta:Add( oEtiqueta:aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )
               SKIP
            ENDDO
            oEtiqueta:End()


E se for diferente, só configurar. A classe ficou pronta pra isso:

            oEtiqueta := EtiquetaClass():New()
            oEtiqueta:nQuantidade := 4
            oEtiqueta:nLargura := 30
            oEtiqueta:nAltura  := 8
            oEtiqueta:nColunaInicial := 4
            oEtiqueta:Begin()
            GOTO TOP
            DO WHILE .NOT. Eof()
               oEtiqueta:Add( oEtiqueta:aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )
               SKIP
            ENDDO
            oEtiqueta:End()


Se fosse função, também daria certo. Mas compare:

EtiquetaConfig := { 4, 30, 8, 4 }


oEtiqueta:nQuantidade := 4
oEtiqueta:nLargura := 30
oEtiqueta:nAltura  := 8
oEtiqueta:nColunaInicial := 4


Podemos considerar a questão "humana".
Ao criar uma nova etiqueta, em qual perdemos menos tempo?

O primeiro, porque digita menos?
Não. O segundo. Não vamos precisar olhar manual nenhum, é só alterar e pronto.

É nesse tipo de coisa que muitos programadores erram.
O segredo da programação é programar pra você mesmo, e não apenas para o computador, para a linguagem ou para o usuário.
No dia a dia, poucas rotinas são novas, a grande maioria é pegar uma rotina pronta como ponto de partida ou pra alteração.
Então se as rotinas estão simples e claras, vai precisar pouco tempo pra entendê-las, e o serviço rende mais.
Vai gastar tempo no que realmente interessa.

Se vai usar classe, função, array, codeblock, tanto faz. Tem que ser simples pra você.
Pegue o fonte que acabou de fazer, dê uma olhada se está entendendo, ou tente imaginar se vai entender meses depois, ou se vai ser fácil adaptar pra outro uso.
Se der pra melhorar, melhore. Senão tudo bem, sinal de que já está bom.
É isso.
Fugindo um pouco do assunto de classe, vou postar um exemplo simples mas que causa confusão.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 13:36

Vejam este bloco de código fonte:

                        sele 1
                        seek SIM00
                        if FOUND()
                           TU00 = 0
                           do while SIM00 = LOCOD
                              TU00 = COD
                              Mensagem( "Salvando o locatário excluído" )
                              INIVS()
                              CARVS()
                              sele 3
                              RecAppend()
                              REPVS()
                              RecUnlock()
                              sele 1
                              RecLock()
                              dele
                              RecUnlock()
                              sele 2
                              seek xCOD
                              if FOUND()
                                 Mensagem( "Salvando o fiador " + StrZero( TU00, 7 ) + " do locatário " + StrZero( TU00, 7 ) )
                                 INIVS()
                                 CARVS()
                                 sele 4
                                 RecAppend()
                                 REPVS()
                                 RecUnlock()
                                 sele 2
                                 RecLock()
                                 dele
                                 RecUnlock()
                              endif
                              sele 1
                              seek SIM00
                              if FOUND()
                                 loop
                              else
                                 exit
                              endif
                           enddo
                           close databases
                           sele 1
                           AbreUmArquivo( "recibo00", , .T. )
                           OrdSetFocus( "xrecibo3" )
                           sele 2
                           AbreUmArquivo( "drecib00", , .T. )
                           Mensagem( "Apagando recibos destes locatários" )
                           sele 1
                           seek  SIM00
                           if FOUND()
                              do while SIM00 = LOCOD
                                 INIVS()
                                 CARVS()
                                 sele 2
                                 RecAppend()
                                 REPVS()
                                 RecUnlock()
                                 sele 1
                                 RecLock()
                                 delete
                                 RecUnlock()
                                 seek SIM00
                                 if FOUND()
                                    loop
                                 else
                                    exit
                                 endif
                              enddo
                              close databases
                           else
                              close databases
                           endif
                        else
                           MsgStop( "Locador não cadastrado" )
                           close databases
                        endif
                     else
                        close databases
                     endif
                  else
                     close databases
                  endif
               else
                  close databases
               endif
            else
               MsgStop( "Locador não cadastrado" + StrZero( Sim00, 4 ) )
               close databases
            endif
         enddo
         @ 04,00,21,79 BOX space(9)
      case CADA01 = 4
      case CADA01 = 5
      case CADA01 = 6
         exit
      endcase
      rest screen from SCADA01
   enddo
   @ 00,00,24,79 BOX space(9)
   close databases
   RETURN
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 14:17

Considere o seguinte são 100 linhas, isso significa que para um programador DOS que use EDIT, vão ser 4 páginas de fonte pra olhar.

Quais são os problemas dele, na minha opinião:

Que arquivos estão abertos em cada área?
começa aí... são 4 páginas de fonte, então precisa olhar mais páginas pra descobrir.
Se houver chamada de rotinas em outros fontes, mais ainda.
Então o fonte faz perder tempo numa questão simples. Se estivesse usando ALIAS, já saberíamos sem olhar páginas de fonte.

Variável SIM00
Pra que serve?
Páginas de fonte, pra descobrir que isso é o código do cadastro.
Se o nome fosse nCodLocatario, bastava olhar o nome de varíavel, sem olhar nenhuma outra página.

IF/ELSE grande
Do IF até o ELSE são várias páginas. Dá pra confundir e nem saber que o ELSE tá lá.
Poderia inverter o IF/ELSE, assim o primeiro IF ficaria pequeno.
Ou, como o ELSE tem LOOP, invertido eliminaria o ELSE.
Menos páginas de fonte pra ter a visão geral.

Vamos supor que queremos aumentar o tamanho de um campo.
Que campos são usados nesse fonte? de quais arquivos? ferrou.

O fonte não tem nenhum comando complicado, é tudo simples.
Mas mexer nele, precisa de uma grande pesquisa em todo o aplicativo.
Páginas e mais páginas de fonte pra ficar navegando.

É a isso que me refiro quando falo de programa simples.
Tem que ser simples de entender e de fazer manutenção.
Tanto faz usar função, classe, comandos avançados, tanto faz.
O fonte é usado por nós humanos, então tem que facilitar pra nós humanos.

Nessas horas, a linguagem de programação que se exploda.
O programador tem que fazer o fonte pra ele, do jeito dele, pra facilitar pra ele.

Entendam o seguinte:
Se o programador conhece a linguagem a fundo, conhece comandos avançados, conhece classe ou sei lá o que, isso ajuda, mas não é o que faz a diferença.
O que faz diferença é querer fazer o fonte simples e prático, pra nós mesmos entendermos.
Fazendo tudo prático, sobra tempo pra ver outras coisas.

É só acostumar com essa idéia. Não precisa mudar tudo da noite pro dia. É ir fazendo e entendendo porque fez daquele jeito.

Nota:
Coincidiu de encontrar alguns programadores que estão se perdendo na programação.
Na prática, eles foram fazendo fontes assim, cada vez maiores, e acostumaram a não entender o fonte, por ter várias páginas.
É ir acrescentando variáveis só pra não dar erro, e outras coisas mais.
Com a idade, e com o costume, se perdem pra fazer algo novo.
Parece que não, mas acostumam com um fonte que tem sempre que parecer complicado.

Então aproveitem enquanto dá.
Fonte fácil, alteração fácil, programa novo fácil, sempre vai ser fácil.
Isso tem que virar vício, então quanto antes começar melhor pra ficar viciado em fazer tudo fácil.

Isso não tem uma regra ou manual.
Cada um vai seguindo seu próprio ritmo pra se acostumar, do jeito que achar melhor.
Não pode deixar isso de lado.

Tá preocupado em converter de Clipper pra Harbour, de usar classe, etc.?
Não se preocupe com isso. Se preocupe em fontes fáceis de mexer.
Se tá fácil, vai fácil.

Assim vai demorar muito....
Ué, há quanto tempo diz isso? anos? e não saiu do lugar?
Vai deixando o fonte fácil.
Se está tudo ficando fácil, tudo vai ser fácil, vai ser apenas questão de tempo, mas está sempre indo em frente... fácil.

Ficar olhando páginas e páginas de fonte, só pra saber que arquivo está aberto.... isso sim é complicado.
Não tem editor de texto, ou tamanho de tela que ajude nisso.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 14:44

Fui postando conforme fui alterando.
Acabou tendo alguns erros.

Pra quem compila usando -w3 -es2 tá fácil.
É a lista de erros abaixo, mas o número de linha é diferente.

Compiling 'ETIKA.prg'...
ETIKA.prg(155) Warning W0001  Ambiguous reference 'AETIQUETA'
ETIKA.prg(166) Warning W0001  Ambiguous reference 'NCOLUNAINICIAL'
ETIKA.prg(166) Warning W0001  Ambiguous reference 'NLARGURA'
ETIKA.prg(167) Warning W0001  Ambiguous reference 'NLARGURA'


Essas variáveis são internas da classe, faltou colocar :: na frente delas. exemplo ::aEtiqueta.

Esse recurso da compilação ajuda muito: já avisou do erro antes de executar.
Isso faz parte de quando se compila usando -w3 -es2

Se possível, adotem para os novos fontes. Ajuda muito mesmo.
Para fontes antigos, tudo depende de como eles estiverem, pode dar muito trabalho.
Se usar misturado fontes novos e antigos, dá pra definir dentro do fonte também.
#pragma -w3
#pragma -es2


Com isso, pode escolher em quais fontes vai adotar a "tolerância zero".
Ou o contrário, deixe como default "tolerância zero", e coloque nos fontes velhos -es0 -w0.
E com o tempo, tente deixar todos os fontes prontos pra isso. Dá trabalho mas vale a pena.
Neste caso, me economizou várias compilações e testes, senão só veria o erro em runtime, um a cada execução/correção/compilação.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor JoséQuintas » 12 Jun 2015 15:33

Mais um erro, faltou apagar uma parte quando virou classe, na rotina que faz uso dela:

               oEtiqueta:Add( oEtiqueta:aEtiqueta, { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )


Correto:
               oEtiqueta:Add( { "ILMO SR(A)", etika->Nome, etika->Endereco, ;
                  etika->Bairro + " - " + Trim( etika->Cidade ) + " - " + etika->Uf, etika->Cep } )


Reduziu até um pouco mais.

O Harbour tem a opção de receber todos os parâmetros da função como array, eliminaria a necessidade de { } nessa linha.
Não lembro qual é, mas pensando em "nós humanos", pode ajudar a evitar futuros erros na digitação dessa linha.

Nota:
Eu disse, isso de melhorar vira vício... sempre que a gente olha um fonte pensa se dá pra melhorar um pouquinho.... rs
Só ter certeza de que está facilitando e não complicando, e tudo bem.
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: 18008
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina pra etiqueta

Mensagempor asimoes » 03 Nov 2015 19:02

Olá Quintas,

Gostei muito da sua contribuição, eu queria tirar uma duvida com você sobre este exemplo.

Quando a impressão for direcionada para um arquivo e posterior impressão usando a função win_printfileraw supondo que a etiqueta é formulário
continuo. Se precisar usar a sequencia escape para condensar tipo Chr(27)+"P"+Chr(15) como ficaria esse arquivo, você já precisou fazer desta forma?
â–ºHarbour 3.x | Minigui xx-x | HwGuiâ—„
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Rotina pra etiqueta

Mensagempor rubens » 06 Nov 2015 00:04

Muito bom Quintas...

Há algum tempo queria perguntar isso a vocês:
No seu exemplo de 100 linhas se estivéssemos falando de classe poderia dizer que essa classe tem um forte acoplamento o que não é "recomendado". Bom tenho uma rotina que transforma o orçamento em venda, e já faz todas as regras de negócios definidas tais como, grava a venda, dá baixa no estoque, grava lançamento no caixa, se for venda a prazo grava no contas a receber, altera saldo do cliente e por aí vai. Caso dê algum problema na execução desses procedimentos como uma travada na máquina, um reset enfim um "problema desconhecido" a integridade vai por água abaixo. Num rotina extensa dessas o que eu poderia fazer para me recupera de problemas desses. Imagina que já gravou a venda e deu baixa no estoque, mas ainda tem que lançar o financeiro e atualizar saldo do cliente. Tem que ser feito manual porque o sistema não vai saber onde parou a execução.

Obrigado
Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Avatar de usuário

rubens
Colaborador

Colaborador
 
Mensagens: 1518
Data de registro: 16 Ago 2003 09:05
Cidade/Estado: Nova Xavantina - MT
Curtiu: 77 vezes
Mens.Curtidas: 104 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 16 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