Página 9 de 35

Meu modo de trabalho

Enviado: 19 Out 2019 09:52
por JoséQuintas
Costumo usar o nome do arquivo como parte do nome do módulo.
Como transportadoras não é mais jpcadas....

Código: Selecionar todos

STATIC FUNCTION Update1019B()

   IF ! AbreArquivos( "jpsenha" )
      QUIT
   ENDIF
   pw_AddModule( "PJPTRANSP", "PJPCADAS3" )
   pw_AddModule( "LJPTRANSP", "LJPCADAS3" )
   CLOSE DATABASES

   RETURN NIL
Na próxima atualização, o aplicativo vai liberar os novos módulos, para os usuários que tinham acesso aos antigos.

Primeira parte ok, novo arquivo de transportadoras, pronto pra ser atualizado nos clientes.
Agora retirar as precauções que tinha deixado na atualização.

Próxima etapa: eliminar os índices que se tornaram inúteis, e todo uso de CDTIPO, que se tornou um campo inútil.

E o MySQL?
Isso fazia parte da conversão pra MySQL anterior.
NÃO tenho problema com DBF, então MySQL é importante mas não é urgente.
Uma coisa de cada vez agora.
Quando chegar a hora de converter pra MySQL, vai ser só isso, e não ficar organizando arquivos/tabelas.

Meu modo de trabalho

Enviado: 19 Out 2019 11:40
por JoséQuintas
Antes da liberação final, definir a nova versão de DBFs:

Código: Selecionar todos

FUNCTION AppVersaoDbf()

   RETURN 20191019
As conversões vão ser feitas se a versão instalada for anterior a esta.

Código: Selecionar todos

FUNCTION ze_Update2019()

   IF AppVersaoDbfAnt() < 20191011; Update1011(); ENDIF
   IF AppVersaoDbfAnt() < 20191019; Update1019A(); ENDIF
   IF AppVersaoDbfAnt() < 20191019; Update1019B(); ENDIF

   RETURN NIL
Conclusão:
Agora deixo essa versão na internet, e o cliente pode atualizar na hora que quiser.
TODAS as atualizações pendentes serão feitas.
E eu prossigo com minhas alterações de fonte, não dependo do cliente instalar versão pra poder prosseguir.

E o MySQL?
Ainda tem a limpeza geral, que nem todos os clientes atualizaram.
Quando chegar a vez do MySQL, aí obrigo todos a atualizarem antes de começar.
Por enquanto continuar com a padronização dos DBFs que restam.
Isso não depende da limpeza, é necessário, e vai facilitar depois.

Meu modo de trabalho

Enviado: 19 Out 2019 18:59
por JoséQuintas
O perigo de alterações é que uma "chama" outra....
O perigo é fugir muito do que estava fazendo antes, e se complicar.
Como a parte anterior tava pronta, tudo bem.
Antes era PJPCADAS1 pra clientes, e PJPCADAS3. Como agora é um só.... lá vamos nós alterar o nome...

Código: Selecionar todos

STATIC FUNCTION Update1019B()

   IF ! AbreArquivos( "jpsenha" )
      QUIT
   ENDIF
   pw_AddModule( "PJPTRANSP", "PJPCADAS3" )
   pw_AddModule( "LJPTRANSP", "LJPCADAS3" )
   pw_AddModule( "PJPCADAS",  "PJPCADAS1" )
   pw_AddModule( "PJPCADASB", "PJPCADAS1B" )
   pw_AddModule( "LJPCADAS",  "LJPCADAS1" )
   CLOSE DATABASES

   RETURN NIL
Aproveitei a rotina anterior, então apenas alterei a versão pra repetir a atualização.
Se fizer mais de uma vez, sem problema, apenas vai estar liberando mesmos acessos pra mesmas pessoas.

Código: Selecionar todos

FUNCTION ze_Update2019()

   IF AppVersaoDbfAnt() < 20191011; Update1011(); ENDIF
   IF AppVersaoDbfAnt() < 20191019.1; Update1019A(); ENDIF
   IF AppVersaoDbfAnt() < 20191019.2; Update1019B(); ENDIF

   RETURN NIL
Agora vou pra eliminação dos índices jpcadas1 a jpcadas4, e o campo CDTIPO.
É até bom fazer agora, porque serve de conferência adicional pra mudança anterior, de separar transportadora.

Meu modo de trabalho

Enviado: 20 Out 2019 22:02
por Fernando queiroz
Boa parte do que você falou já venho fazendo a algum tempo, melhorando fontes, usando w3 , estou modificando os fontes para adaptar para o LETODBF mas já estou enxergando a possiblidade de MYSQL, tá ficando interessante , tem muita coisa ainda, como fazer atualização automática, atualização dos DBF, entre outras "COISAS" :)) :)) :))

Meu modo de trabalho

Enviado: 21 Out 2019 09:13
por syslink
letodbf, não seria letodb?

Meu modo de trabalho

Enviado: 21 Out 2019 09:48
por JoséQuintas
Fernando queiroz escreveu:Boa parte do que você falou já venho fazendo a algum tempo, melhorando fontes, usando w3 , estou modificando os fontes para adaptar para o LETODBF mas já estou enxergando a possiblidade de MYSQL, tá ficando interessante , tem muita coisa ainda, como fazer atualização automática, atualização dos DBF, entre outras "COISAS
Pois é.. isso de dar uma geral, ao mesmo tempo que organiza, abre a visão pra mais possibilidades.

Sobre isso que eu comentava:
não é melhoria só dos fontes, o próprio programador começa a querer cada vez mais.
Os fontes melhoram e o programador melhora junto.
syslink escreveu:letodbf, não seria letodb?
Confunde porque tem pelo menos dois, um original mais simples, e um mais "aperfeiçoado".
Não sei dizer os nomes exatos.

Meu modo de trabalho

Enviado: 21 Out 2019 15:01
por JoséQuintas
Vou deixar o campo por um prazo limitado

Código: Selecionar todos

   IF AppVersaoDbfAnt() < 20191101
      AAdd( aStruList, { "CDTIPO", "C", 1 } )
   ENDIF
Precaução, caso misturem versões.
01/11/2019

Isso tem a ver com o controle dos dbfs, e não com a versão do EXE.
Cada um tem sua própria versão.

Se colocarem versão velha... tudo bem... tem lá o campo. (mas não vai ter mais as transportadoras).
Se colocarem versão nova... por enquanto o campo é mantido.

Numa outra versão tiro o campo fora, mas vai ter que ser antes da versão MySQL, pra não tentar salvar no MySQL esse campo.

Meu modo de trabalho

Enviado: 21 Out 2019 15:26
por JoséQuintas
Decidindo as próximas alterações:

1. Alterar JPPEDI pra JPPEDIDO

2. Campo chave = "ID" + nome do arquivo/tabela, e numérico, mas sem o "JP" lógico, para JPPEDIDO, a chave ser IdPedido.

Nos pedidos hoje o campo é pdPedido, caractere de 6. Vai virar idPedido, numérico de 9 ou 11

Pra essa alteração, muito fonte a ser mexido, nos dois casos.

Ainda decidindo, mas é a reta final pra MySQL.

Talvez o maior problema seja no Harbour/DBF: Como alterar um campo de caractere para numérico, sem o erro de TypeMismatch?

Ou talvez dê pra usar aquela descoberta recente, de que pro MySQL, número é número, não importa se for string.
Vou ter que testar isso.

Meu modo de trabalho

Enviado: 21 Out 2019 15:29
por JoséQuintas
Bingo!!!!
Funciona !!!
O campo CDID é numérico, incremental

Código: Selecionar todos

INSERT INTO JPAGENDA ( CDID ) VALUES ( "100" )
Isso vai facilitar muuuito.

Agora só preciso renomear os campos, e tá feito.

Meu modo de trabalho

Enviado: 22 Out 2019 19:12
por JoséQuintas
Agora alterações delicadas.... nome de arquivo e nome de campo CHAVE.
Tive até que mexer nas atualizações anteriores.
O arquivo de pedidos, passa a ser JPPEDIDO ao invés de JPPEDI.
E o campo chave passa a ser IdPedido, ao invés de PdPedido.

Código: Selecionar todos

STATIC FUNCTION JPPEDIDOCreateDbf()

   LOCAL nCont, cCampo
   LOCAL aStruList := { ;
      { "IDPEDIDO",  "C", 6 }, ;
...

      { "PDINFALT",  "C", 80 } }

   IF AppVersaoDbfAnt() < 99999999
      AAdd( aStruList, { "PDPEDIDO",  "C", 6 } )
   ENDIF

   SayScroll( "JPPEDIDO, verificando atualizações" )

   IF ! ValidaStru( "JPPEDIDO", aStruList )
      MsgStop( "JPPEDIDO não disponível!" )
      QUIT
   ENDIF
Acima: Notem que o campo pdPedido vai existir até determinada versão... ainda em testes, deixei como eterna 99/99/9999

Código: Selecionar todos

   IF ! File( "jppedi.dbf" )
      RETURN NIL
   ENDIF
   IF ! ValidaStru( "JPPEDI", aStruList )
      MsgStop( "JPPEDI não dispnível!" )
      QUIT
   ENDIF
Acima: Como vou importar o arquivo antigo, com certeza preciso garantir que a estrutura está atualizada.

Código: Selecionar todos

   IF ! UseSoDbf( "jppedi", .T. )
      QUIT
   ENDIF
   IF ! AbreArquivos( "jppedido" )
      QUIT
   ENDIF
   SELECT jppedi
   GOTO TOP
   DO WHILE ! Eof()
      SELECT jppedido
      IF Empty( jppedi->idPedido )
         SEEK jppedi->pdPedido
      ELSE
         SEEK jppedi->idPedido
      ENDIF
      IF Eof()
         RecAppend()
         REPLACE ;
            jppedido->pdPedido WITH iif( Empty( jppedi->idPedido ), jppedi->pdPedido, jppedi->idPedido ), ;
            jppedido->idPedido WITH jppedi->idPedido
      ENDIF
      RecLock()
      FOR nCont = 1 TO FCount()
         cCampo := FieldName( nCont )
         FieldPut( nCont, jppedi->( FieldGet( FieldNum( cCampo ) ) ) )
      NEXT
      RecUnlock()
      SELECT jppedi
      RecLock()
      DELETE
      RecUnlock()
      SKIP
   ENDDO
   CLOSE DATABASES
   fErase( "jppedi.dbf" )

   RETURN NIL
Acima:
Detalhe 1:

Código: Selecionar todos

      IF Empty( jppedi->idPedido )
         SEEK jppedi->pdPedido
      ELSE
         SEEK jppedi->idPedido
      ENDIF
Porque isso?
Vai que algum cliente já rodou a atualização que gravou idPedido.... pra garantir se tiver conteúdo pego idPedido.
Ou seja... se a atualização já foi feita, não faz de novo, ou não corre o risco de gravar um número em branco no lugar dele.

Detalhe 2:

Código: Selecionar todos

      RecLock()
      FOR nCont = 1 TO FCount()
         cCampo := FieldName( nCont )
         FieldPut( nCont, jppedi->( FieldGet( FieldNum( cCampo ) ) ) )
      NEXT
      RecUnlock()
Se os arquivos são iguais, porque preciso do FieldNum() ?
Minha atualização de estrutura NÃO mexe com ordem de campos.
Isso significa que os arquivos podem conter os mesmos campos, mas podem estar em outra ordem.

Bom a parte acima conclui a atualização de estrutura, de trocar o nome do arquivo, de importar o arquivo anterior.
Mesma coisa, precaução: vai incluindo e apagando. Se por algum motivo não conseguir excluir, na próxima vez não vai importar duplicado. (apesar que o SEEK resolve isso).

Meu modo de trabalho

Enviado: 22 Out 2019 19:25
por JoséQuintas
A atualização do log no MySQL, porque alterou o nome do arquivo....

Código: Selecionar todos

   SayScroll( "Atualizando mysql" )
   WITH OBJECT cnMySql
      :ExecuteCmd( "UPDATE JPREGUSO SET RUARQUIVO='JPPEDIDO' WHERE RUARQUIVO='JPPEDI'" )
      :ExecuteCmd( "UPDATE JPREGUSO SET RUCODIGO=CONCAT( '1', SUBSTR( RUCODIGO, 2, 5 ) ) WHERE RUARQUIVO='JPPEDIDO' AND SUBSTR( RUCODIGO, 1, 1 ) = '7'" )
      :ExecuteCmd( "UPDATE JPREGUSO SET RUCODIGO=CONCAT( '2', SUBSTR( RUCODIGO, 2, 5 ) ) WHERE RUARQUIVO='JPPEDIDO' AND SUBSTR( RUCODIGO, 1, 1 ) = '8'" )
      :ExecuteCmd( "UPDATE JPREGUSO SET RUCODIGO=CONCAT( '3', SUBSTR( RUCODIGO, 2, 5 ) ) WHERE RUARQUIVO='JPPEDIDO' AND SUBSTR( RUCODIGO, 1, 1 ) = '9'" )
   ENDWITH
E a transferência de PdPedido para IdPedido

Código: Selecionar todos

STATIC FUNCTION Update1022E()

   IF ! UseSoDbf( "jppedido", .T. )
      QUIT
   ENDIF
   GOTO TOP
   DO WHILE ! Eof()
      IF Empty( jppedi->idPedido )
         RecLock()
         REPLACE jppedi->idPedido WITH jppedi->pdPedido
         RecUnlock()
      ENDIF
      SKIP
   ENDDO
   CLOSE DATABASES

   RETURN NIL
Com a precaução de não gravar encima de campo já convertido.
Vai que o número de versão se perde.... e considera versão errada....
Apesar que o número de versão fica no MySQL, não é tão perigoso como em DBF.

O que acontece agora?
Deixo na internet, quem atualizar, vai ter tudo convertido.

Por enquanto MySQL parado, os clientes precisam rodar a limpeza antes que eu comece a transferência pra MySQL.
Enquanto isso... vou organizando os DBFs, preparando pra transferir depois.

Em pedidos... tudo resolvido, pronto do jeito que eu quero pra MySQL.
Quero usar ID seguido do nome do arquivo. JPPEDIDO, tirando o JP fica PEDIDO, a ID dele é IdPedido

Agora vamos aos próximos.
Vou fazer isso com cada um deles.

Lembrando: NÃO é exigência do MySQL, eu é que decidi fazer assim.

Meu modo de trabalho

Enviado: 22 Out 2019 19:59
por JoséQuintas
Uia...
Faz tempo não recebia um email deste:

Código: Selecionar todos

Modulo: PDFECTECANCEL faltou abrir: jpclista  
Called from ENCONTRA(16)  
Called from DOCSALVAEMAIL(323)  
Called from DOCENVIAEMAIL(661)  
Called from SALVAXMLMYSQL(655)  
Called from PDFECTECANCEL(67)  
Called from DO(0)  
Called from RUNMODULE(94)  
Called from BOXMENU(757)  
Called from BOXMENU(744)  
Called from MENUPRINC(592)  
Called from SISTEMA(87)  
Called from (b)MAIN(48) 
[/quote]

Não é erro, o aplicativo já resolveu.

[code]
IF ! Encontra( "chave", "arquivo", "ordem" )
Podemos dizer que minha função Encontra() equivale ao dbSeek().
Mas ao usar um arquivo que não está aberto, ela abre automático.
Coloquei lá pra me avisar quando ela faz isso.

Agora, no PDfeCteCancel(), eu acrescento a abertura do arquivo jpCliSta

Código: Selecionar todos

   IF ! AbreArquivos( "jpempre", "jpcadas", "jpclista" )
      RETURN
   ENDIF
Assim tenho controle sobre quais arquivos cada módulo usa/precisa.

Só pra curiosidade: JP.CLI.STA, JP é meu prefixo padrão, CLI=Clientes, STA=Status
É a tabela aonde tenho os possíveis status de cliente, e a configuração sobre o que cada status afeta no uso daquele cliente.
Pode ser bloqueio total, parcial, etc.

Tava aqui pensando....

Estou mostrando rotinas de atualizar estrutura, a Encontra(), Browse(), AbreArquivos(), e outras mais...
VÃO TODAS PRO LIXO.
Estranho? Pra que vai servir rotina de DBF se não existir DBF?

Vai ver é por isso que estou acertando tudo de uma vez.... vai ser a última vez pra muita coisa...

Só vai restar o aplicativo em Flagship usando DBF, que talvez passe diretamente pra MySQL...

Meu modo de trabalho

Enviado: 23 Out 2019 13:36
por JoséQuintas
vb.png
Como eu comentei, estou atualizando até mesmo os fontes em Visual Basic 6.

Aí vocês podem pensar: já usava MySQL

ERA DBF MESMO.
Visual Basic 6, com ADS Local, acessando DBFs totalmente por comandos SQL !!!!
Compatível com Clipper SIXCDX.

É até interessante....
Seria uma alternativa, caso eu queira manter DBF pra algum uso local sem servidor....

Meu modo de trabalho

Enviado: 24 Out 2019 12:39
por JoséQuintas
Bom...
Eu disse que ia fazer uma coisa de cada vez....
De certa forma eu fiz isso mas....
Mexi em pedidos, clientes, estoque, produtos, financeiro....
Não vou colocar as rotinas porque fica repetitivo.
É minha reta final com DBFs, talvez a última vez que mexo com eles.

A atualização em funcionamento, apesar que não tem muito o que ver...
update.png

Meu modo de trabalho

Enviado: 24 Out 2019 13:18
por JoséQuintas
Primeiro problema.... é grave... mas não é grave...
cli.png
Em clientes não existe mais CDTIPO que fazia parte da chave.
Esqueci de retirar isso do específico do cadastro de clientes.

É só apagar esse "1" + , então não é grave, mas.... o cliente não poder consultar clientes é grave.

Mas tudo bem, já corrigi, e o cliente já clicou em atualizar.

Nota:
O susto foi que a moça ligou aqui e falou que tinha sumido o cliente.
Já pensei no pior...
Mas não, apenas a pesquisa no cadastro que deu problema.
Todo restante, outras telas que pesquisam cliente, tudo ok.

É a vantagem da atualização on-line, prático pra resolver problema.
Lógico... melhor teria sido testar tudo direito antes de instalar...