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 » 04 Ago 2020 15:19

Erro de hoje:

whatsapp.png


Problema:

erro.png


Coloquei pra salvar a soma de valor de ST, ao invés de base de ST.

Problemas desse tipo.... aí tanto faz se é DBF, SQL... errou salva errado kkkk

Como solução rápida, no cliente usei o HeidiSQL, fiz o select com relacionamento e alterei o conteúdo manualmente.
E já alterei o aplicativo, agora faz certo.

Tava errado no pedido e na nota fiscal, já que o total da nota vém do pedido.

Nota:
Já estava em uso há alguns dias em outros clientes.
Esse não atualizava desde MAIO deste ano.
Foi a primeira nota com substituição tributária, desde a mudança desse fonte pra SQL.

Ou seja: ele estava com DBF antes do almoço, passou pra MySQL depois do almoço, e deu esse erro, porque tava errado mesmo, nenhum outro problema.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 04 Ago 2020 15:37

Aproveitando:

Então....

Eu atualizo estruturas automático, tanto DBF quanto MySQL.
Salvar dados de DBF pra MySQL, também automático.
O aplicativo tem atualização automática, é uma opção no menu.

Lembram? fonte fácil, atualização fácil, conversão fácil, tudo fácil.
Isso torna a correção de erros fácil e rápida.

Seria muuuito diferente, se eu tivesse que ir no cliente, pesquisar o problema, levar fontes, utilitários, etc.

Tem que pensar em todo conjunto, tudo que puder facilitar pra gente, melhor.
Cometo erros igual todo mundo, mas essas coisas facilitam fazer manutenção, e por isso tudo foi rápido/fácil.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 07 Ago 2020 14:59

Chegou a hora.
Fiz uma cópia do aplicativo como jpa202008.exe como precaução.
Começar a limpar isto agora:

19/06/2020  17:41             7.666 ze_update.prg
26/06/2020  10:37            22.801 ze_update2020.prg
31/03/2020  18:20             2.004 ze_updatea.prg
28/05/2020  01:29            19.315 ze_updateb.prg
28/05/2020  01:34            19.656 ze_updatec.prg
08/06/2020  22:12            25.138 ze_updated.prg
22/03/2020  13:14            17.515 ze_updatedefault.prg
19/06/2020  17:41            26.352 ze_updatee.prg
10/06/2020  07:54             7.647 ze_updateexedown.prg
04/06/2020  13:03             6.069 ze_updateexeup.prg
14/05/2020  14:23            21.976 ze_updatef.prg
19/06/2020  12:35            23.814 ze_updateg.prg
20/05/2020  03:43            20.502 ze_updateh.prg
              13 arquivo(s)        220.455 bytes


Tem criação/atualização de estrutura de DBF e de MySQL.
E transferência de DBF pra MySQL.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 07 Ago 2020 15:18

Achei que ia reduzir mais.

07/08/2020  14:22             9.328 ze_update.prg
07/08/2020  15:06            14.480 ze_update2020.prg
01/08/2020  06:36             2.071 ze_updatea.prg
07/08/2020  14:49            17.200 ze_updateb.prg
07/08/2020  15:00            15.497 ze_updatec.prg
07/08/2020  14:55            18.460 ze_updated.prg
30/07/2020  04:09            15.340 ze_updatedefault.prg
07/08/2020  15:03            15.372 ze_updatee.prg
17/07/2020  17:16             7.651 ze_updateexedown.prg
04/06/2020  13:03             6.069 ze_updateexeup.prg
07/08/2020  14:30            13.279 ze_updatef.prg
07/08/2020  14:46            16.967 ze_updateg.prg
07/08/2020  15:05            23.646 ze_updateh.prg
              13 arquivo(s)        175.360 bytes


Exceto por esta rotina, o aplicativo não sabe mais sobre muitos DBFs que já existiram.

STATIC FUNCTION UpdateDeleteOld()

   LOCAL cFile, nIdade, aList := { ;
      "ba_auto", ;
      "ba_grup", ;
      "ba_movi", ;
      "jpbaauto", ;
      "jpbaccusto", ;
      "jpbagrup", ;
      "jpanpage", ;
      "jpanpati", ;
      "jpanpins", ;
      "jpanploc", ;
      "jpbamovi", ;
      "jpanpope", ;
      "jpanppro", ;
      "jpbancario", ;
      "jpbarra", ;
      "jpcadastro", ;
      "jpcarcor", ;
      "jpclista", ;
      "jpcep", ;
      "jpcfop", ;
      "jpcomissao", ;
      "jpcotaca", ;
      "jpcotcli", ;
      "jpcotfor", ;
      "jpcotpro", ;
      "jpcte", ;
      "jpdecret", ;
      "jpdocrel", ;
      "jpedicfg", ;
      "jpestoque", ;
      "jpfinan", ;
      "jpfiscal", ;
      "jpfisica", ;
      "jpforpag", ;
      "jpibpt",   ;
      "jpimposto", ;
      "jpitem", ;
      "jpitped", ;
      "jplicmov", ;
      "jplogsi", ;
      "jpmdfcab", ;
      "jpmdfdet", ;
      "jpmotori", ;
      "jpnfbase", ;
      "jpnfeger", ;
      "jpnfexml", ;
      "jpnotaca", ;
      "jpnotfis", ;
      "jpordbar", ;
      "jpordres", ;
      "jpordser", ;
      "jppedido", ;
      "jppreco", ;
      "jpprehis", ;
      "jppretab", ;
      "jpromcab", ;
      "jpromdet", ;
      "jptexto", ;
      "jptransa", ;
      "jptransp", ;
      "jpveiculo", ;
      "jpvendedor", ;
      "jpvvdem", ;
      "jpvvfin", ;
      "nfbase", ;
      "rastrea" }

   SayScroll( "Verificando velhos/desativados" )

   nIdade := iif( IsMaquinaJPA(), -1, 15 )
   FOR EACH cFile IN aList
      DeleteOldFiles( cFile + ".dbf", nIdade )
      DeleteOldFiles( cFile + ".cdx", nIdade )
   NEXT

   RETURN NIL


Na minha máquina apaga na hora, já nos clientes espera 15 dias após o último uso.
NÃO é rotina nova, então é possível que já tenha apagado na maioria dos clientes.

Pois é...
Rotinas automáticas de atualizar DBF, transferir pra MySQL, etc.
Tudo relacionado a DBF vai acabar sumindo....

NÃO... não terminei ainda.... continua faltando o contábil e relacionados.
Pra esses... nem tem nada de nota fiscal, estoque, etc. pra converter de DBF, é só apagar mesmo.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 07 Ago 2020 15:49

JoséQuintas escreveu:NÃO... não terminei ainda.... continua faltando o contábil e relacionados.
Pra esses... nem tem nada de nota fiscal, estoque, etc. pra converter de DBF, é só apagar mesmo.


Pra QUEM USA só contábil, o resto não é usado.
Lembrando que é tudo um único EXE, então o contábil não pode ficar de fora.
TUDO que tenho está num único EXE, tudo é atualizado ao mesmo tempo, seja dbf ou sql, então... no final nenhum fica de fora.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor Vlademiro » 08 Ago 2020 02:51

Seus aplicativos estão independentes de banco de dados devido ao ADO, mas vc está usando muita função nativa do MySQL, o que vai te deixar dependente dele. Uma coisa boa que vc poderia fazer é catalogar em algum local quais as funções nativas do MySQL que vc está usando para , se houver necessidade, criar essas funções em outro banco. Bancos como Sqlserver, Oracle e PostgreSQL tem o comando Create function. As vezes a função existe com nome diferente. Talvez compense só criar uma com o mesmo nome em vez de ficar mechendo no seu código e colocando IFs para cada banco.
Avatar de usuário

Vlademiro
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 647
Data de registro: 11 Jul 2005 02:46
Curtiu: 12 vezes
Mens.Curtidas: 43 vezes

Meu modo de trabalho

Mensagempor JoséQuintas » 08 Ago 2020 23:45

Ainda é cedo pra pensar nisso.
Teria que começar a mexer em outro, pra ver quais seriam as diferenças.

Um lado bom é que uso minha classe, então existe a possibilidade de colocar diferenças pra ela tratar.

Por exemplo, entre Excel e MySQL

METHOD TableList() CLASS ADOClass

   LOCAL acTableList := {}, Rs

   IF ".XLS" $ Upper( ::cn:ConnectionString )
      rs := ::cn:openSchema(20) // adSchemaTables
      DO WHILE ! Rs:Eof()
         IF ! "Print_Are" $ rs:Fields( "Table_Name" ):Value .AND. ;
               ! "FilterDatabase" $ rs:Fields( "Table_Name" ):Value
            AAdd( acTableList, "[" + rs:Fields( "Table_Name" ):Value + "]" )
         ENDIF
         rs:MoveNext()
      ENDDO
      rs:Close()
   ELSE
      ::cSQL := "SELECT DISTINCT table_name AS TABELA FROM information_schema.TABLES WHERE table_schema=" + StringSQL( Lower( AppEmpresaApelido() ) )
      ::Execute()
      DO WHILE ! ::Eof()
         AAdd( acTableList, ::Value( "TABELA" ) )
         ::MoveNext()
      ENDDO
      ::CloseRecordset()
   ENDIF

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

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 08 Ago 2020 23:49

No VB também cheguei a ajustar pra MySQL ou ADS/SQL Server/etc.

If InStr(cSql, " TOP 1") <> 0 Then
   If InStr(UCase(cnConexao.ConnectionString), "MYSQL") <> 0 Then
      cSql = Replace(cSql, " TOP 1 ", " ")
      cSql = cSql & " LIMIT 1"
   End If
End If


Isso trocava o SELECT TOP 1 xxxxxx por SELECT xxx LIMIT 1

Pouca experiência com SQL, mas já preparado desde o início pra eventuais diferenças.
Nessa época, testando ADS com DBF mas preparado pra MySQL.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 09 Ago 2020 16:12

Reorganizei os "updates", mas ainda vou mexer.

09/08/2020  05:52            11.149 ze_update.prg
09/08/2020  05:20            48.203 ze_update2020.prg
09/08/2020  05:47            22.061 ze_updateDBF.prg
30/07/2020  04:09            15.340 ze_updatedefault.prg
09/08/2020  05:43            60.929 ze_updateSQL.prg


ze_update - é a atualização central, atualiza os arquivos de configuração e log, porque o resto depende deles

ze_updatesql - é o primeiro chamado, confere se as tabelas existem no MySQL, somente quando troca versão, pra não perder tempo no uso normal. De um modo geral é CREATE TABLE IF NOT EXISTS

ze_updatedbf - vou acabar incorporando no update2020, faz atualização nos DBFs que ainda restam
Alteração de estrutura, e compatiblidade com nova estrutura

ze_updatedefault - só pra gravar conteúdo default em certas tabelas

ze_update2020 - esse sim, faz muita coisa
- deixa o conteúdo dos DBFs compatível com a necessidade atual, seja pra uso como DBF ou pra transferir para o MySQL
- atualiza estruturas do MySQL, caso eu tenha alterado, por exemplo, campos caractere pra numérico
- Transfere para MySQL o que tiver que ser transferido
- Faz outros ajustes pra deixar compatível com versão atual

Atualizações antigas, não mais necessárias, é justamente o que comecei a apagar do ze_Update2020.
Por isso transferir a atualização de DBF aqui pra dentro acho correto, porque também vai acabar sendo apagado quando não mais existir DBF.

Acabei lembrando de um cliente que não atualiza há um ano.... pra esse, acaba sendo necessário manter as atualizações MySQL.
DBFs não, porque não fazem falta. Só uso meu aplicativo pra atualizar o outro, mas... precisa ser atualizado junto, pra continuar funcionando a atualizando no futuro. Talvez junte os dois aplicativos... não tem nada a ver um com o outro, mas... evita certas rotinas repetidas, ou ... esquecer de alguma dependência que não pode ser apagada - fontes de rotinas genéricas são compartilhadas nos dois, incluindo a classe ADO.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 09 Ago 2020 16:30

Pra curiosidade, a atualização entre versões, de DBF, SQL, e transferência

/*
ZE_UPDATE2020 - Atualizações 2020
*/

#include "inkey.ch"
#include "josequintas.ch"
#include "directry.ch"
#include "sefaz_anpprod.ch"

FUNCTION ze_Update2020()

   LOCAL nVersaoDBF

   nVersaoDBF := AppVersaoDbfAnt()

   SayScroll( "Atualizações 9/9 - atualizações por data" )

   IF nVersaoDBF < 20200101;   Update0100A();  ENDIF
   IF nVersaoDBF < 20200110;   Update0110();   ENDIF
   IF nVersaoDBF < 20200331;   Update03SQL( nVersaoDBF );  ENDIF
   IF nVersaoDBF < 20200430;   Update04SQL( nVersaoDBF );  ENDIF
   IF nVersaoDBF < 20200731;   Update07SQL( nVersaoDBF );  ENDIF
   IF nVersaoDBF < 20200705;   Update0705();   ENDIF
   IF nVersaoDBF < 20200707.2; Update0707();   ENDIF
   IF nVersaoDBF < 20200713;   Update0713();   ENDIF
   IF nVersaoDBF < 20200727.2; Update0727B();  ENDIF
   IF nVersaoDBF < 20200831;   Update08SQL( nVersaoDBF );  ENDIF
   CLOSE DATABASES

   RETURN NIL

STATIC FUNCTION VerificaNumeracao( cArquivo, cCampoChave, cCampoObs )

   LOCAL cId := StrZero( 0, 6 ), aList := {}, nAtual := 0, nTotal, nRecNo, cTmpFile

   SayScroll( "Verificando repetidos em " + cArquivo + ".DBF" )
   IF ! UseSoDbf( cArquivo, .T. )
      QUIT
   ENDIF
   cTmpFile := MyTempFile()
   INDEX ON &cCampoChave TO ( cTmpFile )
   GOTO TOP
   GrafTempo( cArquivo )
   nTotal := LastRec()
   DO WHILE ! Eof()
      GrafTempo( nAtual++, nTotal )
      IF FieldGet( FieldPos( cCampoChave ) ) <= cId .OR. Val( FieldGet( FieldPos( cCampoChave ) ) ) == 0
         AAdd( aList, RecNo() )
      ENDIF
      cId := FieldGet( FieldPos( cCampoChave ) )
      SKIP
   ENDDO
   IF Len( aList ) != 0
      FOR EACH nRecNo IN aList
         Inkey()
         GOTO ( nRecNo )
         cID := FieldGet( FieldPos( cCampoChave ) )
         IF Val( cID ) == 0
            GOTO BOTTOM
            cId := FieldGet( FieldPos( cCampoChave ) )
         ENDIF
         DO WHILE .T.
            SEEK cId
            IF Eof()
               EXIT
            ENDIF
            cId := StrZero( Val( cId ) + 1, 6 )
            Inkey()
         ENDDO
         GOTO ( nRecNo )
         SayScroll( "lançamento " + cArquivo + " de " + SoNumeros( FieldGet( FieldPos( cCampoChave ) ) ) + " para " + cID )
         GravaOcorrencia( cArquivo, cId, "lancamento " + cArquivo + " de " + SoNumeros( FieldGet( FieldPos( cCampoChave ) ) ) + " para " + cID )
         RecLock()
         IF cCampoObs != NIL .AND. ! Empty( cCampoObs )
            FieldPut( FieldPos( cCampoObs ), AllTrim( FieldGet( FieldPos( cCampoObs ) ) ) + " lanc.ant. " + ;
               FieldGet( FieldPos( cCampoChave ) ) )
         ENDIF
         FieldPut( FieldPos( cCampoChave ), cId )
         RecUnlock()
      NEXT
   ENDIF
   CLOSE DATABASES
   fErase( cTmpFile )

   RETURN NIL

STATIC FUNCTION Update0100A()

   IF ! AbreArquivos( "jpsenha" )
      QUIT
   ENDIF
   SayScroll( "2020-01-00-A Nome de módulos" )
   pw_AddModule( "PJPIMPOSTO",   "PLEISIMPOSTO" )
   pw_AddModule( "LJPIMPOSTO",   "PLEISRELIMPOSTO" )
   pw_AddModule( "PJPNOTFIS",    "PNOTACADASTRO" )
   pw_AddModule( "PJPDECRETO",   "PLEISDECRETO" )
   pw_AddModule( "PAUXPRODEP",   "PESTODEPTO" )
   pw_AddModule( "PAUXPROGRU",   "PESTOGRUPO" )
   pw_AddModule( "PAUXPROSEC",   "PESTOSECAO" )
   pw_AddModule( "PAUXPROUNI",   "PLEISPROUNI" )
   pw_AddModule( "PAUXPROLOC",   "PESTOLOCAL" )
   pw_AddModule( "PAUXCFOP",     "PLEISCFOP" )
   pw_AddModule( "PAUXTRIEMP",   "PLEISTRIEMP" )
   pw_AddModule( "PAUXTRICAD",   "PLEISTRICAD" )
   pw_AddModule( "PAUXTRIPRO",   "PLEISTRIPRO" )
   pw_AddModule( "PAUXTRIUF",    "PLEISTRIUF" )
   pw_AddModule( "PAUXICMCST",   "PLEISICMCST" )
   pw_AddModule( "PAUXIPICST",   "PLEISIPICST" )
   pw_AddModule( "PAUXIPIENQ",   "PLEISIPIENQ" )
   pw_AddModule( "PAUXORIMER",   "PLEISORIMER" )
   pw_AddModule( "PAUXPISCST",   "PLEISPISCST" )
   pw_AddModule( "PAUXPISENQ",   "PLEISPISENQ" )
   pw_AddModule( "PAUXCNAE",     "PLEISCNAE" )
   pw_AddModule( "PAUXCARCOR",   "PLEISCORRRECAO" )
   pw_AddModule( "PAUXMODFIS",   "PLEISMODFIS" )
   pw_AddModule( "LJPCADAS",     "LJPCADAS1" )
   pw_AddModule( "LJPPEDIDO",    "LJPPEDI" )
   pw_AddModule( "LJPTRANSP",    "LJPCADAS3" )
   pw_AddModule( "PJPCADAS",     "PJPCADAS1" )
   pw_AddModule( "PJPCADASB",    "PJPCADAS1B" )
   pw_AddModule( "PJPCOMISSAO",  "PJPCOMISS" )
   pw_AddModule( "PJPTRANSP",    "PJPCADAS3" )
   pw_AddModule( "PJPVEICULO",   "PJPVEICUL" )
   pw_AddModule( "PJPVENDEDOR",  "PJPVENDED" )
   pw_AddModule( "LJPESTOQUEA",  "LJPESTOQA" )
   pw_AddModule( "LJPESTOQUEB",  "LJPESTOQB" )
   pw_AddModule( "LJPESTOQUEC",  "LJPESTOQC" )
   pw_AddModule( "LJPESTOQUEA",  "PJPESTOQUEA" )
   pw_AddModule( "LJPESTOQUEB",  "PJPESTOQUEB" )
   pw_AddModule( "LJPESTOQUEC",  "PJPESTOQUEC" )
   pw_AddModule( "LJPCADASTRO",  "LJPCADAS" )
   pw_AddModule( "PJPCADASTRO",  "PJPCADAS" )
   pw_AddModule( "PJPCADASTROB", "PJPCADASB" )
   pw_AddModule( "PJPEMPRESA",   "PJPEMPRE" )
   pw_AddModule( "PJPCIDADE",    "PLEISCIDADE" )
   pw_AddModule( "PJPUF",        "PLEISUF" )
   pw_AddModule( "LJPCIDADE",    "PLEISRELCIDADE" )
   pw_AddModule( "PJPIBPT",      "PLEISIBPT" )
   CLOSE DATABASES

   RETURN NIL

STATIC FUNCTION Update0110()

   LOCAL oElement, cnSQL := ADOClass():New( AppConexao() )
   LOCAL aList := { ;
      ; // combustivel
      { 820101032, "L",  "DIESEL B S10/S50 PRA GERACAO ENERGIA" }, ;
      { 820101026, "L",  "DIESEL B S1800 PRA GERACAO DE ENERGIA" }, ;
      { 820101027, "L",  "DIESEL B S500 PRA GERACAO DE ENERGIA" }, ;
      { 820101017, "L",  "MIST DIESEL MARITMO 98% 2%" }, ;
      { 820101018, "L",  "DIESEL MARITMO 95% 5%" }, ;
      { 820101019, "L",  "DIESEL MARITMO DMB B2" }, ;
      { 820101020, "L",  "DIESEL MARITMO DMB B5" }, ;
      { 820101021, "L",  "DIESEL NAUTICO B2 ESPECIAL PPM ENXOFRE" }, ;
      { 420201001, "L",  "DIESEL MARITMO" }, ;
      { 420201003, "L",  "DMB MDO" }, ;
      { 430101004, "L",  "OLEO COMB TURBINA GERADORA" }, ;
      { 510103001, "KG", "OLEO COMBUSTIVEL 3 OC3" }, ;
      { 510101001, "KG", "OLEO COMBUSTIVEL 1A" }, ;
      { 510101002, "KG", "OLEO COMBUSTIVEL 2A" }, ;
      { 510102001, "KG", "OLEO COMBUSTIVEL B1" }, ;
      { 510102002, "KG", "OLEO COMBUSTIVEL B2" }, ;
      { 510201001, "KG", "OLEO COMBUSTIVEL MARITMO" }, ;
      { 510201003, "KG", "OLEO COMBUSTIVEL MARITMO MISTURA" }, ;
      { 510301003, "KG", "OLEO COMBUSTIVEL GERACAO ELETRICA" }, ;
      { 560101001, "L",  "OLEO DE XISTO" }, ;
      { 820101033, "L",  "OLEO DIESEL S10 ADITIVADO" }, ;
      { 820101034, "L",  "OLEO DIESEL S10 COMUM" }, ;
      { 820101011, "L",  "OLEO DIESEL BS1800 ADITIVADO" }, ;
      { 820101003, "L",  "MIST DIESEL 95% 5%" }, ;
      { 820101013, "L",  "OLEO DIESEL BS500 ADITIVADO" }, ;
      { 820101012, "L",  "OLEO DIESEL BS500 COMUM" }, ;
      { 420202001, "L",  "OLEO DIESEL NAUTICO ESP ENXOFRE 200 PPM" }, ;
      { 510301001, "KG", "OUTROS OLEOS COMBUSTIVEIS" }, ;
      { 410102001, "L",  "QUEROSENE ILUMINANTE" }, ;
      ; // outros
      { 650101004, "KG", "GRAXAS DE CALCIO" }, ;
      { 650101003, "KG", "GRAXAS DE LITIO" }, ;
      { 650101001, "KG", "GRAXAS MINERAIS" }, ;
      { 650101002, "KG", "OUTRAS GRAXAS" }, ;
      { 620502001, "L",  "MOTORES 2 TEMPOS" }, ;
      { 620501002, "L",  "CICLO DIESEL" }, ;
      { 620501001, "L",  "CICLO OTTO" }, ;
      { 620601003, "L",  "CORRENTE DE MOTOSSERRA" }, ;
      { 620601001, "L",  "OLEOS EXTENSORES E PLASTICICANTES" }, ;
      { 620601004, "L",  "OUTROS OLEOS LUBRIF ACABADOS" }, ;
      { 620601002, "L",  "PULVERIZACAO AGRICOLA" }, ;
      { 620401001, "L",  "OLEOS LUBRIF FERROVIARIOS" }, ;
      { 620101002, "L",  "ENGRENAGENS E SISTEMAS CIRCULATORIOS" }, ;
      { 620101007, "L",  "ESTAMPAGEM" }, ;
      { 620101001, "L",  "HIDRAULICO" }, ;
      { 620101004, "L",  "ISOLANTE TIPO A" }, ;
      { 620101005, "L",  "ISOLANTE TIPO B" }, ;
      { 620101008, "L",  "OUTROS OLEOS LUBRIF INDUST" }, ;
      { 620101003, "L",  "PROCESSO" }, ;
      { 620101006, "L",  "TEXTIL AMACIANTE DE FIBRAS" }, ;
      { 620301001, "L",  "OLEOS LUBRIF MARITMOS" }, ;
      { 620201001, "L",  "OLEOS LUBRIF AVIACAO" }, ;
      { 660101001, "L",  "OLEOS LUBRIF PARAF GRAXAS INTERMED" }, ;
      { 620505001, "L",  "OUTROS OLEOS LUBRIF AUTOMOTIVOS" }, ;
      { 620504001, "L",  "TRANSMISSAO AUTOMATICA" }, ;
      { 620503001, "L",  "TRANSMISSOES E SISTEMAS HIDRAULICOS" } }

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   SayScroll( "2020-01-10" )

   WITH OBJECT cnSQL
      FOR EACH oElement IN aList
         :QueryCreate()
         :QueryAdd( "IDANPPRO", StrZero( oElement[ 1 ], 9 ) )
         :QueryAdd( "APDESCRICAO", oElement[ 3 ] )
         :QueryAdd( "APUNIDADE", oElement[ 2 ] )
         :QueryAdd( "APISIMP", "S" )
         :QueryExecuteInsert( "JPANPPRO", .T. )
         Inkey()
      NEXT
      FOR EACH oElement IN SEFAZ_ANPPROD
         :QueryCreate()
         :QueryAdd( "IDANPPRO", oElement[ 1 ] )
         :QueryAdd( "APDESCRICAO", oElement[ 2 ] )
         :QueryAdd( "APISIMP", "N" )
         :QueryExecuteInsert( "JPANPPRO", .T. )
         Inkey()
      NEXT
   ENDWITH

   RETURN NIL

STATIC FUNCTION Update03SQL( nVersaoDBF )

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

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   SayScroll( "2020-03 SQL" )
   WITH OBJECT cnSQL
      IF nVersaoDBF < 20200302
         SayScroll( "2020-03-02 SQL" )
         :ExecuteCmd( "ALTER TABLE JPAGENDA CHANGE COLUMN IDAGENDA IDAGENDA INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPAGE CHANGE COLUMN IDANPAGE IDANPAGE INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPATI CHANGE COLUMN IDANPATI IDANPATI INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPINS CHANGE COLUMN IDANPINS IDANPINS INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPLOC CHANGE COLUMN IDANPLOC IDANPLOC INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPOPE CHANGE COLUMN IDANPOPE IDANPOPE INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPPRO CHANGE COLUMN IDANPPRO IDANPPRO INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPCLISTA CHANGE COLUMN IDCLISTA IDCLISTA INT(11) NOT NULL AUTO_INCREMENT" )
         IF :FieldExists( "CBID", "JPCOMBUSTIVEL" )
            :ExecuteCmd( "ALTER TABLE JPCOMBUSTIVEL DROP COLUMN CBID, DROP PRIMARY KEY" )
            :ExecuteCmd( "ALTER TABLE JPCOMBUSTIVEL ADD COLUMN IDCOMBUSTIVEL INT(11) NOT NULL AUTO_INCREMENT FIRST," + ;
               " ADD PRIMARY KEY ( IDCOMBUSTIVEL )" )
         ENDIF
         :ExecuteCmd( "ALTER TABLE JPCOMBUSTIVEL CHANGE COLUMN IDCOMBUSTIVEL IDCOMBUSTIVEL INT(11) NOT NULL AUTO_INCREMENT FIRST" )
         :ExecuteCmd( "ALTER TABLE JPCOMISSAO CHANGE COLUMN IDCOMISSAO IDCOMISSAO INT(11) NOT NULL AUTO_INCREMENT" )
         IF :FieldExists( "DENUMLAN", "JPDECRETO" )
            SayScroll( "Modificando tabela JPDECRETO" )
            :ExecuteCmd( "ALTER TABLE JPDECRETO DROP COLUMN DEID, DROP PRIMARY KEY, " + ;
               "CHANGE COLUMN DENUMLAN IDDECRETO INT(11) NOT NULL AUTO_INCREMENT, " + ;
               "ADD PRIMARY KEY ( IDDECRETO )" )
         ENDIF
         :ExecuteCmd( "ALTER TABLE JPDECRETO CHANGE COLUMN IDDECRETO IDDECRETO INT(11) NOT NULL AUTO_INCREMENT" )
         IF :IndexExists( "IDXEDICFG", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG DROP INDEX IDXEDICFG" )
         ENDIF
         IF :IndexExists( "IDXEDI", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG DROP INDEX IDXEDI" )
         ENDIF
         IF :IndexExists( "IDXJPA", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG DROP INDEX IDXJPA" )
         ENDIF
         IF :FieldExists( "EDID", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG CHANGE COLUMN EDID IDEDICFG INT(11) NOT NULL AUTO_INCREMENT," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDEDICFG )" )
         ENDIF
         IF :FieldExists( "IDREGISTRO", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG CHANGE COLUMN IDREGISTRO IDEDICFG INT(11) NOT NULL AUTO_INCREMENT," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDEDICFG )" )
         ENDIF
         IF :FieldExists( "EDNUMLAN", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG DROP COLUMN EDNUMLAN" )
         ENDIF
         IF :FieldExists( "EDCODEDI1", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG CHANGE COLUMN EDCODEDI1 EDEMPRESA VARCHAR(20) NOT NULL DEFAULT ''" )
         ENDIF
         IF :FieldExists( "EDCODJPA", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG CHANGE COLUMN EDCODJPA EDINTERNO VARCHAR(6) NOT NULL DEFAULT ''" )
         ENDIF
         IF :FieldExists( "EDCODEDI2", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG CHANGE COLUMN EDCODEDI2 EDEXTERNO VARCHAR(20) NOT NULL DEFAULT ''" )
         ENDIF
         IF :FieldExists( "EDDESEDI", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG CHANGE COLUMN EDDESEDI EDDESCRICAO VARCHAR(50) NOT NULL DEFAULT ''" )
         ENDIF
         IF ! :IndexExists( "IDXINTERNO", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG ADD INDEX IDXINTERNO ( EDTIPO, EDINTERNO )" )
         ENDIF
         IF ! :indexExists( "IDXEMPRESA", "JPEDICFG" )
            :ExecuteCmd( "ALTER TABLE JPEDICFG ADD INDEX IDXEMPRESA ( EDTIPO, EDEMPRESA, EDEXTERNO )" )
         ENDIF
      ENDIF
      IF nVersaoDBF < 20200312
         SayScroll( "2020-03-12 SQL" )
         IF :FieldExists( "PDDATCAN", "JPPEDIDO" ) // 2020-03-15
            :ExecuteCmd( "ALTER TABLE JPPEDIDO DROP COLUMN PDDATCAN" )
         ENDIF
         IF :FieldExists( "PDMOTCAN", "JPPEDIDO" ) // 2020-03-15
            :ExecuteCmd( "ALTER TABLE JPPEDIDO DROP COLUMN PDMOTCAN" )
         ENDIF
         :ExecuteCmd( "DELETE FROM JPITPED WHERE IPPEDIDO IN ( SELECT IDPEDIDO FROM JPPEDIDO WHERE PDSTATUS = 'C' )" )
         :ExecuteCmd( "DELETE FROM JPPEDIDO WHERE PDSTATUS = 'C'" )
      ENDIF
      IF nVersaoDBF < 20200302
         :ExecuteCmd( "ALTER TABLE JPEMANFE CHANGE COLUMN ENEMANFE ENEMANFE VARCHAR(250) NOT NULL DEFAULT ''" )
         :ExecuteCmd( "ALTER TABLE JPEMANFE CHANGE COLUMN IDEMANFE IDEMANFE INT(11) NOT NULL AUTO_INCREMENT" )
         IF :FieldExists( "ESCLIFOR", "JPESTOQUE" )
            :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESCLIFOR ESCADASTRO VARCHAR(6) NOT NULL DEFAULT '000000'" )
         ENDIF
         IF :IndexExists( "IDXITEM", "JPESTOQUE" )
            :ExecuteCmd( "ALTER TABLE JPESTOQUE DROP INDEX IDXITEM" )
         ENDIF
         IF :FieldExists( "ESITEM", "JPESTOQUE" )
            :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESITEM ESPRODUTO VARCHAR(6) NOT NULL DEFAULT '000000'" )
         ENDIF
         IF ! :IndexExists( "IDXPRODUTO", "JPESTOQUE" )
            :ExecuteCmd( "ALTER TABLE JPESTOQUE ADD INDEX IDXPRODUTO ( ESPRODUTO, ESTIPLAN, ESDATLAN, IDESTOQUE )" )
         ENDIF
         IF ! :IndexExists( "IDXPRODUTO", "JPESTOQUE" )
            :ExecuteCmd( "ALTER TABLE JPESTOQUE ADD INDEX IDXPRODUTO ( ESPRODUTO, ESTIPLAN DESC, ESDATLAN, IDESTOQUE )" )
         ENDIF
         :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN IDESTOQUE IDESTOQUE INT(11) NOT NULL AUTO_INCREMENT" )
         IF nVersaoDBF < 20200217
            IF :FieldExists( "ESCLIFOR", "JPESTOQUE" )
               :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESFILIAL ESFILIAL VARCHAR(6) NOT NULL DEFAULT '000000'" )
               :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESTIPLAN ESTIPLAN CHAR(1) NOT NULL DEFAULT '1'" )
               :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESTRANSA ESTRANSA VARCHAR(6) NOT NULL DEFAULT '000000'" )
               :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESPRODUTO ESPRODUTO VARCHAR(6) NOT NULL DEFAULT '000000'" )
               :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESNUMDEP ESNUMDEP CHAR(1) NOT NULL DEFAULT '1'" )
               :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESCCUSTO ESCCUSTO VARCHAR(6) NOT NULL DEFAULT '000000'" )
            ENDIF
         ENDIF
         IF nVersaoDBF < 20200221
            :ExecuteCmd( "UPDATE JPESTOQUE SET ESPEDIDO = 0 WHERE ESPEDIDO = ''" )
            :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESPEDIDO ESPEDIDO INT(11) NOT NULL DEFAULT '0'" )
         ENDIF
         IF :FieldExists( "FSID", "JPFISICA" )
            :ExecuteCmd( "ALTER TABLE JPFISICA CHANGE COLUMN FSID IDFISICA INT(11) NOT NULL AUTO_INCREMENT FIRST," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDFISICA )" )
         ENDIF
         IF :FieldExists( "IDREGISTRO", "JPFISICA" )
            :ExecuteCmd( "ALTER TABLE JPFISICA CHANGE COLUMN IDREGISTRO IDFISICA INT(11) NOT NULL AUTO_INCREMENT FIRST," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDFISICA )" )
         ENDIF
         IF :FieldExists( "IBID", "JPIBPT" )
            :ExecuteCmd( "ALTER TABLE JPIBPT DROP COLUMN IBID, DROP PRIMARY KEY" )
         ENDIF
         IF ! :FieldExists( "IDIBPT", "JPIBPT" )
            :ExecuteCmd( "ALTER TABLE JPIBPT ADD COLUMN IDIBPT INT(11) NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY ( IDIBPT )" )
         ENDIF
         :ExecuteCmd( "ALTER TABLE JPIBPT CHANGE COLUMN IDIBPT IDIBPT INT(11) NOT NULL AUTO_INCREMENT FIRST" )
      ENDIF
      IF nVersaoDbf < 20200302
         IF :IndexExists( "IDXNUMLAN", "JPLICMOV" )
            :ExecuteCmd( "ALTER TABLE JPLICMOV DROP INDEX IDXNUMLAN" )
         ENDIF
         IF :FieldExists( "LCNUMLAN", "JPLICMOV" )
            :ExecuteCmd( "ALTER TABLE JPLICMOV DROP COLUMN LCNUMLAN" )
         ENDIF
         IF :FieldExists( "LCID", "JPLICMOV" )
            :ExecuteCmd( "ALTER TABLE JPLICMOV CHANGE COLUMN LCID IDLICMOV INT(11) NOT NULL AUTO_INCREMENT FIRST," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDLICMOV )" )
         ENDIF
         IF :FieldExists( "IDREGISTRO", "JPLICMOV" )
            :ExecuteCmd( "ALTER TABLE JPLICMOV CHANGE COLUMN IDREGISTRO IDLICMOV INT(11) UNSIGNED NOT NULL AUTO_INCREMENT FIRST," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDLICMOV )" )
         ENDIF
         IF :FieldExists( "NBID", "JPNFBASE" )
            :ExecuteCmd( "ALTER TABLE JPNFBASE CHANGE COLUMN NBID IDNFBASE INT(11) UNSIGNED NOT NULL AUTO_INCREMENT FIRST," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDNFBASE )" )
         ENDIF
         IF :FieldExists( "IDREGISTRO", "JPNFBASE" )
            :ExecuteCmd( "ALTER TABLE JPNFBASE CHANGE COLUMN IDREGISTRO IDNFBASE INT(11) UNSIGNED NOT NULL AUTO_INCREMENT FIRST," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDNFBASE )" )
         ENDIF
         IF :IndexExists( "NOME", "JPNFBASE" )
            :ExecuteCmd( "ALTER TABLE JPNFBASE DROP INDEX NOME" )
         ENDIF
         IF :IndexExists( "ENDERECO", "JPNFBASE" )
            :ExecuteCmd( "ALTER TABLE JPNFBASE DROP INDEX ENDERECO" )
         ENDIF
         IF :IndexExists( "NUMLAN", "JPNFBASE" )
            :ExecuteCmd( "ALTER TABLE JPNFBASE DROP INDEX NUMLAN" )
         ENDIF
         IF :FieldExists( "NBNUMLAN", "JPNFBASE" )
            :ExecuteCmd( "ALTER TABLE JPNFBASE DROP COLUMN NBNUMLAN" )
         ENDIF
         IF :IndexExists( "IDXCADEMI", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS DROP INDEX IDXCADEMI" )
         ENDIF
         IF ! :IndexExists( "IDXPEDIDO", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS ADD INDEX IDXPEDIDO ( NFPEDIDO, IDNOTFIS )" )
         ENDIF
         IF :IndexExists( "NOTA", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS DROP INDEX NOTA" )
         ENDIF
         IF ! :IndexExists( "IDXNOTFIS", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS ADD INDEX IDXNOTFIS ( NFFILIAL, NFNOTFIS )" )
         ENDIF
         IF :FieldExists( "NFCADDES", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS CHANGE COLUMN NFCADDES NFCADASTRO VARCHAR(6) NOT NULL DEFAULT '000000'" )
         ENDIF
         IF :FieldExists( "NFAVENUM", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS DROP COLUMN NFAVENUM" )
         ENDIF
         IF :FieldExists( "NFAVEPRO", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS DROP COLUMN NFAVEPRO" )
         ENDIF
         IF :FieldExists( "NFCTE", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS DROP COLUMN NFCTE" )
         ENDIF
         IF :FieldExists( "NFNFE", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS DROP COLUMN NFNFE" )
         ENDIF
         IF ! :IndexExists( "IDXCADASTRO", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS ADD INDEX IDXCADASTRO ( NFCADASTRO, NFDATEMI, IDNOTFIS )" )
         ENDIF
         IF ! :FieldExists( "NFVALDES", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS ADD COLUMN NFVALDES DOUBLE(14,2) NOT NULL DEFAULT '0'" )
         ENDIF
         IF ! :FieldExists( "NFIIVAL", "JPNOTFIS" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS ADD COLUMN NFIIVAL DOUBLE(14,2) NOT NULL DEFAULT '0'" )
         ENDIF
         IF nVersaoDBF < 20200221
            :ExecuteCmd( "UPDATE JPNOTFIS SET NFPEDIDO = 0 WHERE NFPEDIDO IS NULL OR NFPEDIDO < '0' OR NFPEDIDO > '999999'" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS CHANGE COLUMN NFPEDIDO NFPEDIDO INT(11) NOT NULL DEFAULT '0'" )
         ENDIF
         :ExecuteCmd( "UPDATE JPNOTFIS SET NFLEIS = TRIM( NFLEIS )" )
         :ExecuteCmd( "UPDATE JPNOTFIS SET NFLEIS = TRIM( Left( NFLEIS, LENGTH( NFLEIS ) - 1 ) ) WHERE RIGHT( NFLEIS, 1 ) = ','" )
         IF :FieldExists( "PHID", "JPPREHIS" )
            :ExecuteCmd( "ALTER TABLE JPPREHIS CHANGE COLUMN PHID IDPREHIS INT(11) NOT NULL AUTO_INCREMENT FIRST," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDPREHIS )" )
         ENDIF
         IF :FieldExists( "IDREGISTRO", "JPPREHIS" )
            :ExecuteCmd( "ALTER TABLE JPPREHIS CHANGE COLUMN IDREGISTRO IDPREHIS INT(11) NOT NULL AUTO_INCREMENT FIRST," + ;
               " DROP PRIMARY KEY, ADD PRIMARY KEY ( IDPREHIS )" )
         ENDIF
         IF :FieldExists( "PHCADAS", "JPPREHIS" )
            :ExecuteCmd( "ALTER TABLE JPPREHIS CHANGE COLUMN PHCADAS PHCADASTRO VARCHAR(6) NOT NULL DEFAULT '000000'" )
         ENDIF
         IF :FieldExists( "PHITEM", "JPPREHIS" )
            :ExecuteCmd( "ALTER TABLE JPPREHIS CHANGE COLUMN PHITEM PHPRODUTO VARCHAR(6) NOT NULL DEFAULT '000000'" )
         ENDIF
      ENDIF
      IF nVersaoDBF < 20200302
         IF :FieldExists( "FICLIFOR", "JPFINAN" )
            :ExecuteCmd( "ALTER TABLE JPFINAN CHANGE COLUMN FICLIFOR FICADASTRO VARCHAR(6) NOT NULL DEFAULT '000000'" )
         ENDIF
         IF :IndexExists( "IDXNUMLAN", "JPFINAN" )
            :ExecuteCmd( "ALTER TABLE JPFINAN DROP INDEX IDXNUMLAN" )
         ENDIF
         IF ! :IndexExists( "IDXPEDIDO", "JPFINAN" )
            :ExecuteCmd( "ALTER TABLE JPFINAN ADD INDEX IDXPEDIDO ( FIPEDIDO, IDFINAN )" )
         ENDIF
         IF nVersaoDBF < 20191201
            :ExecuteCmd( "UPDATE JPFINAN SET FIPEDIDO = '0' WHERE FIPEDIDO < '0'" )
            :ExecuteCmd( "ALTER TABLE JPFINAN CHANGE COLUMN FIPEDIDO FIPEDIDO VARCHAR(6) NOT NULL DEFAULT '0'" )
         ENDIF
         IF nVersaoDBF < 20200221
            :ExecuteCmd( "UPDATE JPFINAN SET FIPEDIDO = 0 WHERE FIPEDIDO IS NULL OR FIPEDIDO < '0'" )
            :ExecuteCmd( "ALTER TABLE JPFINAN CHANGE COLUMN FIPEDIDO FIPEDIDO INT(11) NOT NULL DEFAULT '0'" )
         ENDIF
      ENDIF
      IF nVersaoDBF < 20200326
         IF :FieldExists( "FIDATPRE", "JPFINAN" )
            :ExecuteCmd( "ALTER TABLE JPFINAN DROP COLUMN FIDATPRE" )
         ENDIF
         IF :FieldExists( "IPQTDEF", "JPITPED" )
            :ExecuteCmd( "ALTER TABLE JPITPED DROP COLUMN IPQTDEF" )
         ENDIF
         IF :FieldExists( "JPVALTAB", "JPPEDIDO" )
            :ExecuteCmd( "ALTER TABLE JPPEDIDO DROP COLUMN PDVALTAB" )
         ENDIF
      ENDIF
      IF nVersaoDBF < 20200302
         IF :FieldExists( "PDVALCUT", "JPPEDIDO" )
            SayScroll( "Modificando tabela JPPEDIDO" )
            :ExecuteCmd( "ALTER TABLE JPPEDIDO DROP COLUMN PDVALCUT" )
         ENDIF
         IF :FieldExists( "PDREACAO", "JPPEDIDO" )
            :ExecuteCmd( "ALTER TABLE JPPEDIDO DROP COLUMN PDREACAO" )
         ENDIF
         IF :FieldExists( "PDPARCEL", "JPPEDIDO" )
            :ExecuteCmd( "ALTER TABLE JPPEDIDO DROP COLUMN PDPARCEL" )
         ENDIF
         IF :FieldExists( "PDDOLAR", "JPPEDIDO" )
            :ExecuteCmd( "ALTER TABLE JPPEDIDO DROP COLUMN PDDOLAR" )
         ENDIF
         IF nVersaoDBF < 20200222
            :ExecuteCmd( "UPDATE JPPEDIDO SET PDPEDREL = 0 WHERE PDPEDREL= ''" )
            :ExecuteCmd( "ALTER TABLE JPPEDIDO CHANGE COLUMN PDPEDREL PDPEDREL INT(11) NOT NULL DEFAULT '0'" )
            IF ! :IndexExists( "IDXPEDREL", "JPPEDIDO" )
               :ExecuteCmd( "ALTER TABLE JPPEDIDO ADD INDEX IDXPEDREL ( PDPEDREL )" )
            ENDIF
         ENDIF
         :ExecuteCmd( "UPDATE JPPEDIDO SET PDLEIS = TRIM( PDLEIS )" )
         :ExecuteCmd( "UPDATE JPPEDIDO SET PDLEIS = TRIM( Left( PDLEIS, LENGTH( PDLEIS ) - 1 ) ) WHERE RIGHT( PDLEIS, 1 ) = ','" )
         IF :FieldExists( "PDCLIFOR", "JPPEDIDO" )
            :ExecuteCmd( "ALTER TABLE JPPEDIDO CHANGE COLUMN PDCLIFOR PDCADASTRO VARCHAR(6) NOT NULL DEFAULT '000000'" )
         ENDIF
      ENDIF
      IF nVersaoDBF < 20200315
         :ExecuteCmd( "ALTER TABLE JPCIDADE CHANGE COLUMN IDCIDADE IDCIDADE INT(11) NOT NULL AUTO_INCREMENT" )
      ENDIF
   ENDWITH

   RETURN NIL

STATIC FUNCTION Update04SQL( nVersaoDBF )

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

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   SayScroll( "2020-04 SQL" )
   WITH OBJECT cnSQL
      IF nVersaoDBF < 20200408
         SayScroll( "2020-04-08 SQL" )
         :ExecuteCmd( "UPDATE JPESTOQUE SET ESCADASTRO = '0'  WHERE ESCADASTRO IS NULL OR ESCADASTRO < '0' OR ESCADASTRO > '999999'" )
         :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESCADASTRO ESCADASTRO INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "UPDATE JPESTOQUE SET ESFILIAL = '0' WHERE ESFILIAL IS NULL OR ESFILIAL < '0' OR ESFILIAL > '999999'" )
         :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESFILIAL ESFILIAL INT(11) NOT NULL DEFAULT '0'"  )
         :ExecuteCmd( "UPDATE JPESTOQUE SET ESPRODUTO = '0' WHERE ESPRODUTO IS NULL OR ESPRODUTO < '0' OR ESPRODUTO > '999999'" )
         :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESPRODUTO ESPRODUTO INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "UPDATE JPESTOQUE SET ESTRANSA = '0' WHERE ESTRANSA IS NULL OR ESTRANSA < '0' OR ESTRANSA > '999999'" )
         :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESTRANSA ESTRANSA INT(11) NOT NULL DEFAULT '0'" )
      ENDIF
      IF nVersaoDbf < 20200427
         SayScroll( "2020-04-27 SQL" )
         :ExecuteCmd( "UPDATE JPCOMISSAO SET CMVENDEDOR = '000000' WHERE CMVENDEDOR IS NULL OR CMVENDEDOR = ''" )
         :ExecuteCmd( "UPDATE JPCOMISSAO SET CMPRODEP = '000000' WHERE CMPRODEP IS NULL OR CMPRODEP = ''" )
         :ExecuteCmd( "ALTER TABLE JPCOMISSAO" + ;
            " CHANGE CMVENDEDOR CMVENDEDOR INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE CMPRODEP CMPRODEP INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "UPDATE JPESTOQUE SET ESCCUSTO = '000000' WHERE ESCCUSTO IS NULL OR ESCCUSTO <  '0' OR ESCCUSTO > '999999'"  )
         :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN ESCCUSTO ESCCUSTO INT(11) NOT NULL DEFAULT '0'"  )
      ENDIF
      IF nVersaoDBF < 20200423
         SayScroll( "2020.04.23 Regras Fiscais numéricas" )
         :ExecuteCmd( "UPDATE JPIMPOSTO SET IMTRANSA = '0' WHERE IMTRANSA IS NULL OR IMTRANSA < '0' OR IMTRANSA > '999999'" )
         :ExecuteCmd( "UPDATE JPIMPOSTO SET IMTRIUF = '0' WHERE IMTRIUF IS NULL OR IMTRIUF < '0' OR IMTRIUF > '999999'" )
         :ExecuteCmd( "UPDATE JPIMPOSTO SET IMTRICAD = '0' WHERE IMTRICAD IS NULL OR IMTRICAD < '0' OR IMTRICAD > '999999'" )
         :ExecuteCmd( "UPDATE JPIMPOSTO SET IMTRIPRO = '0' WHERE IMTRIPRO IS NULL OR IMTRIPRO < '0' OR IMTRIPRO > '999999'" )
         :ExecuteCmd( "ALTER TABLE JPIMPOSTO " + ;
            " CHANGE COLUMN IMTRANSA IMTRANSA INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN IMTRIUF  IMTRIUF INT(11)  NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN IMTRICAD IMTRICAD INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN IMTRIPRO IMTRIPRO INT(11) NOT NULL DEFAULT '0'" )
      ENDIF
      IF nVersaoDBF < 20200408
         SayScroll( "2020.04.08 Atualizando JPFINAN.SQL pra numérico" )
         IF AppEmpresaApelido() == "MARINGA"
            :ExecuteCmd( "DELETE FROM JPFINAN WHERE FIVALOR=0 OR FIDATEMI IS NULL" ) // LIXO MARINGA
         ENDIF
         :ExecuteCmd( "UPDATE JPFINAN SET FIFILIAL='1' WHERE FIFILIAL IS NULL OR FIFILIAL < '0' OR FIFILIAL > '999999'" )
         :ExecuteCmd( "UPDATE JPFINAN SET FICADASTRO = '0' WHERE FICADASTRO IS NULL OR FICADASTRO < '0' OR FICADASTRO > '999999'" )
         :ExecuteCmd( "UPDATE JPFINAN SET FISACADO = '0' WHERE FISACADO IS NULL OR FISACADO < '0' OR FISACADO > '999999'" )
         :ExecuteCmd( "UPDATE JPFINAN SET FICCUSTO = '0' WHERE FICCUSTO IS NULL OR FICCUSTO < '0' OR FICCUSTO > '999999'" )
         :ExecuteCmd( "UPDATE JPFINAN SET FIOPERACAO = '0' WHERE FIOPERACAO IS NULL OR FIOPERACAO < '0' OR FIOPERACAO > '999999'" )
         :ExecuteCmd( "UPDATE JPFINAN SET FIPORTADOR = '0' WHERE FIPORTADOR IS NULL OR FIPORTADOR < '0' OR FIPORTADOR > '999999'" )
         :ExecuteCmd( "UPDATE JPFINAN SET FIVENDEDOR = '0' WHERE FIVENDEDOR IS NULL OR FIVENDEDOR < '0' OR FIVENDEDOR > '999999'" )
         :ExecuteCmd( "ALTER TABLE JPFINAN " + ;
            "CHANGE COLUMN FIFILIAL FIFILIAL INT(11) NOT NULL DEFAULT '0'," + ;
            "CHANGE COLUMN FICADASTRO FICADASTRO INT(11) NOT NULL DEFAULT '0', " + ;
            "CHANGE COLUMN FISACADO FISACADO INT(11) NOT NULL DEFAULT '0'," + ;
            "CHANGE COLUMN FICCUSTO FICCUSTO INT(11) NOT NULL DEFAULT '0'," + ;
            "CHANGE COLUMN FIOPERACAO FIOPERACAO INT(11) NOT NULL DEFAULT '0'," + ;
            "CHANGE COLUMN FIPORTADOR FIPORTADOR INT(11) NOT NULL DEFAULT '0'," + ;
            "CHANGE COLUMN FIVENDEDOR FIVENDEDOR INT(11) NOT NULL DEFAULT '0'" )
      ENDIF
      IF nVersaoDBF < 20200425
         SayScroll( "2020.04.25 Num.Bancário jpfinan.SQL" )
         :ExecuteCmd( "UPDATE JPFINAN SET FINUMBAN = '000000' WHERE Year( FIDATVEN  ) < 2020" )
      ENDIF
      IF nVersaoDBF < 20200406
         IF :FieldExists( "CDSITFAZ", "JPCADASTRO" )
            :ExecuteCmd( "ALTER TABLE JPCADASTRO DROP COLUMN CDSITFAZ" )
         ENDIF
         IF :FieldExists( "CDSITNFE", "JPCADASTRO" )
            :ExecuteCmd( "ALTER TABLE JPCADASTRO DROP COLUMN CDSITNFE" )
         ENDIF
      ENDIF
      IF nVersaoDBF < 20200427
         :ExecuteCmd( "UPDATE JPCADASTRO SET CDVENDEDOR = '000000' WHERE CDPORTADOR IS NULL OR CDVENDEDOR < '0' OR CDVENDEDOR > '999999'" )
         :ExecuteCmd( "UPDATE JPCADASTRO SET CDPORTADOR = '000000' WHERE CDVENDEDOR IS NULL OR CDPORTADOR < '0' OR CDPORTADOR > '999999'" )
         :ExecuteCmd( "UPDATE JPCADASTRO SET CDTRANSP = '000000' WHERE CDTRANSP IS NULL OR CDTRANSP < '0' OR CDTRANSP > '999999'" )
         :ExecuteCmd( "UPDATE JPCADASTRO SET CDTRICAD = '000000' WHERE CDTRICAD IS NULL OR CDTRICAD < '0' OR CDTRICAD > '999999'" )
         :ExecuteCmd( "UPDATE JPCADASTRO SET CDSTATUS = '000000' WHERE CDSTATUS IS NULL OR CDSTATUS < '0' OR CDSTATUS > '999999'" )
         :ExecuteCmd( "ALTER TABLE JPCADASTRO" + ;
            " CHANGE COLUMN CDVENDEDOR CDVENDEDOR INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN CDPORTADOR CDPORTADOR INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN CDTRANSP CDTRANSP INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN CDTRICAD CDTRICAD INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN CDSTATUS CDSTATUS INT(11) NOT NULL DEFAULT '0'" )
      ENDIF
      IF nVersaoDbf < 20200427
         :ExecuteCmd( "UPDATE JPITEM SET IEPRODEP = '000000' WHERE IEPRODEP IS NULL OR IEPRODEP < '0' OR IEPRODEP > '999999'" )
         :ExecuteCmd( "UPDATE JPITEM SET IEPROSEC = '000000' WHERE IEPROSEC IS NULL OR IEPROSEC < '0' OR IEPROSEC > '999999'" )
         :ExecuteCmd( "UPDATE JPITEM SET IEPROGRU = '000000' WHERE IEPROGRU IS NULL OR IEPROGRU < '0' OR IEPROGRU > '999999'" )
         :ExecuteCmd( "UPDATE JPITEM SET IEPROLOC = '000000' WHERE IEPROLOC IS NULL OR IEPROLOC < '0' OR IEPROLOC > '999999'" )
         :ExecuteCmd( "ALTER TABLE JPITEM" + ;
           " CHANGE IEPRODEP IEPRODEP INT(11) NOT NULL DEFAULT '0'," + ;
           " CHANGE IEPROSEC IEPROSEC INT(11) NOT NULL DEFAULT '0'," + ;
           " CHANGE IEPROGRU IEPROGRU INT(11) NOT NULL DEFAULT '0'," + ;
           " CHANGE IEPROLOC IEPROLOC INT(11) NOT NULL DEFAULT '0'" )
      ENDIF
   ENDWITH

   RETURN NIL

STATIC FUNCTION Update07SQL( nVersaoDBF )

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

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   WITH OBJECT cnSQL
      IF nVersaoDBF < 20200716
         IF ! :FieldExists( "PHREAJUSTE", "JPPREHIS" )
            :ExecuteCmd( "ALTER TABLE JPPREHIS ADD COLUMN PHREAJUSTE VARCHAR(1) NOT NULL DEFAULT ''" )
         ENDIF
         :ExecuteCmd( "DELETE FROM JPPREHIS WHERE PHCADASTRO IS NULL OR PHCADASTRO = 0 OR" + ;
            " PHPRODUTO IS NULL OR PHPRODUTO = 0 OR PHFORPAG IS NULL OR PHFORPAG = 0" )
      ENDIF
      IF nVersaoDBF < 20200728
         SayScroll( "2020.07.28 Docto/Parcela não zero JPFINAN.SQL" )
         :ExecuteCmd( "UPDATE JPFINAN SET FIPARCELA = '001' WHERE FIPARCELA < '001'" )
         :ExecuteCmd( "UPDATE JPFINAN SET FINUMDOC = '000000001' WHERE FINUMDOC < '000000001'" )
         :ExecuteCmd( "UPDATE JPFINAN SET FINUMBAN = '0' WHERE FINUMBAN = ''" )
         :ExecuteCmd( "ALTER TABLE JPFINAN" + ;
            " CHANGE COLUMN FIPARCELA FIPARCELA INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN FINUMDOC FINUMDOC INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN FINUMBAN FINUMBAN INT(11) NOT NULL DEFAULT '0'" )
      ENDIF
      IF nVersaoDBF < 20200716
         IF ! :FieldExists( "PCDATA", "JPPRECO" )
            :ExecuteCmd( "ALTER TABLE JPPRECO ADD COLUMN PCDATA DATE NULL" )
         ENDIF
         IF ! :FieldExists( "PCHORA", "JPPRECO" )
            :ExecuteCmd( "ALTER TABLE JPPRECO ADD COLUMN PCHORA VARCHAR(8) NOT NULL DEFAULT ''" )
         ENDIF
         :ExecuteCmd( "DELETE FROM JPPRECO WHERE PCCADASTRO IS NULL OR PCCADASTRO = 0 OR " + ;
            " PCPRODUTO IS NULL OR PCPRODUTO = 0 OR PCFORPAG IS NULL OR PCFORPAG = 0" )
      ENDIF
   ENDWITH

   RETURN NIL

STATIC FUNCTION Update0705()

   SayScroll( "2020-07-05 - Nome de rotina" )
   IF ! AbreArquivos( "jpsenha" )
      QUIT
   ENDIF
   pw_AddModule( "PJPPEDIDO",       "P0600PED" )
   pw_AddModule( "PJPESTOQUE",      "PESTOLANCA1" )
   pw_AddModule( "PJPESTOQUEE",     "PESTOLANCA2" )
   pw_AddModule( "PJPPEDIDOCTE",    "ADMPEDCTE" )
   pw_AddModule( "PJPPEDIDONFE",    "ADMPEDNOT" )
   pw_AddModule( "PJPPEDIDOFATURA", "ADMPEDFAT" )
   pw_AddModule( "PJPPEDIDOCUPOM",  "ADMPEDCUP" )
   pw_AddModule( "PJPMDFCAB",       "PJPMF" )
   pw_AddModule( "PJPPEDIDONOTA",   "P0600NOTA" )
   pw_AddModule( "PJPMDFCAB",       "PJPMDF" )
   CLOSE DATABASES

   RETURN NIL

STATIC FUNCTION Update0707()

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   SayScroll( "2020-07-06" )
   SayScroll( "Salvando SQL.JPBANCARIO" )
   VerificaNumeracao( "JPBANCARIO", "IDBANCARIO" )
   CopyDbfToSQL( "JPBANCARIO", .T., .F., .T. )
   SayScroll( "Salvando SQL.JPBACCUSTO" )
   VerificaNumeracao( "JPBACCUSTO", "IDBACCUSTO" )
   CopyDBFToSQL( "JPBACCUSTO", .T., .F., .T. )
   SayScroll( "Salvando SQL.JPBAAUTO" )
   VerificaNumeracao( "JPBAAUTO", "IDBAAUTO" )
   CopyDBFToSQL( "JPBAAUTO", .T., .F., .T. )

   RETURN NIL

STATIC FUNCTION Update0713()

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   SayScroll( "2020-07-13 Salvando SQL.JPPRECO" )
   CopyDBFToSQL( "JPPRECO", .T., .F., .T. )

   RETURN NIL

STATIC FUNCTION Update0727B()

   SayScroll( "2020-07-27 Update JPFISCAL.DBF" )
   IF ! UseSoDBF( "jpfiscal", .T. )
      QUIT
   ENDIF
   DO WHILE ! Eof()
      RecLock()
      REPLACE ;
         jpfiscal->lfPedido WITH StrZero( Val( jpfiscal->lfPedido ), 6 ), ;
         jpfiscal->lfFilial WITH StrZero( Val( jpfiscal->lfFilial ), 6 ), ;
         jpfiscal->lfDocIni WITH StrZero( Val( jpfiscal->lfDocIni ), 9 ), ;
         jpfiscal->lfDocFim WITH StrZero( Val( jpfiscal->lfDocFim ), 9 ), ;
         jpfiscal->lfCadastro WITH StrZero( Val( jpfiscal->lfCadastro ), 6 ), ;
         jpfiscal->lfModFis WITH StrZero( Val( jpfiscal->lfModFis ), 2 ), ;
         jpfiscal->lfCCusto WITH StrZero( Val( jpfiscal->lfCCusto ), 6 )
      SKIP
   ENDDO
   CLOSE DATABASES
   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   SayScroll( "Salvando SQL.JPFISCAL" )
   VerificaNumeracao( "jpfiscal", "IDFISCAL", "lfObs" )
   CopyDbfToSQL( "JPFISCAL", .T., .F., .T. )

   RETURN NIL

STATIC FUNCTION Update08SQL( nVersaoDBF )

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

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   SayScroll( "2020-08 SQL" )
   WITH OBJECT cnSQL
      IF nVersaoDBF < 20200801
         SayScroll( "2020-08-01 SQL" )
         :ExecuteCmd( "ALTER TABLE JPAGENDA CHANGE COLUMN IDAGENDA IDAGENDA INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPAGE CHANGE COLUMN IDANPAGE IDANPAGE INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPATI CHANGE COLUMN IDANPATI IDANPATI INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPINS CHANGE COLUMN IDANPINS IDANPINS INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPLOC CHANGE COLUMN IDANPLOC IDANPLOC INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPOPE CHANGE COLUMN IDANPOPE IDANPOPE INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPANPPRO CHANGE COLUMN IDANPPRO IDANPPRO INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPCLISTA CHANGE COLUMN IDCLISTA IDCLISTA INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPCOMBUSTIVEL CHANGE COLUMN IDCOMBUSTIVEL IDCOMBUSTIVEL INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPCOMISSAO CHANGE COLUMN IDCOMISSAO IDCOMISSAO INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPDECRETO CHANGE COLUMN IDDECRETO IDDECRETO INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPEDICFG CHANGE COLUMN IDEDICFG IDEDICFG INT(11) NOT NULL AUTO_INCREMENT" )
      ENDIF
      IF nVersaoDBF < 20200801
         :ExecuteCmd( "ALTER TABLE JPEMANFE CHANGE COLUMN IDEMANFE IDEMANFE INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "UPDATE JPESTOQUE SET ESPEDIDO = 0 WHERE ESPEDIDO=''" )
         :ExecuteCmd( "ALTER TABLE JPESTOQUE CHANGE COLUMN IDESTOQUE IDESTOQUE INT(11) NOT NULL AUTO_INCREMENT," + ;
            "CHANGE COLUMN ESPEDIDO ESPEDIDO INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "ALTER TABLE JPFISICA CHANGE COLUMN IDFISICA IDFISICA INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPIBPT CHANGE COLUMN IDIBPT IDIBPT INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPMOTORI CHANGE COLUMN IDMOTORI IDMOTORI INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPFORPAG" + ;
            " CHANGE COLUMN IDFORPAG IDFORPAG INT(11) NOT NULL AUTO_INCREMENT," + ;
            " CHANGE COLUMN FPDE1 FPDE1 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPATE1 FPATE1 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTMES1 FPQTMES1 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTDIA1 FPQTDIA1  INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDIAFIM1 FPDIAFIM1 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDE2 FPDE2 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPATE2 FPATE2 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTMES2 FPQTMES2 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTDIA2 FPQTDIA2 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDIAFIM2 FPDIAFIM2 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDE3 FPDE3 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPATE3 FPATE3 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTMES3 FPQTMES3 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTDIA3 FPQTDIA3 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDIAFIM3 FPDIAFIM3 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDE4 FPDE4 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPATE4 FPATE4 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTMES4 FPQTMES4 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTDIA4 FPQTDIA4 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDIAFIM4 FPDIAFIM4 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDE5 FPDE5 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPATE5 FPATE5 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTMES5 FPQTMES5 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPQTDIA5 FPQTDIA5 INT(3) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN FPDIAFIM5 FPDIAFIM5 INT(3) NOT NULL DEFAULT '0'" )
      ENDIF
      IF nVersaoDBF < 20200801
         IF :FieldExists( "NFCADTRA", "JPNOTFIS" )
            :ExecuteCmd( "UPDATE JPNOTFIS SET NFCADTRA = '0' WHERE NFCADTRA = ''" )
            :ExecuteCmd( "ALTER TABLE JPNOTFIS CHANGE COLUMN NFCADTRA NFTRANSP INT(11) NOT NULL DEFAULT '0'" )
         ENDIF
         IF ! :FieldExists( "KKMANIF", "JPNFEKEY" )
            :ExecuteCmd( "ALTER TABLE JPNFEKEY ADD COLUMN KKMANIF CHAR(1) NOT NULL DEFAULT 'N'" )
            :ExecuteCmd( "UPDATE JPNFEKEY SET KKMANIF = 'S' WHERE KKDATEMI < '2020-03-01'" )
         ENDIF
         :ExecuteCmd( "ALTER TABLE JPIMPOSTO CHANGE COLUMN IDIMPOSTO IDIMPOSTO INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPLICMOV CHANGE COLUMN IDLICMOV IDLICMOV INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPNFBASE CHANGE COLUMN IDNFBASE IDNFBASE INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPNOTFIS" + ;
            " CHANGE COLUMN IDNOTFIS IDNOTFIS INT(11) NOT NULL AUTO_INCREMENT," + ;
            " CHANGE COLUMN NFPEDIDO NFPEDIDO INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN NFQTDVOL NFQTDVOL INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN NFTRANSP NFTRANSP INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "ALTER TABLE JPPREHIS CHANGE COLUMN IDPREHIS IDPREHIS INT(11) NOT NULL AUTO_INCREMENT" )
      ENDIF
      IF nVersaoDBF < 20200801
         :ExecuteCmd( "ALTER TABLE JPFINAN CHANGE COLUMN FIPEDIDO FIPEDIDO INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "ALTER TABLE JPTRANSA CHANGE COLUMN IDTRANSA IDTRANSA INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPVEICULO" + ;
            " CHANGE COLUMN IDVEICULO IDVEICULO INT(11) NOT NULL AUTO_INCREMENT, " + ;
            " CHANGE COLUMN VEPESO VEPESO INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPACTOT VECAPACTOT INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC1 VECAPAC1 INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC2 VECAPAC2 INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC3 VECAPAC3 INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC4 VECAPAC4 INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC5 VECAPAC5 INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC6 VECAPAC6 INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC7 VECAPAC7 INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC8 VECAPAC8 INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN VECAPAC9 VECAPAC9 INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "ALTER TABLE JPVENDEDOR CHANGE COLUMN IDVENDEDOR IDVENDEDOR INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPFINAN" + ;
            " CHANGE COLUMN IDFINAN IDFINAN INT(11) NOT NULL AUTO_INCREMENT," + ;
            " CHANGE COLUMN FIPEDIDO FIPEDIDO INT(11) NOT NULL DEFAULT '0' " )
         :ExecuteCmd( "ALTER TABLE JPITPED" + ;
            " CHANGE COLUMN IDITPED IDITPED    INT(11) NOT NULL AUTO_INCREMENT, " + ;
            " CHANGE COLUMN IPPEDIDO IPPEDIDO INT(11) NOT NULL DEFAULT '0'," + ;
            " CHANGE COLUMN IPGARANTIA IPGARANTIA INT(11) NOT NULL DEFAULT '0'" )
      ENDIF
      IF nVersaoDBF < 20200801
         :ExecuteCmd( "ALTER TABLE JPCADASTRO CHANGE COLUMN IDCADASTRO IDCADASTRO INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPTRANSP CHANGE COLUMN IDTRANSP IDTRANSP   INT(11) NOT NULL AUTO_INCREMENT" )
      ENDIF
      IF nVersaoDBF < 20200801
         IF :FieldExists( "JPVALTAB", "JPPEDIDO" )
            :ExecuteCmd( "ALTER TABLE JPPEDIDO DROP COLUMN PDVALTAB" )
         ENDIF
         :ExecuteCmd( "UPDATE JPPEDIDO SET PDPEDREL = 0 WHERE PDPEDREL=''" )
         :ExecuteCmd( "ALTER TABLE JPPEDIDO CHANGE COLUMN PDPEDREL PDPEDREL INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "ALTER TABLE JPITEM CHANGE COLUMN IDPRODUTO IDPRODUTO INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPITEM" + ;
            " CHANGE COLUMN IDPRODUTO IDPRODUTO  INT(11) NOT NULL AUTO_INCREMENT," + ;
            " CHANGE COLUMN IEGTINQTD IEGTINQTD  INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN IEGARCOM IEGARCOM   INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN IEGARVEN IEGARVEN   INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN IEALTURA IEALTURA   INT(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN IELARGURA IELARGURA  Int(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN IEPROFUND IEPROFUND  Int(11) NOT NULL DEFAULT '0', " + ;
            " CHANGE COLUMN IEQTDCOM IEQTDCOM   INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "ALTER TABLE JPPEDIDO CHANGE COLUMN IDPEDIDO IDPEDIDO   INT(11) NOT NULL AUTO_INCREMENT" )
      ENDIF
      IF nVersaoDBF < 20200801
         :ExecuteCmd( "ALTER TABLE JPCIDADE CHANGE COLUMN IDCIDADE IDCIDADE INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPFISCAL" + ;
            " CHANGE COLUMN IDFISCAL IDFISCAL INT(11) NOT NULL AUTO_INCREMENT," + ;
            " CHANGE COLUMN LFPEDIDO LFPEDIDO INT(11) NOT NULL DEFAULT '0'" )
         :ExecuteCmd( "ALTER TABLE JPPRECO CHANGE COLUMN IDPRECO IDPRECO    INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPMDFCAB CHANGE COLUMN IDMDFCAB IDMDFCAB INT(11) NOT NULL AUTO_INCREMENT" )
         :ExecuteCmd( "ALTER TABLE JPMDFDET" + ;
            " CHANGE COLUMN IDMDFDET IDMDFDET INT(11) NOT NULL AUTO_INCREMENT," + ;
            " CHANGE COLUMN MDPESO MDPESO INT(11) NOT NULL DEFAULT '0'" )
      ENDIF
      IF nVersaoDBF < 20200804
         :ExecuteCmd( "ALTER TABLE JPBANCARIO CHANGE COLUMN BAHIST BAHIST VARCHAR(50) NOT NULL DEFAULT ''" )
      ENDIF
   ENDWITH

   RETURN NIL


Tem muito comando SQL nesse fonte.
Por isso apagando coisa antiga, porque começa a ser arriscado deixar essas mudanças no fonte, por causa de atrasadinhos.
Atualizar só UM cliente atrasado nesta semana, pra apagar tudo anterior a JULHO.

Pois é... a tranferência/uso foi só mais uma entre várias etapas.

Agora começa a fase: o que mais o MySQL pode fazer, que o DBF não podia...
É, por exemplo: juntar registros com linhas separadas de observações, porque podem ficar todas juntas no MySQL.
Alterar isso antes, complicaria pra manter compatibilidade com estrutura de DBFs pra transferir.
Uma vez encerrada a transferência em todos os clientes, acabou a necessidade de manter compatibilidade.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 11 Ago 2020 12:31

Ainda rodeando a contabilidade.
Primeiro preparando, tirando o atraso de atualizações.
A primeira coisa: trocando nome de arquivo, nome de campos, e até tipo de campo, bem diferente das conversões anteriores.

Esse é o módulo que eu menos atualizava.
Apenas aproveitando a situação, dar uma geral no aplicativo em DBF, deixando preparado pra depois transferir pra MySQL.

STATIC FUNCTION Update0807( nVersaoDBF )

   JPCTHISTOCreateDbf( nVersaoDBF )

   RETURN NIL

STATIC FUNCTION JPCTHISTOCreateDbf( nVersaoDBF )

   LOCAL aStruList := { ;
     { "IDCTHISTO", "N", 6 }, ;
     { "CHCODIGO", "N", 7 }, ;
     { "CHDESCRI", "C", 250 }, ;
     { "CHINFINC", "C", 80 }, ;
     { "CHINFALT", "C", 80 } }

   IF nVersaoDBF < 20200807
      AAdd( aStruList, { "HIHISPAD", "C", 6 } )
      AAdd( aStruList, { "HIDESCRI", "C", 250 } )
      AAdd( aStruList, { "HIINFINC", "C", 80 } )
      AAdd( aStruList, { "HIINFALT", "C", 80 } )
   ENDIF

   SayScroll( "JPCTHISTO.DBF, verificando atualizações" )

   IF ! ValidaStru( "jpcthisto", aStruList )
      MsgStop( "JPCTHISTO não disponível!" )
      QUIT
   ENDIF
   CLOSE DATABASES
   IF nVersaoDBF >= 20200807
      RETURN NIL
   ENDIF
   IF File( "cthisto.dbf" )
      IF ! ValidaStru( "cthisto", aStruList )
         MsgStop( "CTHISTO não disponível" )
         QUIT
      ENDIF
      IF ! UseSoDbf( "jpcthisto", .T. )
         QUIT
      ENDIF
      IF ! UseSoDbf( "cthisto", .T. )
         QUIT
      ENDIF
      SELECT cthisto
      GOTO TOP
      DO WHILE ! Eof()
         SELECT jpcthisto
         RecAppend()
         REPLACE ;
            jpcthisto->idctHisto WITH Int( Val( cthisto->hiHisPad ) / 10 ), ;
            jpcthisto->chCodigo  WITH Val( cthisto->hiHisPad ), ;
            jpcthisto->chDescri  WITH cthisto->hiDescri, ;
            jpcthisto->chInfInc  WITH cthisto->hiInfInc, ;
            jpcthisto->chInfAlt  WITH cthisto->hiInfAlt
         SELECT cthisto
         RecLock()
         DELETE
         RecUnlock()
         SKIP
      ENDDO
      CLOSE DATABASES
      fErase( "cthisto.dbf" )
   ENDIF
   IF ! UseSoDbf( "jpcthisto", .T. )
      RETURN NIL
   ENDIF
   DO WHILE ! Eof()
      RecLock()
      IF Empty( jpcthisto->idCtHisto )
         REPLACE jpcthisto->idctHisto WITH Int( jpcthisto->chCodigo / 10 )
      ENDIF
      IF Empty( jpcthisto->chCodigo )
         REPLACE jpcthisto->chCodigo WITH Val( jpcthisto->hiHisPad )
      ENDIF
      IF Empty( jpcthisto->chDescri )
         REPLACE jpcthisto->chDescri WITH jpcthisto->hiDescri
      ENDIF
      IF Empty( jpcthisto->chInfInc )
         REPLACE jpcthisto->chInfInc WITH jpcthisto->hiInfInc
      ENDIF
      IF Empty( jpcthisto->chInfAlt )
         REPLACE jpcthisto->chInfAlt WITH jpcthisto->hiInfAlt
      ENDIF
      IF jpcthisto->idctHisto == 0
         DELETE
      ENDIF
      SKIP
   ENDDO
   CLOSE DATABASES

   RETURN JPCTHISTOCreateDBF( 20200807 )


Pensando em aproveitar o incremental do MySQL, e gravar um código alternativo com o incremental + dígito de controle
Com certeza isso vai exigir a chave primária no incremental e mais um índice secundário pelo código com dígito de controle, mas tudo bem.
Pois é... por enquanto atualizar o DBF, mas pensando no que vai ser bom para o MySQL depois.

Por enquanto, na minha máquina, essa conversão roda toda vez que entro no aplicativo.
É que é fase de testes, confirmando o comportamento das mudanças do aplicativo, e pensando se altero algo mais.

Seria péssimo mudar de idéia com isso já instalado no cliente, porque complicaria conversões de conversões...
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 12 Ago 2020 23:15

Só pra constar:

Agora só mexendo com contabilidade, ainda em DBF.

Todo restante funcionando em MySQL sem nenhum problema.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 14 Ago 2020 17:05

Voltei à situação de 07/08, parece.... parece que só perdi toda conversão da contabilidade.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 16 Ago 2020 14:00

Estou revisando minha atualização de arquivos.
Acho que no passar dos anos, piorei ao invés de melhorar.

O que acontece: temos que considerar 4 situações

Situação 1:
Quando temos campos novos, precisamos dos campos novos e dos antigos ao mesmo tempo
Ok com conversão de arquivo por vez

Situação 2:
Terminada conversão, não precisa mais dos campos antigos, precisamos eliminar os antigos
Ok com conversão de um arquivo por vez

Situação 3:
A conversão pode incluir transferência pra MySQL, neste caso, precisamos eliminar os antigos ANTES de terminar toda conversão
Ok com conversão de um arquivo por vez

Situação 4:
Justamente isso tudo junto, que pode significar parcialmente convertido
Deu algum problema, e precisa recomeçar... lá vém problemas, porque não tem mais o que tinha antes em cada arquivo, só vai ter pra onde parou.

O que eu fazia antes:

Quando era só DBF... eu rodava tudo duas vezes: uma acrescentando em tudo, e depois outra removendo em tudo
Normal... se correu tudo bem com a adição, a remoção não é problema.

Mas... entrou o SQL.
A transferência do MySQL precisa do DBF pronto.
Acabei alterando pra fazer um DBF por vez, tudo que tiver que fazer.

Mas isso tem um risco: se der problema na conversão.... ferrou... porque não tem mais a situação anterior.
Ok, tem o backup, mas para o usuário complica, além do que, se a conversão tem problema, só retornar o backup não resolve.

Os DBFs estão acabando, mas... o contabil vai precisar de conversão ativa por alguns anos.... então vou repensar.

Por enquanto, uma coisa que pensei foi salvar a situação atual de conversão.
E como salvar a conversão parcial?
Se eu tiver as conversões por data.... salvaria a data como sendo data atual.

Exemplo:

Versão atual 2020-08-16, versão dos DBFs 2019-01-01

Ao rodar uma conversão de 2019-02-01, gravaria como versão 2019-02-01
Se der problema ao carregar o EXE, as versões anteriores a 2019-02-01 já não seriam feitas.
Normal, já teriam sido feitas antes, bastaria converter a partir daí.

O lado ruim é que obrigatoriamente iria fazer as conversões na ordem definida.
Às vezes, com o tempo, mais rápido fazer várias de uma vez do que uma de cada vez.
Exemplo: 10 atualizações adicionando e removendo campo. Mais rápido acrescentar todos e remover todos no final, pra fazer logo tudo de uma vez.

Mas... DBF tá acabando? tá sim, mas MySQL também vai precisar, e o contábil vai precisar disso por tempo indeterminado.
Ainda pensando na idéia.
Senão... é recorrer ao backup, tudo bem, o aplicativo obrigatoriamente faz backup.

Agora lembrei porque uso versão de DBF, além da versão de EXE.
É que ao trocar versão de DBF obrigatoriamente faço backup.
Não dá pra fazer isso ao trocar versão de EXE, porque EXE posso trocar várias vezes, sem mexer nos DBFs, e obrigar backup na na troca de EXE seria muita perda de tempo.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

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

Meu modo de trabalho

Mensagempor JoséQuintas » 16 Ago 2020 14:18

JoséQuintas escreveu:Agora lembrei porque uso versão de DBF, além da versão de EXE.
É que ao trocar versão de DBF obrigatoriamente faço backup.
Não dá pra fazer isso ao trocar versão de EXE, porque EXE posso trocar várias vezes, sem mexer nos DBFs, e obrigar backup na na troca de EXE seria muita perda de tempo.


Ao postar isso me veio outra idéia:
Porque salvar versão de DBF?
Basta a versão do EXE mesmo.

Quem vai precisar estruturas novas é o EXE, pronto, resolvido sobre atualizar.

E o backup?
IF AppVersaoEXEAnt() < '2020.08.16.1437' // versão que mudou estrutura

Só preciso ter no EXE a data em que ocorreu mudança de estrutura, pra forçar o backup.
No cliente, é só manter salva a data do último EXE usado.
Legal, isso pode servir até pra obrigar a atualizar o EXE, coisa que vou acabar precisando fazer, no caso de MySQL remoto.

Pensar mais sobre isso.

Nota: Isso tem a ver com atualização, mas não resolve a questão anterior, apenas elimina a necessidade de salvar um campo a mais.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 14276
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 859 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 2 visitantes


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