Clipper On Line • Ver Tópico - Meu modo de trabalho

Meu modo de trabalho

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

Moderador: Moderadores

 

Meu modo de trabalho

Mensagempor JoséQuintas » 21 Dez 2019 22:08

Tem mais um ponto importantíssimo nisso aí:

é um comando SQL, e um browse...
Qualquer linguagem de programação tem isso.

Sabem como era no Visual Basic 6, de 20 anos atrás?
Exatamente isso.
Um texto digitado, que é o comando SQL, e o GRID.

Entenderam? não está preso a DBF, e nem mesmo ao Harbour !!!

Estou confirmando isso na prática agora.
Abandonar o mecanismo DBF é o primeiro passo pra evolução e pra liberdade !!!!
Pode ser com ADO, a Microsoft deixou o ADO disponível pra todos, DE GRAÇA, há 20 anos.
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 22 Dez 2019 18:03

Situação em 20/11/2019: 37 DBFs
Situação em 22/12/2019: 30 DBFs, e 48 no MySQL.
Usando cliente com mais opções em uso como referência 813MB em DBF, e 3.7GB em MySQL.
Não anotei outras referências.
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 23 Dez 2019 18:12

Nos meus fontes eu já usava classe, em muita coisa, então pra muita coisa foi só ajustar as classes.

O cadastro de veículos:

PROCEDURE PJPVEICULO

   LOCAL oFrm := JPVEICULOClass():New()

   IF ! AbreArquivos( "jpcadastro", "jpcidade", "jpconfi", "jpempresa", "jpitem", "jpitped", ;
      "jpnotfis", "jpnumero", "jppedido", "jppreco", "jpsenha", "jptabel", "jpuf" )
      RETURN
   ENDIF
   oFrm:Execute()

   RETURN


E a classe aplicada herança:

CREATE CLASS JPVEICULOClass INHERIT FrmCadastroClass

   VAR    cDataTable INIT "JPVEICULO"
   VAR    cDataField INIT "IDVEICULO"
   VAR    axKeyField INIT { Space(6) }
   VAR    cnMySql    INIT ADOClass():New( AppConexao() )
   METHOD GridSelection()
   METHOD Especifico( lExiste )
   METHOD TelaDados( lEdit )
   METHOD Valida( cCodigo, lMostra, cCampo )

   ENDCLASS


No que o cadastro de veículso é diferente dos demais?
o browse, que pode ser usado em qualquer parte do aplicativo

METHOD GridSelection() CLASS JPVEICULOClass

   LOCAL oTBrowse, cnMySql := ADOClass():New( AppConexao() )

   WITH OBJECT cnMySql
      :cSql := "SELECT * FROM JPVEICULO ORDER BY VEPLACA"
      :Execute()
      oTBrowse := { ;
         { "CÓDIGO",    { || StrZero( :Number( "IDVEICULO" ), 6 ) } }, ;
         { "PLACA",     { || :String( "VEPLACA", 10 ) } }, ;
         { "MOTORISTA", { || :String( "VEMOTORI", 30 ) } }, ;
         { "TELEFONE",  { || :String( "VETELEFONE", 20 ) } }, ;
         { "CAP.TOT",   { || Transform( :Number( "VECAPACTOT" ), PicVal(6) ) } }, ;
         { "CAP.1",     { || Transform( :Number( "VECAPAC1" ), PicVal(6) ) } }, ;
         { "CAP.2",     { || Transform( :Number( "VECAPAC2" ), PicVal(6) ) } }, ;
         { "CAP.3",     { || Transform( :Number( "VECAPAC3" ), PicVal(6) ) } }, ;
         { "CAP.4",     { || Transform( :Number( "VECAPAC4" ), PicVal(6) ) } }, ;
         { "CAP.5",     { || Transform( :Number( "VECAPAC5" ), PicVal(6) ) } }, ;
         { "CAP.6",     { || Transform( :Number( "VECAPAC6" ), PicVal(6) ) } }, ;
         { "CAP.7",     { || Transform( :Number( "VECAPAC7" ), PicVal(6) ) } }, ;
         { "CAP.8",     { || Transform( :Number( "VECAPAC8" ), PicVal(6) ) } }, ;
         { "CAP.9",     { || Transform( :Number( "VECAPAC9" ), PicVal(6) ) } } }
      BrowseADO( cnMySql, oTBrowse, "VEPLACA,VEMOTORI,VETELEFONE", { || StrZero( :Number( "IDVEICULO" ), 6 ) } )
      :CloseRecordset()
   ENDWITH

   RETURN NIL


escolher um código específico:

METHOD Especifico( lExiste ) CLASS JPVEICULOClass

   LOCAL GetList := {}, midVeiculo

   midVeiculo := ::axKeyValue[ 1 ]
   @ Row()+1, 20 GET midVeiculo PICTURE "@K 999999"  VALID NovoMaiorZero( @midVeiculo )
   Mensagem( "Digite código, F9 pesquisa, ESC sai" )
   READ
   Mensagem()
   IF LastKey() == K_ESC .OR. ( Val( midVeiculo ) == 0 .AND. ::cOpc != "I" )
      RETURN .F.
   ENDIF
   IF ! ::EspecificoExiste( lExiste, ADORecCount( "JPVEICULO", "IDVEICULO=" + StringSql( midVeiculo ) ) == 0 )
      RETURN .F.
   ENDIF
   ::axKeyValue := { midVeiculo }

   RETURN .T.


A tela de edição, que tem muito lixo por sinal, e não parei pra retirar a parte inútil...

METHOD TelaDados( lEdit ) CLASS JPVEICULOClass

   LOCAL GetList := {}
   LOCAL midVeiculo, mvePlaca, mveMotori, mveTelefone, mveCapacTot, mveCapac1, mveCapac2, mveCapac3
   LOCAL mveCapac4, mveCapac5, mveCapac6, mveCapac7, mveCapac8, mveCapac9, mvePeso, mveInfInc, mveInfAlt

   midVeiculo := ::axKeyValue[1]
   WITH OBJECT ::cnMySql
      mvePlaca    := :String( "VEPLACA", 8 )
      mveMotori   := :String( "VEMOTORI", 30 )
      mveTelefone := :String( "VETELEFONE", 20 )
      mvePeso     := :Number( "VEPESO" )
      mveCapac1   := :Number( "VECAPAC1" )
      mveCapac2   := :Number( "VECAPAC2" )
      mveCapac3   := :Number( "VECAPAC3" )
      mveCapac4   := :Number( "VECAPAC4" )
      mveCapac5   := :Number( "VECAPAC5" )
      mveCapac6   := :Number( "VECAPAC6" )
      mveCapac7   := :Number( "VECAPAC7" )
      mveCapac8   := :Number( "VECAPAC8" )
      mveCapac9   := :Number( "VECAPAC9" )
      mveInfInc   := :String( "VEINFINC" )
      mveInfAlt   := :String( "VEINFALT" )
      :CloseRecordset()
   ENDWITH

   hb_Default( @lEdit, .F. )
   ::nNumTab := 1
   DO WHILE .T.
      ::ShowTabs()
      DO CASE
      CASE ::nNumTab == 1
         @ Row() + 1, 1 SAY "Núm. Lançto......:" GET midVeiculo WHEN .F.
         @ Row() + 2, 1 SAY "Placa............:" GET mvePlaca    PICTURE "!!!-9999" VALID ValidaPlaca( @mvePlaca )
//         @ Row() + 2, 1 SAY "CPF..............:" GET mveCPF      PICTURE "@9"       VALID OkGetCnpjCpf( @mvecpf, .T. )
         @ Row() + 2, 1 SAY "Motorista........:" GET mveMotori   PICTURE "@!"       VALID ! Empty( mveMotori )
         @ Row() + 1, 1 SAY "Telefone.........:" GET mveTelefone PICTURE "@!"
         @ Row() + 1, 1 SAY "Capacidade Total.:" GET mveCapacTot PICTURE "999,999"  VALID mveCapacTot > 0
         @ Row() + 1, 1 SAY "Peso do Veículo..:" GET mvePeso     PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 1...:" GET mveCapac1   PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 2...:" GET mveCapac2   PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 3...:" GET mveCapac3   PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 4...:" GET mveCapac4   PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 5...:" GET mveCapac5   PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 6...:" GET mveCapac6   PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 7...:" GET mveCapac7   PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 8...:" GET mveCapac8   PICTURE "999,999"
         @ Row() + 1, 1 SAY "Capac.Tanque 9...:" GET mveCapac9   PICTURE "999,999"
         @ Row() + 2, 1 SAY "Inf.Inclusão.....:" GET mveInfInc   WHEN .F.
         @ Row() + 1, 1 SAY "Inf.Alteração....:" GET mveInfAlt   WHEN .F.
      ENDCASE
      //SetPaintGetList( GetList )
      IF ! lEdit
         CLEAR GETS
         EXIT
      ENDIF
      Mensagem( "Digite campos, F9 Pesquisa, ESC Sai" )
      READ
      Mensagem()
      ::nNumTab += 1
      IF LastKey() == K_ESC
         EXIT
      ENDIF
      IF ::nNumTab > Len( ::acTabName )
         EXIT
      ENDIF
   ENDDO
   IF ! lEdit
      RETURN NIL
   ENDIF
   ::nNumTab := 1
   IF LastKey() == K_ESC
      RETURN NIL
   ENDIF
   WITH OBJECT ::cnMySql
      :QueryCreate()
      :QueryAdd( "VEPLACA", mvePlaca )
      :QueryAdd( "VEMOTORI", mveMotori )
      :QueryAdd( "VEPESO", mvePeso )
      :QueryAdd( "VECAPACTOT", mveCapacTot )
      :QueryAdd( "VECAPAC1", mveCapac1 )
      :QueryAdd( "VECAPAC2", mveCapac2 )
      :QueryAdd( "VECAPAC3", mveCapac3 )
      :QueryAdd( "VECAPAC4", mveCapac4 )
      :QueryAdd( "VECAPAC5", mveCapac5 )
      :QueryAdd( "VECAPAC6", mveCapac6 )
      :QueryAdd( "VECAPAC7", mveCapac7 )
      :QueryAdd( "VECAPAC8", mveCapac8 )
      :QueryAdd( "VECAPAC9", mveCapac9 )
      IF ::cOpc == "I"
         :QueryAdd( "VEINFINC", LogInfo() )
         IF Val( midVeiculo ) == 0
            midVeiculo := StrZero( :QueryExecuteInsert( "JPVEICULO" ), 6 )
         ELSE
            :QueryAdd( "IDVEICULO", midVeiculo )
            :QueryExecuteInsert( "JPVEICULO" )
         ENDIF
      ELSE
         :QueryAdd( "VEINFALT", LogInfo() )
         :QueryExecuteUpdate( "JPVEICULO", "IDVEICULO=" + StringSql( midVeiculo ) )
      ENDIF
   ENDWITH

   RETURN NIL


A validação de veículo e/ou placa que pode ser usada no aplicativo inteiro

METHOD Valida( cCodigo, lMostra, cCampo ) CLASS JPVEICULOClass

   LOCAL cnMySql := ADOClass():New( AppConexao() )

   hb_Default( @lMostra, .T. )
   hb_Default( @cCampo, "codigo" )
   IF cCampo == "placa"
      IF Len( AllTrim( cCodigo ) ) < 2
         RETURN .T.
      ENDIF
      IF ! ValidaPlaca( cCodigo )
         RETURN .F.
      ENDIF
      IF ADORecCount( "JPVEICULO", "VEPLACA=" + StringSql( cCodigo ) ) == 0
         IF ! MsgYesNo( "Placa não utilizada antes. Continua?" )
            RETURN .F.
         ENDIF
         WITH OBJECT cnMySql
            :QueryCreate()
            :QueryAdd( "VEPLACA", cCodigo )
            :QueryExecuteInsert( "JPVEICULO" )
         ENDWITH
      ENDIF
   ELSE
      IF lMostra
         @ Row(), 32 SAY Space(10)
      ENDIF
      cCodigo := StrZero( Val( cCodigo ), 6 )
      IF ADORecCount( "JPVEICULO", "IDVEICULO=" + StringSql( cCodigo ) ) == 0
         MsgExclamation( "Veículo não cadastrado" )
         RETURN .F.
      ENDIF
      IF lMostra
         @ Row(), 32 SAY ADOField( "VEPLACA", "C", "JPVEICULO", "IDVEICULO=" + StringSql( cCodigo ) )
      ENDIF
   ENDIF

   RETURN .T.


Apenas ajustei o estilo DBF pra comportar o estilo ADO.
Mantendo o código caractere, apesar de salvar como numérico no MySQL, pra compatibilidade, até a completa migração pra MySQL.

aplicativo.png


Dizem que a GTWVG é complicada, enche de código fonte estranho dentro do fonte....
Tão vendo alguma coisa de GTWVG no fonte?
Pois é... uma IDE pra desenhar telas pra que? pra qual tela?
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 25 Dez 2019 17:24

O meu aplicativo também tem uns fontes ridículos....
Algum dia devo ter criado, não sei se alguém usa, mas tá lá até hoje.
Vou alterar neste instante, porque estou querendo eliminar o JPESTOQUE.DBF
Este vai ser um bom exemplo de mudança pra SQL !!!

/*
PESTOENTFOR - Consulta Entradas de Fornecedor
2000.12.05 José Quintas
*/

#include "inkey.ch"

PROCEDURE pEstoEntFor

   LOCAL m_TxtTmp, mFornec, GetList := {}, mTexto, mDocto

   IF ! AbreArquivos( "jpcadastro", "jpcidade", "jpconfi", "jpempresa", ;
      "jpestoque", "jpitem", "jpitped", "jpfiscal", "jpnotfis", "jpnumero", "jppedido", ;
      "jppreco", "jpsenha", "jptabel", "jpuf" )
      RETURN
   ENDIF
   m_TxtTmp  := MyTempFile( "DBF" )
   dbCreate( m_TxtTmp, { { "TEXTO", "C", 80, 0 } } )
   SELECT 0
   USE ( m_TxtTmp ) EXCLUSIVE ALIAS TEMP
   mFornec := Space(6)
   DO WHILE .T.
      @ 4, 0 SAY "Fornecedor.." GET mFornec PICTURE "@K 999999" VALID JPCADASTROClass():Valida( @mFornec )
      Mensagem( "Digite fornecedor, F9 pesquisa, ESC sai" )
      READ
      Mensagem()
      IF lastkey() == K_ESC
         EXIT
      ENDIF
      WSave()
      SELECT temp
      ZAP
      RecAppend()
      REPLACE temp->Texto WITH "FORNECEDOR (" + jpcadastro->idCadastro + ") " + jpcadastro->cdNome
      RecAppend()
      RecUnlock()
      SELECT jpestoque
      OrdSetFocus( "jpestoq5" )
      SEEK "2" + mFornec
      DO WHILE jpestoque->esTipLan == "2" .AND. jpestoque->esCliFor == mFornec .AND. ! Eof()
         GrafProc()
         mTexto := "Docto " + jpestoque->esNumDoc
         mTexto += " Emissao " + Dtoc( jpestoque->esDatLan )
         SELECT temp
         RecAppend()
         REPLACE temp->Texto WITH mTexto
         RecUnlock()
         mDocto := jpestoque->esNumDoc
         SELECT jpestoque
         DO WHILE mDocto == jpestoque->esNumDoc .AND. mFornec == jpestoque->esCliFor .AND. jpestoque->esTipLan == "2" .AND. ! Eof()
            GrafProc()
            Encontra( jpestoque->esItem, "jpitem","item" )
            mTexto := "   Qtde " + str( jpestoque->esQtde )
            mTexto += " Preco " + str( jpestoque->esValor )
            mTexto += " Item " + Left( jpitem->ieDescri, 70 )
            SELECT Temp
            RecAppend()
            REPLACE temp->Texto WITH mTexto
            RecUnlock()
            SELECT jpestoque
            SKIP
         ENDDO
      ENDDO
      SELECT temp
      RecAppend()
      REPLACE temp->Texto WITH "*** FIM ***"
      RecUnlock()
      Mensagem( "Selecione e tecle ENTER, ESC sai" )
      SELECT temp
      GOTO TOP
      FazBrowse()
      WRestore()
   ENDDO
   SELECT ( Select( "temp" ) )
   USE
   fErase( m_TxtTmp )

   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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 25 Dez 2019 18:12

Pronto.
Pede pro servidor e mostra.
Não precisa de nenhum DBF agora, nem nada em disco.

#include "inkey.ch"

PROCEDURE pEstoEntFor

   LOCAL mFornec := Space(6), GetList := {}, oTBrowse
   LOCAL cnMySql := ADOClass():New( AppConexao() )

   DO WHILE .T.
      @ 4, 0 SAY "Fornecedor.." GET mFornec PICTURE "@K 999999" VALID JPCADASTROClass():Valida( @mFornec )
      Mensagem( "Digite fornecedor, F9 pesquisa, ESC sai" )
      READ
      Mensagem()
      IF lastkey() == K_ESC
         EXIT
      ENDIF
      WITH OBJECT cnMySql
         :cSql := "SELECT LPAD( IDESTOQUE, 6, '0' ) AS ID, ESCLIFOR, ESDATLAN, ESNUMDOC, " + ;
            " ESQTDE, ESVALOR, ESQTDE * ESVALOR AS VALTOT, " + ;
            " LEFT( JPITEM.IEDESCRI, 50 ) AS ITENOME" + ;
            " FROM JPESTOQUE" + ;
            " LEFT JOIN JPITEM ON ESITEM=JPITEM.IDITEM" + ;
            " WHERE ESTIPLAN='2'" + ;
            " AND ESCLIFOR=" + StringSql( mFornec ) + ;
            " ORDER BY ESDATLAN DESC, ITENOME"
         :Execute()
         oTBrowse := { ;
            { "ID",      { || :String( "ID", 6 ) } }, ;
            { "DOCTO",   { || :String( "ESNUMDOC", 9 ) } }, ;
            { "DATA",    { || :Date( "ESDATLAN" ) } }, ;
            { "QTDE",    { || Transform( :Number( "ESQTDE" ), "@E 999,999,999.99" ) } }, ;
            { "VALOR",   { || Transform( :Number( "ESVALOR" ), "@E 999,999,999.9999" ) } }, ;
            { "TOTAL",   { || Transform( :Number( "VALTOT" ), "@E 999,999,999.99" ) } }, ;
            { "PRODUTO", { || :String( "ITENOME", 30 ) } } }
         BrowseADO( cnMySql, oTBrowse, "ESNUMDOC,ITENOME" )
         :CloseRecordset()
      ENDWITH
   ENDDO

   RETURN


Aproveitar fonte anterior?
De certa forma aproveitou a lógica, mas o fonte, quem se importa.

O que tem no fonte?
Pede pro servidor e faz um browse, nenhum processamento no terminal ou no aplicativo.

Trazer total pronto, ou multiplicar no browse? talvez... pode economizar alguns milésimos de segundo...
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 25 Dez 2019 19:04

Agora pensando numa coisa:

Se não depende de arquivo aberto....
Nada impede de embutir/chamar essa rotina direto no cadastro do fornecedor, por exemplo.

É disso que o usuário gosta: recursos na mão (ou no click).
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 28 Dez 2019 13:45

Quase acabando com o uso do dbf jpestoque.
O alias aparece 76 vezes em todos os fontes, incluindo rotinas de conversão/atualização.
Falta pouco....

jpestoque.png
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor asimoes » 28 Dez 2019 22:56

Quintas,

Nas minhas consultas, percebi que criar indices temporários é muito mais rápido que set filter to...

A vantagem disso é que que informo uma chave de ordenação e um filtro usando a clausula "for" que é equivalente ao "where" do sql

ainda de quebra posso usar OrdScope, OrdKeyCount...
►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

Meu modo de trabalho

Mensagempor JoséQuintas » 28 Dez 2019 23:12

asimoes escreveu:Nas minhas consultas, percebi que criar indices temporários é muito mais rápido que set filter to...
A vantagem disso é que que informo uma chave de ordenação e um filtro usando a clausula "for" que é equivalente ao "where" do sql ainda de quebra posso usar OrdScope, OrdKeyCount...


Também tinha o sub-index, usava em SIXCDX.

INDEX ON .... FOR ... WHILE ...

Um índice criado a partir do índice atual, que pode servir pra algum tipo de filtro, pra ganhar tempo.

Mas estou encerrando com DBF.

Repetir o que já disse antes:
Trazer do MySQL é 1 segundo.
Gravar isso em DBF LOCAL, demora minutos.
Usar DBF deixou totalmente de fazer sentido.

Sinceramente...
Quer velocidade com DBF?
Use ADS LOCAL e comando SQL.
SEM ÍNDICE vai ser mais rápido do que qualquer outra alternativa.
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 28 Dez 2019 23:19

Um exemplo de uso do sub-índice:

tem lá o movimento por data:

OrdSetFocus( "ordemdata" )
SEEK Dtos( "20191201" )
INDEX ON produto WHILE Data <= Ctod("31/12/2019")

Nesse caso vai usar o índice por data, usando só os lançamentos do mês, pra criar um índice por produto.

Mais fácil e rápido no MySQL... rs...
SELECT * FROM MOVIMENTO WHERE DATA BETWEEN ... ORDER BY PRODUTO
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor asimoes » 29 Dez 2019 10:47

Trabalhamos com Oracle desde 2001, sei do que você está falando.
Mas ainda existe sistema legado ( dbf ) ai optamos por manter do jeito que está, até converter para c#, enquanto isso, tem esse recurso do temporário.
►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

Meu modo de trabalho

Mensagempor JoséQuintas » 31 Dez 2019 17:15

Última alteração de 2019:
Toda movimentação de estoque agora é exclusiva em MySQL.
Isso inclui relatórios, consultas, arquivo de envio pra ANP, etc.
Sem mais leitura ou gravação em DBF pra estoque.
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 26 Jan 2020 22:01

Ainda estou eliminando JPNOTFIS.DBF, esse é o foco central, porque é o maior DBF de todos.
De um modo geral, em certos fontes é mais fácil eliminar vários DBFs de uma vez do que um só.
E também é interessante já ir testando um uso "mais avançado", pra ver se o comportamento é o esperado.

jpnotfis.png


Lembrando:
As gravações já estão duplicadas em DBF e MySQL.
Estou alterando agora as leituras, pra usar somente o MySQL.

Não tinha pensado nisso antes:

Mesmo que fosse alguma LIB do Harbour, até mesmo se fosse uma RDDSQL da vida, eu teria que fazer essa parte, de alterar ao máximo pra comandos SQL, pra ter velocidade.
Nem dá pra comparar o MEU tempo de migração com o de alguma RDDSQL, porque acabaria tendo que fazer isso do mesmo jeito.
Parece que na prática deu no mesmo, só alterei a ordem das coisas, fui direto pros finalmentes, antes de eliminar os DBFs.

Só uma coisa é certa:
Ver tudo funcionando mais rápido, deixa mais empolgado pra terminar tudo mais rápido.
E todos já devem ter percebido como estou empolgado.... rs
E ainda tenho DBFs, ainda nem me livrei de todos eles !!!
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 26 Jan 2020 22:17

jpnotfis.png


O jpnotfis.dbf é o que estou eliminando, mas todos os NÃO marcados com X estão dentro do MySQL.
Acabei acrescentando os outros pra facilitar.

Pensando bem... acho que dava pra eliminar o jpestoque primeiro...
Se é que ainda precisa dele... rs
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 26 Jan 2020 22:19

Vixe... não precisa mais dele....
Eliminei a necessidade de um DBF e nem percebi kkkk
Não usa em mais lugar nenhum.

jpestoque.png
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: 18127
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Anterior Próximo



Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 6 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