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 » 26 Jan 2020 22:47

Ok, erro de programador.

   IF AppVersaoDbfAnt() < 20200101;   Update0100A(); ENDIF
   IF AppVersaoDbfAnt() > 20200101;   Update0100B(); ENDIF // apagar apos ok
   IF AppVersaoDbfAnt() < 20200102.1; Update0102A(); ENDIF
   IF AppVersaoDbfAnt() < 20200102.2; Update0102B(); ENDIF
   IF AppVersaoDbfAnt() < 20200110.1; Update0110A(); ENDIF
   IF AppVersaoDbfAnt() < 20200113.1; Update0113A(); ENDIF
   IF AppVersaoDbfAnt() < 20200116.1; Update0116A(); ENDIF

   RETURN NIL


No segundo IF, por precaução, é sinal de maior, mas deixei nas atualizações de 2019.
Como já passou.... nunca era executado.

Porque diferente:

Entra a versão 2020, digamos que no cliente seja 2018, faz toda conversão, mas não vai apagar nada.
Na próxima entrada, que tudo está convertido e a versão mudou pra 2020, sinal de que tudo correu bem, então apaga.
Fiz isso como precaução.

Mas... deixei em 2019... e se a versão mudou pra 2020, nem processa nenhuma conversão de 2019, nem essa.

jpestoque.png


Agora sim, 2 DBFs a menos, e 100MB a menos em DBF.

Pois é... perdendo tempo e espaço à toa fazendo backup desses 100MB.... rs
Ainda bem que fui postar aqui, e reparei no jpestoque.dbf...
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: 18160
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 23:08

Pra quem não entendeu:

Toda migração de DBF pra MySQL está sendo automática.
O cliente clica em atualizar versão, e o que era DBF vira MySQL.
Está sendo tudo automático.
Não precisa mais desse jpestoque.dbf, faltava apagar o DBF.
Na próxima atualização que o cliente fizer, o arquivo será apagado.

Está sendo assim desde o começo.
Daqui a pouco, não tem mais nenhum DBF na pasta, e o cliente nem vai perceber.
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: 18160
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 » 29 Jan 2020 17:11

jpnotfis.png


Tá baixando o uso do jpnotfis.dbf.
Faltam menos de 187 lugares.
Se comecei pelos mais simples, sinal de que faltam os que precisam de mais atenção.

Os mais simples serviram pra ir adquirindo experiência, talvez esses tenham se tornado simples agora.
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: 18160
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 » 30 Jan 2020 18:46

O que tenho feito nos fontes mais "delicados":

Recapitulando:
Um fonte pode depender de DBFs abertos e posicionados.
E este fonte pode chamar outros fontes, e outros, e mais outros, e sempre dependendo dos DBFs posicionados.

Estou pegando o mais interno, e alterando pra depender apenas de um código.
Por exemplo, na geração do XML de NFE, o bloco de cobrança:

NfeBlocoCobranca( @cXml, jpnotfis->idNotFis )
...
STATIC FUNCTION NfeBlocoCobranca( cXml, midNotFis )

Alterei pra receber a ID da nota fiscal, e com essa ID gera o bloco.
O anterior dependia disso, e continua dependendo, então nada mudou na rotina anterior.
Mas, para o bloco de cobrança, passou a depender somente de um valor.

Qual a diferença?
Depois altero o anterior pra também não depender do DBF.

Preciso retirar a dependência do DBF aberto, e é o que estou fazendo, uma rotina por vez.
Se fosse fazer diferente.... vixe... muitos problemas até conseguir finalizar
Retirando uma rotina por vez: pode ser instalado imediatamente nos clientes.

Isso é legal: poder deixar sempre em uso o fonte mais atualizado.

Lembram do princípio da programação: dividir um problema grande em problemas pequenos, porque os pequenos a gente resolve fácil, e acaba resolvendo o problema grande no final.
Pois é... é o que estou fazendo, pequenas conversões mais simples, que no final vão converter tudo.

Na postagem anterior faltavam 187 lugares pra eliminar jpnotfis.dbf, agora 107
Sendo que, além de eliminar o uso de jpnotfis.dbf desses fontes, já estou eliminando de outros DBFs também.

meutrabalho.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: 18160
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 » 30 Jan 2020 23:19

Como curiosidade, vou alterar este bloco agora.
Já acrescentei mIdNotFis como parâmetro, agora alterar pra não precisar DBF.
Já tinha alterado a transportadora, mas vou aproveitar pra fazer um único comando SQL pegando tudo.
Talvez acrescente algo mais no SQL, só pra ter menos fonte PRG.

STATIC FUNCTION NfeBlocoTransporte( cXml, midNotFis )

   LOCAL mPlaca, cnMySql := ADOClass():New( AppConexao() )
   LOCAL mtpNome, mtpCnpj, mtpInsEst, mtpEndereco, mtpCidade, mtpUF

   WITH OBJECT cnMySql
      :cSql := "SELECT TPNOME, TPCNPJ, TPINSEST, TPENDERECO, TPNUMERO, TPCOMPL, TPBAIRRO, TPCIDADE, TPUF " + ;
         "FROM JPTRANSP WHERE IDTRANSP=" + StringSql( jpnotfis->nfCadTra )
      :Execute()
      mtpNome     := :String( "TPNOME" )
      mtpCnpj     := :String( "TPCNPJ" )
      mtpInsEst   := :String( "TPINSEST" )
      mtpEndereco := :String( "TPENDERECO" ) + " " + :String( "TPNUMERO" ) + " " + :String( "TPCOMPL" ) + ;
         " " + :String( "TPBAIRRO" )
      mtpCidade   := :String( "TPCIDADE" )
      mtpUF       := :String( "TPUF" )
      :CloseRecordset()
   ENDWITH

   cXml += [<transp>]
   DO CASE
   CASE jpnotfis->nfPagFre $ "R0" .AND. ! Empty( mtpNome )
      cXml += XmlTag( "modFrete", "0" )
   CASE jpnotfis->nfPagFre $ "D1" .AND. ! Empty( mtpNome )
      cXml += XmlTag( "modFrete", "1" )
   CASE jpnotfis->nfPagFre $ "T2" .AND. ! Empty( mtpNome )
      cXml += XmlTag( "modFrete", "2" )
   CASE jpnotfis->nfPagFre $ "3" .AND. ! Empty( mtpNome )
      cXml += XmlTag( "modFrete", "3" )
   CASE jpnotfis->nfPagFre $ "4" .AND. ! Empty( mtpNome )
      cXml += XmlTag( "modFrete", "4" )
   OTHERWISE // CASE jpnotfis->nfPagFre == "N"
      cXml += XmlTag( "modFrete", "9" )
   ENDCASE

   IF ! Empty( mtpNome )
      cXml += [<transporta>]
      IF Len( SoNumeros( mtpCnpj ) ) != 0
         IF Len( SoNumeros( mtpCnpj ) ) == 14
            cXml += XmlTag( "CNPJ", SoNumeros( mtpCnpj ) )
         ELSE
            cXml += XmlTag( "CPF", SoNumeros( mtpCnpj ) )
         ENDIF
      ENDIF
      cXml += XmlTag( "xNome", mtpNome )
      IF Len( SoNumeros( mtpInsEst ) ) != 0
         cXml += XmlTag( "IE", SoNumeros( mtpInsEst ) )
         cXml += XmlTag( "xEnder", Trim( Pad( mtpEndereco, 60 ) ) )
         cXml += XmlTag( "xMun", mtpCidade )
         cXml += XmlTag( "UF", mtpUF )
      ENDIF
      cXml += [</transporta>]
   ENDIF
   mPlaca := AllTrim( jpnotfis->nfVeiculo )
   mPlaca := StrTran( mPlaca, "-", "" )
   IF Len( mPlaca ) > 5
      cXml += [<veicTransp>]
      cXml += XmlTag( "placa", mPlaca )
      cXml += XmlTag( "UF", "SP" )
      cXml += [</veicTransp>]
   ENDIF
   cXml += [<vol>]
   cXml += XmlTag( "qVol", jpnotfis->nfQtdVol, 0 )
   cXml += XmlTag( "esp", iif( Len( Trim( jpnotfis->nfEspecie ) ) == 0, "UNID", jpnotfis->nfEspecie ) )
   cXml += XmlTag( "marca", "." )
   cXml += XmlTag( "nVol", "." )
   cXml += XmlTag( "pesoL", jpnotfis->nfPesLiq, 3 )
   cXml += XmlTag( "pesoB", jpnotfis->nfPesBru, 3 )
   cXml += [</vol>]
   cXml += [</transp>]

   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: 18160
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 » 30 Jan 2020 23:52

Pronto, sem mais DBF na rotina.

STATIC FUNCTION NfeBlocoTransporte( cXml, midNotFis )

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

   WITH OBJECT cnMySql
      :cSql := "SELECT NFVEICULO, NFQTDVOL, NFPESLIQ, NFPESBRU," + ;
         " IF( JPTRANSP.IDTRANSP IS NULL, '9', IF( NFPAGFRE IN ( '0', '1', '2', '3', '4', '9' ), " + ;
         " NFPAGFRE, IF( NFPAGFRE = 'R', '0', IF( NFPAGFRE = 'D', '1', IF( NFPAGFRE = 'T', '2'," + ;
         " '9' ) ) ) ) ) AS PAGFRE," + ;
         " IF( LENGTH( NFESPECIE ) < 1, 'UNID', NFESPECIE ) AS ESPECIE," + ;
         " JPTRANSP.TPNOME AS NOME, JPTRANSP.TPCNPJ AS CNPJ, JPTRANSP.TPINSEST AS INSEST," + ;
         " TRIM( LEFT( CONCAT( JPTRANSP.TPENDERECO, ' ', JPTRANSP.TPNUMERO, ' ', JPTRANSP.TPCOMPL, ' ', JPTRANSP.TPBAIRRO ), 60 ) ) AS ENDERECO," + ;
         " JPTRANSP.TPCIDADE AS CIDADE, JPTRANSP.TPUF AS UF" + ;
         " FROM JPNOTFIS" + ;
         " LEFT JOIN JPTRANSP ON JPTRANSP.IDTRANSP = JPNOTFIS.NFCADTRA" + ;
         " WHERE IDNOTFIS = " + StringSql( midNotFis )
      :Execute()

      cXml += [<transp>]
      cXml += XmlTag( "modFrete", :String( "PAGFRE", 1  ) )
      IF ! Empty( :String( "NOME" ) )
         cXml += [<transporta>]
         IF Len( SoNumeros( :String( "CNPJ" ) ) ) != 0
            IF Len( SoNumeros( :String( "CNPJ" ) ) ) == 14
               cXml += XmlTag( "CNPJ", SoNumeros( :String( "CNPJ" ) ) )
            ELSE
               cXml += XmlTag( "CPF", SoNumeros( :String( "CNPJ" ) ) )
            ENDIF
         ENDIF
         cXml += XmlTag( "xNome", :String( "NOME" ) )
         IF Len( SoNumeros( :String( "INSEST" ) ) ) != 0
            cXml += XmlTag( "IE", SoNumeros( :String( "INSEST" ) ) )
            cXml += XmlTag( "xEnder", :String( "ENDERECO" ) )
            cXml += XmlTag( "xMun", :String( "CIDADE" ) )
            cXml += XmlTag( "UF", :String( "UF" ) )
         ENDIF
         cXml += [</transporta>]
      ENDIF
      mPlaca := AllTrim( :String( "NFVEICULO" ) )
      mPlaca := StrTran( mPlaca, "-", "" )
      IF Len( mPlaca ) > 5
         cXml += [<veicTransp>]
         cXml += XmlTag( "placa", mPlaca )
         cXml += XmlTag( "UF", :String( "UF" ) )
         cXml += [</veicTransp>]
      ENDIF
      cXml += [<vol>]
      cXml += XmlTag( "qVol", :Number( "NFQTDVOL" ), 0 )
      cXml += XmlTag( "esp", :String( "ESPECIE" ) )
      cXml += XmlTag( "marca", "." )
      cXml += XmlTag( "nVol", "." )
      cXml += XmlTag( "pesoL", :Number( "NFPESLIQ" ), 3 )
      cXml += XmlTag( "pesoB", :Number( "NFPESBRU" ), 3 )
      cXml += [</vol>]
      cXml += [</transp>]
      :CloseRecordset()
   ENDWITH

   RETURN NIL


e baixou um pouco mais

jpnotfis.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: 18160
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 » 31 Jan 2020 01:36

Mas uma possibilidade poderia ser:

SELECT CONCAT( '<xEnder>', ENDERECO, '</xEnder><xMun>', CIDADE, '</xMun><UF>', UF, '</UF>' ) AS XML


Poderia ser uma Stored Procedure, um VIEW, ou outra coisa dentro do banco de dados.
E aí, teremos a geração de XML dentro do MySQL, pra qualquer linguagem de programação.

Como eu disse, apenas mostrando possibilidades.

Me veio na cabeça a briga por escolher linguagem de programação, ou pra portar de Desktop pra mobile, etc.

No final, colocar no banco de dados talvez seja a melhor escolha. kkkkkk
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: 18160
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 » 13 Fev 2020 11:53

Só sobrou o uso nas atualizações de versão.
Esses fontes depois serão apagados, porque a única utilidade deles passa a ser caso precise usar um backup anterior, que precise conversão.

jpnotfis.png


Nota:
Não usa mais o DBF, mas ainda não retirei a gravação.
Deixar isso pra próxima.
Eliminar depois a gravação, e também o JPNOTFIS.DBF, porque não precisa mais dele.
Notas fiscais agora só em MySQL.
O DBF, vai ser só pra garantia de que tudo está ok, uma última conferência antes de apagar de vez.
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: 18160
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 » 13 Fev 2020 12:04

Acho que não cheguei a comentar isto:

O controle de versão, aonde tem MySQL está no MySQL.
Lógico, MySQL é mais seguro pra isso.
Aonde ainda é só DBF - que não vai mais ter emissão de nota fiscal - o controle de versão ainda é no DBF.

O aplicativo é único pra todos, quando chegar a hora, esses últimos só com contábil vão para o MySQL também.
Como eu já disse, o contábil libera empresas à vontade, deixar pra pensar nisso depois.
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: 18160
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 » 18 Fev 2020 16:33

Dica pra quem estiver pensando em MySQL:

Primeiro troque as chaves pra numérico, e só depois migre.
Comecei a fazer isso no meio do caminho.... vixe... vários bugs.

Não, MySQL não é problema, mas ajustar os campos no aplicativo.... são muitos... acaba sempre passando coisa...
E gravando duplicado em DBF então... aí piorou.... porque no DBF tá caractere e no MySQL está numérico...

Mas está indo....
Trabalhar com campo numérico é muito mais prático.
Só não estou alterando nos DBFs... porque infelizmente se alterar isso na estrutura vai dar erro de type mismatch.
Só mesmo no dBASE/FoxPro era permitido alterar campo de caractere pra numérico, no Clipper e Harbour não dá.
No MySQL ok, mas no DBF não.

Até que não é complicado, porque basta alterar no REPLACE e usar StrZero() e tudo bem.
Isso vale inclusive para o MySQL/MariaDB.

Isto é válido no MySQL:

UPDATE tabela SET CampoNumerico = '0'

Mas isto não:

UPDATE TABELA SET CampoNumerico = ' '

Inicialmente usava a própria variável, porque facilitou a montagem do comando, mas quando não tem número.... ERRO

cVar := "000000"
"UPDATE TABELA SET CampoNumero = " + ['] + cVar + [']

Então, passando pra numérico de vez, e alterando todo o aplicativo.
E StrZero() antes de salvar em DBF/MYSQL, assim funciona nos dois, DBF como caractere e MySQL como numérico.

Entrando nas partes que dão mais trabalho pra ajustar.
Ainda trocando nomes de campos pra padronizar, assim evita ficar errando nome.
Quem mandou deixar despadronizado kkkkk

Tipo... cadastro IdCadastro, no financeiro fiCliFor, no estoque esCliFor, na nota nfCadDes, no pedido pdCliFor
Agora vai virar idCadastro, fiCadastro, esCadastro, nfCadastro e pdCadastro
iniciais do arquivo seguido do nome do campo, exceto no cadastro principal, onde começa com ID.
De onde vém os campos xxCadastro? do arquivo dbf/tabela JPCADASTRO.
Agora sim... ficando padronizado.

Isso me lembra aquela questão: E se você morrer?
Mais fácil que isso impossível, qualquer um vai poder continuar a manutenção, pelo menos no que se refere a encontrar as informações.
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: 18160
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 » 24 Fev 2020 21:12


Erro executando comando:-2147217900 [ma-3.1.6][10.4.11-MariaDB]Unknown column 'ESITEM' in 'where clause'
Called from ADOCLASS:EXECUTECMD(254)
Called from ADOCLASS:EXECUTE(227)
Called from MOSTRAULTIMACOMPRA(1444)
Called from INCALTITEM(1345)
Called from DIGPED(940)
Called from (b)JPPEDIDOCLASS_TELADADOS(816)
Called from DBVIEW(638)
Called from JPPEDIDOCLASS:TELADADOS(816)
Called from JPPEDIDOCLASS:EXECUTE(426)
Called from P0600PED(70)
Called from DO(0)
Called from DOPRG(126)
Called from (b)RUNMODULE(96)


É erro, mas por enquanto é normal...

Estou padronizando nomes de campos, e esse ESITEM agora é ESPRODUTO, e falta ajustar TODOS os fontes ainda, para o novo nome, desse campo e de muitos outros.....

E isso com gravação dupla DBF + MySQL....
Mais divertido do que ficar vendo carnaval na TV kkkk

E tenho que aproveitar agora o carnaval, porque quarta feira já precisa estar instalado em cliente....
Aproveitei pra mexer em TUDO novamente kkkkk

E desta vez sim: fechar a versão, obrigar todos a atualizarem, e remover tudo que é conversão.
Esse negócio de manter conversões anteriores pra cliente atualizar quando quiser, neste momento complicou, porque estou tendo até que refazer conversões anteriores, porque o MYSQL vai estar totalmente atualizado, e qualquer DBF ainda não atualizado vai precisar ser atualizado antes de transferir para o MySQL... coisa que em vários clientes já foi feito e nem precisa mais disso.

No MySQL é moleza, só alterar o nome do campo e pronto.
Mas em DBF é mais chato, precisa processamento porque não dá pra fazer direto.

Pois é... perdendo tempo com DBFs que vão pro lixo kkkk
Mas faz parte, fazer o que....
E gravando duplicado serve como garantia pra algum problema eventual.

Pensando bem.... se agora tá direcionado primariamente pra MySQL, poderia até apagar coisas antigas do DBF, que não vão fazer falta...
Mas não agora, deixa primeiro eu arrumar a bagunça que comecei, porque nada mais funciona, por enquanto kkkk

Nota:
Na prática, nem sei se algum cliente ainda precisa dessas conversões antigas, talvez todos já tenham atualizado.
Mas na dúvida tenho que atualizar, pra não ter imprevisto.
Por isso obrigar a atualizarem, inclusive já criei controle disso no meu website, assim fica registrado que versão cada um está usando.
LIMPEZA GERAL EM MARÇ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: 18160
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 Fev 2020 10:06

Esta é apenas uma das mudanças do carnaval:

STATIC FUNCTION JPEDICFGCreateMySql()

RETURN ;
"CREATE TABLE IF NOT EXISTS JPEDICFG ( " + ;
"EDID INT(11) NOT NULL AUTO_INCREMENT, " + ;
"EDNUMLAN VARCHAR(6) NOT NULL DEFAULT '', " + ;
"EDTIPO VARCHAR(6) NOT NULL DEFAULT '', " + ;
"EDCODJPA VARCHAR(6) NOT NULL DEFAULT '', " + ;
"EDCODEDI1 VARCHAR(20) NOT NULL DEFAULT '', " + ;
"EDCODEDI2 VARCHAR(20) NOT NULL DEFAULT '', " + ;
"EDDESEDI VARCHAR(50) NOT NULL DEFAULT '', " + ;
"EDINFINC VARCHAR(80) NOT NULL DEFAULT '', " + ;
"EDINFALT VARCHAR(80) NOT NULL DEFAULT '', " + ;
"PRIMARY KEY ( EDID ), " + ;
"INDEX IDXJPEDICFG ( EDNUMLAN, EDID ), " + ;
"INDEX IDXEDI ( EDTIPO, EDCODEDI1, EDCODEDI2, EDNUMLAN ), " + ;
"INDEX IDXJPA ( EDTIPO, EDCODJPA, EDCODEDI1, EDNUMLAN ) " + ;
") COLLATE=latin1_swedish_ci ENGINE=InnoDB"



STATIC FUNCTION JPEDICFGCreateMySql()

RETURN ;
"CREATE TABLE IF NOT EXISTS JPEDICFG ( " + ;
"IDEDICFG INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + ;
"EDTIPO VARCHAR(6) NOT NULL DEFAULT '', " + ;
"EDEMPRESA VARCHAR(20) NOT NULL DEFAULT '', " + ;
"EDEXTERNO VARCHAR(20) NOT NULL DEFAULT '', " + ;
"EDINTERNO VARCHAR(6) NOT NULL DEFAULT '', " + ;
"EDDESCRICAO VARCHAR(50) NOT NULL DEFAULT '', " + ;
"EDINFINC VARCHAR(80) NOT NULL DEFAULT '', " + ;
"EDINFALT VARCHAR(80) NOT NULL DEFAULT '', " + ;
"PRIMARY KEY ( IDEDICFG ), " + ;
"INDEX IDXEXTERNO ( EDTIPO, EDEMPRESA, EDEXTERNO ), " + ;
"INDEX IDXINTERNO ( EDTIPO, EDEMPRESA, EDINTERNO ) " + ;
") COLLATE=latin1_swedish_ci ENGINE=InnoDB"


É o "conversor" de notas, ficou "menos ruim".

EDCODJPA => EDINTERNO = código interno do aplicativo
EDCODEDI1 => EDEMPRESA = empresa sendo integrada
EDCODEDI2 => EDEXTERNO = código usado pela empresa, portanto externo
EDDESEDI => EDDESCRICAO = descrição usada pela empresa/nota da empresa

Se minha migração pra MySQL não é rápida, é porque estou dando uma geral ainda durante a migraçã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: 18160
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 Fev 2020 13:54

Uia...

Erro executando comando:-2147217900 [ma-3.1.6][10.4.11-MariaDB]Unknown column 'FICLIFOR' in 'field list'


IF :FieldExists( "FICLIFOR", "JPFINAN" )
:ExecuteCmd( "ALTER TABLE JPFINAN CHANGE COLUMN FICLIFOR FICADASTRO VARCHAR(6) NOT NULL DEFAULT '000000'" )
ENDIF


Normal, se alterei o campo FICLIFOR pra FICADASTRO... FICLIFOR não existe mais kkkk

Pois é... é o que dá atender telefone no meio de alterações kkkkk

Aí tem um ponto importante:

Minha migração e alteração de campos se torna menos problemática porque tenho padrão no nome dos campos.
TODO campo começando com FI... é do arquivo do financeiro.
FICADASTRO só pode ser o código de cadastro no arquivo/tabela do financeiro.
Se estou mexendo nele, fica fácil localizar em TODOS os fontes aonde preciso alterar, basta o FIND IN FILES.

Então... meu modo de trabalho é facilitado para... o modo que eu trabalho.
Fica mais seguro mexer em muitas coisas, porque está fácil identifica-las nos fontes.
O que vale pra mim pode não valer pra outros fontes, com modo de trabalho diferente.
Se em todos os arquivos fosse IDCadastro... aí ficaria impossível identificar quais os fontes que usam aquele campo daquela tabela, a não ser olhando um a um...
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: 18160
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 » 03 Mar 2020 20:37

Uma das alterações deste final de semana:

antes:

METHOD MostraReserva() CLASS JPITEMClass

   LOCAL nSelect := Select()
   LOCAL nOrdSetFocus, nKey := 0, aaPedidoList := {}, acList, oElement

   Mensagem( "Pesquisando nos pedidos, ESC cancela" )
   SELECT jpitped
   nOrdSetFocus := OrdSetFocus()
   OrdSetFocus( "jpitped2" )
   SEEK jpitem->idItem
   DO WHILE nKey != K_ESC .AND. jpitped->ipItem == jpitem->idItem .AND. ! Eof()
      nKey := Inkey()
      Encontra( jpitped->ipPedido, "jppedido", "pedido" )
      IF jppedido->pdConf != "S"
         SKIP
         LOOP
      ENDIF
      IF Left( jpitped->ipCfOp, 1 ) < "5"
         SKIP
         LOOP
      ENDIF
      IF Encontra( jppedido->idPedido, "jpnotfis", "pedido" )
         SKIP
         LOOP
      ENDIF
      IF ! "+R" $ ReacaoJPTRANSA( jppedido->pdTransa )
         SKIP
         LOOP
      ENDIF
      AAdd( aaPedidoList, { jppedido->idPedido, jppedido->pdDatEmi, jpitped->ipQtde } )
      SKIP
   ENDDO
   OrdSetFocus( nOrdSetFocus )
   SELECT( nSelect )
   Mensagem()
   IF Len( aaPedidoList ) == 0
      MsgExclamation( "Não há reserva deste produto" )
   ELSE
      acList := {}
      FOR EACH oElement IN aaPedidoList
         AAdd( acList, oElement[ 1 ] + " " + Dtoc( oElement[ 2 ] ) + " " + Str( oElement[ 3 ], 10, 2 ) )
      NEXT
      Atail( AppForms() ):GUIHide()
      wAChoice( 10, 2, acList, 1, "RESERVA " + jpitem->idItem + " " + Trim( jpitem->ieDescri ) )
      Atail( AppForms() ):GUIShow()
   ENDIF

   RETURN NIL


depois:

METHOD MostraReserva() CLASS JPITEMClass

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

   mIdProduto := Val( jpitem->idProduto )

   WITH OBJECT cnMySql
      :cSql := "SELECT JPPEDIDO.IDPEDIDO, JPPEDIDO.PDDATEMI, IPQTDE" + ;
         " FROM JPITPED" + ;
         " LEFT JOIN JPPEDIDO ON JPPEDIDO.IDPEDIDO = JPITPED.IPPEDIDO" + ;
         " LEFT JOIN JPNOTFIS ON JPNOTFIS.NFPEDIDO = JPPEDIDO.IDPEDIDO" + ;
         " LEFT JOIN JPTRANSA ON JPPEDIDO.PDTRANSA = JPTRANSA.IDTRANSA" + ;
         " WHERE JPPEDIDO.PDCONF = 'S'" + ;
         " AND LEFT( JPITPED.IPCFOP, 1 ) >= '5'" + ;
         " AND JPNOTFIS.IDNOTFIS IS NULL" + ;
         " AND JPTRANSA.TRREACAO LIKE '%+R%'" + ;
         " AND JPITPED.IPPRODUTO = " + NumberSql( mIdProduto )
      :Execute()
      OTBrowse := { ;
         { "PEDIDO",   { || StrZero( :Number( "IDPEDIDO" ), 6 ) } }, ;
         { "EMISSAO",  { || :Date( "PDDATEMI" ) } }, ;
         { "QTDE",     { || Str( :Number( "IPQTDE" ), 16, 5 ) } } }
      BrowseADO( cnMySql, oTBrowse )
      :CloseRecordset()
   ENDWITH

   RETURN NIL


Por enquanto ficou preso a JPITEM estar aberto pra pegar o código do produto.
Depois altero pra receber o código por parâmetro e altero a(s) rotina(s) que faz(em) chamada pra ela.
E assim vai indo, eliminando o uso de DBFs em uma rotina por vez.

Detalhe que pode ter passado desapercebido:

mIdProduto := Val( jpitem->idProduto )

Pois é... nem terminei a conversão, e já alterei de novo.
O nome do campo era IEITEM, depois idItem, e agora idProduto
E pra complicar... decidi alterar o aplicativo pra trabalhar com numérico, antes de terminar a conversão.
No DBF ainda é caractere....

Instalei hoje, com certeza vários bugs pra resolver.
E com certeza isso fica facilitado por estar usando compilação -w3 -es2, e por ter o recurso de find-in-files, procurar em todos os fontes, o nome do campo.

Tá valendo a pena o trabalho.

Não tem mais arquivo aberto, não tem mais arquivo temporário/array temporário, é só pedir pro servidor e mostrar.
SELECT, nAnterior := Select(), SEEK, etc. isso não existe mais.
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: 18160
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 » 05 Mar 2020 12:13

Alteração do momento:

   Encontra( StrZero( mIdCadastro, 6 ), "jpcadastro", "numlan" )
   oBoleto:Calcula()
   oBoleto:cBeneficNome := Trim( jpempresa->emNome )
   oBoleto:cBeneficEnd1 := Trim( jpempresa->emEndereco )
   oBoleto:cBeneficEnd2 := Trim( jpempresa->emCep ) + " " + Trim( jpempresa->emBairro ) + " " + Trim( jpempresa->emCidade ) + " " + jpempresa->emUf
   oBoleto:cPagadorNome := Trim( jpcadastro->cdNome ) + " " + jpcadastro->cdCnpj
   oBoleto:cPagadorEnd1 := Trim( jpcadastro->cdEndereco ) + " " + Trim( jpcadastro->cdNumero ) + " " + Trim( jpcadastro->cdCompl )
   oBoleto:cPagadorEnd2 := jpcadastro->cdCep + " " + Trim( jpcadastro->cdBairro ) + " " + Trim( jpcadastro->cdCidade ) + " " + jpcadastro->cdUf
   oBoleto:cAvalista    := Trim( jpcadastro->cdNome ) + " " + jpcadastro->cdCnpj


   WITH OBJECT cnMySql
      :cSql := "SELECT CONCAT_WS( ' ', CDNOME, CDCNPJ ) AS PAGADORNOME, " + ;
         " CONCAT_WS( ' ', CDENDERECO, CDNUMERO, CDCOMPL ) AS PAGADOREND1," + ;
         " CONCAT_WS( ' ', CDCEP, CDBAIRRO, CDCIDADE, CDUF ) AS PAGADOREND2," + ;
         " CONCAT_WS( ' ', CDNOME, CDCNPJ ) AS AVALISTA" + ;
         " FROM JPCADASTRO WHERE IDCADASTRO = " + NumberSql( mIdCadastro )
      :Execute()
      oBoleto:Calcula()
      oBoleto:cBeneficNome := Trim( jpempresa->emNome )
      oBoleto:cBeneficEnd1 := Trim( jpempresa->emEndereco )
      oBoleto:cBeneficEnd2 := Trim( jpempresa->emCep ) + " " + Trim( jpempresa->emBairro ) + " " + Trim( jpempresa->emCidade ) + " " + jpempresa->emUf
      oBoleto:cPagadorNome := :String( "PAGADORNOME" )
      oBoleto:cPagadorEnd1 := :String( "PAGADOREND1" )
      oBoleto:cPagadorEnd2 := :String( "PAGADOREND2" )
      oBoleto:cAvalista    := :String( "AVALISTA" )
      :CloseRecordset()
   ENDWITH


Menos código Harbour, mais código SQL.
À primeira vista: o fonte Harbour fica mais simples

Cada vez mais eu estou pensando no seguinte:
Código fonte XBASE... uma eterna busca de substituto Clipper
Código SQL... pronto pra tudo
Eternamente esperar XBASE ou.... deixar pronto pra qualquer coisa que exista?
Então... menos fonte Harbour significa cada vez mais pronto pra qualquer coisa.

O que vém depois disso?
Se pode ser qualquer coisa... também pode ser o Harbour... não tenho nenhum motivo pra quebrar a cabeça procurando alternativa pro Harbour, talvez algum dia no 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: 18160
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 17 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