Jump to content
Fivewin Brasil

alex2002

Membros
  • Posts

    1,229
  • Joined

  • Last visited

  • Days Won

    24

Posts posted by alex2002

  1. Olá galera, em especial o meu amigo "Vai Driblando" rsrsrsrsrs

    Me caro, já no meu auge dos quase cinquenta anos, trinta e cinco nos desenvolvimentos de linhas de programação, me vejo na mesma situação que você. Porém, por esses dias tomei a decisão de também planejar a saída de cena (ou quase isso). Acontece que essa decisão só veio depois de umas consultas rotineiras as quais descobri uns B.Os. na saúde. Contudo, graças a Deus, fiz as cirurgias necessárias e hoje estou bem. Mas estou tirando o pé do acelerador e pisando um pouco mais forte no freio.

    Como é de conhecimento de muitos amigos, trabalho com sistema para insituições financeiras, o que torna as coisas um pouco mais intensa rsrsrsrs. O chefe (Evandro Guimarães de Paula) já deveria ter tomado essa decisão há muito tempo, até porque hoje ele atrapalha os funcionários dele rsrsrsrsrs.

    Como pé de meia, negociei uma parte da empresa e consegui comprar uma terrinha onde vou criar uns gadinhos e boa.

    No mais é isso meu amigo, arrume sócios que irão tocar o seu projeto e vá descansar mesmo. Creio que, com a experiência que temos, jamais vamos deixar de vez, mas eu estou optando por ficar só na consultoria e diminuindo o que ponho a mão na massa hoje.

    É isso aí. Um abraço a todos.

    Alexandre Pereira 

  2. 4 horas atrás, Valdir disse:

    Indico: https://www.teamviewer.com/pt-br/

    Pagando uma pequena mensalidade, você terá acesso a outras funcionalidades que a versão gratuita não disponibiliza.

    Além disso,  você pode criar uma versão QS com sua Tela de Suporte Exclusiva e disponibilizá-la para todos os seus clientes.

    Utilizo a versão paga do Teamviewer há mais de 8 anos e eu e meus clientes, estamos muito satisfeitos.

    abrs.

    Rapaz do céu, o "VaiDriblando" apareceu.

    Está sumido meu amigo.

    Um abraço.

    Alexandre Pereira

  3. 12 horas atrás, macs disse:

    Obrigado amigo... irei testar e darei um feedback se o problema foi resolvido!

    Outra coisa, você está usando o MariaDb ou MySql? Qual a versão?

    De um modo geral uso o MariaDB 10.6, mas os clientes trabalham com as mais variadas versões. Inclusive alguns usam o MySQL mesmo.

    Mas esta configuração de ambiente é para o MariaDB, porém os campos são os essenciais para configuração de ambos (Maria/MySQL).

    Um abraço,

    Alexandre Pereira

  4. Boa noite meu amigo.

    Isso daí possivelmente é configuração de ambiente do MySQL.

    Você tem que mudar alguns campos no arquivo de configuração do MYSQL/MariaDB.

    O campo principal aí deve ser: o wait_timeout

    O meu arquivo My.INI do MariaDB é assim:
     

    ///////////////////////////////////////////////////////////
    [mysqld]
    datadir=C:\Program Files\MariaDB 10.6\data
    port=3307
    innodb-page-size=16384
    innodb_buffer_pool_size=5096M
    max_allowed_packet = 64M
    wait_timeout = 6000
    skip-name-resolve
    sql-mode = ""
    sysdate-is-now = 1
    innodb = FORCE
    innodb-strict-mode = 1
    general_log = 0

    # CACHES AND LIMITS #
    tmp-table-size = 16M
    max-heap-table-size = 16M
    query-cache-type = 0
    query-cache-size = 0
    max-connections = 100
    thread-cache-size = 50
    open-files-limit = 65535
    table-definition-cache = 1024
    table-open-cache = 2048

    # INNODB #
    innodb-flush-method = O_DIRECT
    innodb-log-files-in-group = 2
    innodb-log-file-size = 64M
    innodb-flush-log-at-trx-commit = 1
    innodb-file-per-table = 1
    innodb-buffer-pool-size = 2G

    [client]
    port=3307
    plugin-dir=C:/Program Files/MariaDB 10.6/lib/plugin
    /////////////////////////////////////////////////////////////////////////////

     

    Lembrando que esta configuração é a que coloco para maioria dos clientes e rodam sistemas pesados.

     

    Um abraço,

    Alexandre Pereira

     

     

     

  5. 6 horas atrás, Ladinilson disse:

    O site é beeeeem amador e parece site de golpe!
    Mesmo assim obrigado amigo mas não tive nenhuma confiança nele e vou continuar procurando.

    Mas é lá mesmo. O pessoal da Xailer é que está mantendo o Fast for xHarbour

  6. Bom dia Luiz.

    Este código meu faz exatamente o que vc precisa. Eu rodo a verificação de tabelas todas as vezes que muda uma versão. Sendo assim, nunca mais precisei me preocupar com estrutura de banco de clientes. E quando mudo alguma coisa, basta eu colocar no array que define a estrutura da tabela. Só isso.

     

    cTabela := cBanco+'.ase_log'  // Tabela de logs de documentos assinados eletrônicamente
    aCampos := {}

    //                Campo             Tipo            NULL?  Default  Comentário (isso vira um dicionário de dados depois)
    aadd( aCampos, { 'CCO_CONTA',       'CHAR(9)',      '',    '',      'Código da Conta Corrente' } )
    aadd( aCampos, { 'ASE_NDOC',        'CHAR(10)',     '',    '',      'Número do Contrato' } )
    aadd( aCampos, { 'ASE_PARCEIRO',    'INT(1)',       '',    '0',     'Código do parceiro: 1-ClickSign' } )
    aadd( aCampos, { 'ASE_ARQUIVO',     'VARCHAR(50)',  '',    '',      'Nome do arquivo' } )
    aadd( aCampos, { 'ASE_TOKEN',       'MEDIUMBLOB',   '',    '',      'Token do arquivo devolvido pelo parceiro de assinatura eletrônica' } )
    VerificaTabela( cTabela, aCampos )

    ////////////////////////////DADOS DA FUNCAO////////////////////////////////////////////
    // NOME       : VerificaTabela                                                       //
    // SINTESE    : Verificar a estrutura da tabela e atualiza                           //
    // PARAMETROS : <1> cTabela   = Nome da Tabela                                       //
    //              <2> aCampos   = Estrutura dos campos                                 //
    //              [3] cChave Primária  (Default SQL_ROWID)                             //
    //              [4] lAutoIncrement  (Default .t. )                                   //
    // RETORNO    : lExecutou                                                            //
    ///////////////////////////////////////////////////////////////////////////////////////
    function VerificaTabela( cTabela, aCampos, cChavePrimaria, lAutoIncrement )
    local aSql
    local cCmdSql
    local cNomeA, cTipoA, cDefaultA, cComentA, cNullA
    local cNomeB, cTipoB, cDefaultB, cComentB, cNullB
    local nEncontrado
    local i
    local lRetorno := .t.
    local lSetExact := set(_SET_EXACT, .t.)

    default cChavePrimaria := 'SQL_ROWID'
    defaulT lAutoIncrement := .t.

    if !Table( cTabela )
        CriaTabela( aCampos, cTabela, cChavePrimaria, lAutoIncrement )
        
        // Verificando se criou
        if !Table( cTabela )
           lRetorno := .f.
        endif
        set(_SET_EXACT, lSetExact )
        return lRetorno
    endif

    aEstrutura := SqlArray('show full columns from '+cTabela )

    for i = 1 to len( aCampos )
       cCampoA   := rtrim( aCampos[i,1] ) 
       cTIpoA    := strtran( aCampos[i,2], ' ', '') 
       cNullA    := aCampos[i,3]
       cDefaultA := aCampos[i,4]
       cCommentA := aCampos[i,5]
       
       if len( aCampos ) >= 6 .and. aCampos[i,6] 
          cDefaultX := aCampos[i,4]
       else
          cDefaultX := '"'+aCampos[i,4]+'"'
       endif
          


       nEncontrado := ascan( aEstrutura, {| x | lower( cCampoA ) == lower( x[1] ) } )
       if nEncontrado <> 0
          cCampoB    := rtrim( alltrim(aEstrutura[nEncontrado,1]) )
          cTipoB     := strtran( alltrim(aEstrutura[nEncontrado,2]), "'", '"' )
          cNullB     := alltrim(aEstrutura[nEncontrado,4])
          if lower(cNullB)  = 'yes'
              cNullB  := ''
          endif
          cDefaultB  := alltrim(aEstrutura[nEncontrado,6])
          cCommentB  := alltrim(aEstrutura[nEncontrado,9])
          
          // Verificando se houve mudança na estrutura
          if lower(cCampoA) <> lower(cCampoB) .or. lower(cTipoA) <> lower(cTipoB) .or. lower(cNullA) <> lower(cNullB) .or. lower(cDefaultA) <> lower(cDefaultB) .or. lower(cCommentA) <> lower(cCommentB)
             // Verificando se o campo é númerico e se realmente mudou
             
             if lower(cCampoA) = lower(cCampoB) .and. lower(cTipoA) = lower(cTipoB) .and. lower(cNullA) = lower(cNullB) .and. lower(cCommentA) = lower(cCommentB) .and. ( len( sonumeros( cDefaultA ) ) <> 0 .or. len( sonumeros( cDefaultB ) ) <> 0 )

                // Verificando o valor default
                    if strzero( val( cDefaultA ), 30, 10 ) = strzero( val( cDefaultB ), 30, 10 ) 
                   loop
                endif

                endif
                
             if lower(cCampoA) = lower(cCampoB) .and. lower(cTipoA) = lower(cTipoB) .and. lower(cCommentA) = lower(cCommentB) .and. lower(cNullA) <> lower(cNullB)
                // Verificando condição do NULL
                if empty(cNullA) .and. lower(cNullB) = 'no'
                   loop
                endif

             endif
             // Fim
                 
        //         ? cTabela, 'campo', lower(cCampoA), lower(cCampoB), 'tipo', lower(cTipoA), lower(cTipoB), 'null', lower(cNullA), lower(cNullB), 'default', lower(cDefaultA) , lower(cDefaultB), 'comment', lower(cCommentA), lower(cCommentB)

             if upper(cCampoA) = cChavePrimaria .and. lAutoIncrement
                cCmdSql := 'ALTER TABLE '+cTabela+' DROP '+cCampoA
                if !SqlExecute( cCmdSql )
                   lRetorno := .f.
                endif
          
                  cCmdSql := 'ALTER TABLE '+cTabela+' '
                    cCmdSql += 'ADD '+cCampoA+' '+cTipoA+' '
                    cCmdSql += if(cNullA = 'NO','NOT NULL','')+' '
                    cCmdSql += if(!empty(cDefaultX) .and. cDefaultX <> '""','DEFAULT '+cDefaultX,'')+' '
                    cCmdSql += if(!empty(cCommentA),'COMMENT "'+cCommentA+'"','')+' '
                    if upper(cCampoA) = cChavePrimaria            
                       cCmdSql += 'PRIMARY KEY '+if( lAutoIncrement, 'AUTO_INCREMENT','')+' '
                  endif
                   cCmdSql += if( i > 1, 'AFTER '+aCampos[i-1,1],'FIRST') 
             else
                 cCmdSql := 'ALTER TABLE '+cTabela+' '
                    cCmdSql += 'MODIFY COLUMN '+cCampoA+' '+cTipoA+' '
                    cCmdSql += if(cNullA = 'NO','NOT NULL','')+' '
                    cCmdSql += if(!empty(cDefaultX) .and. cDefaultX <> '""' ,'DEFAULT '+cDefaultX,'')+' '
                    cCmdSql += if(!empty(cCommentA),'COMMENT "'+cCommentA+'"','')+' '
                    if upper(cCampoA) = cChavePrimaria            
                       cCmdSql += 'PRIMARY KEY '+if( lAutoIncrement, 'AUTO_INCREMENT','') 
                 endif
                endif
     
              if !SqlExecute( cCmdSql )
                 lRetorno := .f.
              endif
            endif
       else   
          cCmdSql := 'ALTER TABLE '+cTabela+' '
            cCmdSql += 'ADD '+cCampoA+' '+cTipoA+' '
            cCmdSql += if(cNullA = 'NO','NOT NULL','')+' '
            cCmdSql += if(!empty(cDefaultX) .and. cDefaultX <> '""','DEFAULT '+cDefaultX,'')+' '
            cCmdSql += if(!empty(cCommentA),'COMMENT "'+cCommentA+'"','')+' '
            if upper(cCampoA) = cChavePrimaria            
               cCmdSql += 'PRIMARY KEY '+if( lAutoIncrement, 'AUTO_INCREMENT','')+' '
          endif
           cCmdSql += if( i > 1, 'AFTER '+aCampos[i-1,1],'FIRST') 
          if !SqlExecute( cCmdSql )
             lRetorno := .f.
          endif
       endif
    next

    // Limpando campos que não existem na estrutura e que estão na tabela
    for i = 1 to len( aEstrutura )
       cCampoA   := aEstrutura[i,1]  
       if upper(cCampoA) = 'SQL_ROWID' .or. upper(cCampoA) = 'SQL_DELETED'
          loop
       endif

        nEncontrado := ascan( aCampos, {| x | lower( cCampoA ) == lower( x[1] ) } )
       if nEncontrado = 0
          cCmdSql := 'ALTER TABLE '+cTabela+' DROP '+cCampoA
          if !SqlExecute( cCmdSql )
             lRetorno := .f.
          endif
       endif
    next
    //    
    SysRefresh()
    set(_SET_EXACT, lSetExact )
                     
    return lRetorno
     

  7. 22 horas atrás, wanderso disse:

    Mas dependendo do que é alterado no sistema, não muda o tamanho do arquivo, se vc alterou um "a" por "o" no .res do sistema não muda o tamanho. Como fica neste caso?

    Cara, sempre muda o tamanho, porque eu mando o pacote zipado. E sempre que compilo mudando uma vírgula o tamanho muda. Já teve caso em que acidentalmente colocamos um número na variável e subimos, daí tivemos que corrigir e mudou sim o tamanho.

  8. 22 horas atrás, emotta disse:

    Alex, seria legal você fazer um teste, mas acredito que é muito rápido obter o MD5. O importante é que não seja um processo executado a todo minuto, mas se for executado só algumas vezes por dia não terá problema.

    Agora se ficar lento pra você, realmente é melhor continuar checando data/hora/tamanho, mas se o usuário abre o executavel na máquina ele também faz download do executável e o executa, o que demora muito mais.

    Hoje em dia para o usuário abrir o seu programa (de 30mb) demora muito pra começar a executar?

    Então, no meu caso eu rodo o atualizador (em background) toda vez que o cara entra no sistema. Isso porque durante o dia pode ter uma bug corrigido urgentemente. 

    Quanto a abrir o EXE não demora muito. 

    Mas tudo isso é só para clientes que não usam a nuvem. Como hoje a maioria usa o TSPLUS a atualização é feita por nós mesmos.

     

  9. No meu caso, antes era por data e hora.

    Depois que trocamos o servidor, passou a dar problema pq mudou o SO dele. Daí colocamos por tamanho e tem uns 15 anos que não temos problemas. Já colocamos em todo tipo de SO e tem rodado legal. 

    Comparar o hash é legal, mas é bem mais lento, pq ele vai ter que praticamente fazer um donwload do arquivo (ou subir o conteúdo na memória) para fazer comparação. No nosso caso aqui é sem chance, o pacote compactado tem mais de 30 megas, imagina aguardar isso tudo apenas para dizer se tem versão nova.

    Mas o que vale é ver o que mais funciona para você.

  10. Olá Edu.

    Segue a parte do meu código que verifica versão nova.

    Normalmente é um EXE que eu rodo toda vez que entra no meu ERP. Daí se existir versão nova e o cara quiser atualizar, este atualizador fecha o ERP para fazer a atualização. E é bem rápido, como se ele rodasse em background.

    Um abraço,

    Alexandre Pereira

     

     

    //////////////////////////////////////////////////////
    LOCAL lRetorno := .T.
    local lErro      := .f., lAchou := .f., lTemVersaoNova := .f., lAtualiza := .f.
    local i
    local nTamRemoto, nTamLocal

    cArqLocal  := cLocal+'\'+cSistema+'.zip'
    cArqRemoto := cArquivo

    // Aqui existe o "for" porque eu e trabalhava com mais de um repositório da versão

    for i = 1 to 1
       if Conecta( i )
          visualiza( "Conexão estabelecida, Verificando se existe Atualização..." )
          oFtp:Cwd(cPasta)
          aArquivo := oFTP:listfiles( cArqRemoto )
          if len( aArquivo ) = 0
             lRetorno := .f.
             // visualiza('Atualização não encontrada! **** ERRO **** ')
           else
             nTamRemoto  := aArquivo[1,2]
          endif
          oFTP:Close()
       else
          lRetorno := .f.
       endif
       if lRetorno 
          exit
       endif
    next


    if lRetorno
       if file( cArqLocal )
         nTamLocal := fsize( cArqLocal )
       else
         nTamLocal := 0
       endif
       
      if nTamRemoto <> nTamLocal
          lTemVersaoNova := .t.
       endif

    else
       lErro := .t.
       visualiza("Problemas para verificar nova versão! ")
       if !lQuiet 
           MsgInfo('Problemas para verificar nova versão!','Erro de Atualização')
       endif
    endif

    if !lErro .and. !lTemVersaoNova
       visualiza("Não Existe nova versão disponibilizada! ")
       if !lQuiet 
           MsgInfo('Não Existe nova versão disponível!','Sem Atualização')
       endif
    endif

    if !lErro .and. lTemVersaoNova
         if MsgYesNo('Existe nova versão disponível do CredPLUS, deseja atualizar?','Nova Versão')
            lAtualiza := .t.
         endif
    endif

    if lAtualiza
       visualiza("Resetando conexões...! ")
       syswait(2)
        sysrefresh()     
        killprocess(cSistema+".exe")
        MyWinExec('livecred '+if(lQuiet,'/quiet ','')+cSistema+' '+cPerfil)                                                                   
    endif   

    lSair:= .t.
    quit
    hb_gcAll()                                 
    return nil

     

  11. Olá pessoal.

    Alguém conhece uma ferramenta que converta um HTML em PDF? 

    Vi alguma coisa em JavaScript, mas queria ver algo já pronto como classe ou coisa parecida.

    Um abraço,

    Alexandre Pereira

     

  12. Olá amigo.

    Tente:

     

     
    cSql := "INSERT INTO contador ( 'id_contador', 'nome', 'dtcadastro' ) "
    cSql += "VALUES ("
    cSql += " '1', '"+ALLTRIM( D_CONTAB->NOME ) +"', "
    if empty( D_CONTAB->DTCADASTRO )
       cSql += "NULL"
    else
       cSql += " '"+Data_sql( D_CONTAB->DTCADASTRO )+"' "
    endif
    cSql += " );"

    Um abraço,

    Alexandre Pereira

     

  13. Olá pessoal.

    Conversei com o Gilmer e estou prestes a atualizar a minha versão do Five.

    Queria saber se alguém aqui já compila em 64 bits. Se é tranqueira ou se é de boa a conversão.

    Atualmente estou com a 14.12 do five e ainda uso o xHarbour 1.2.3 mais o BCC.

    Não uso nenhuma LIB de terceiro. Todos eu tenho os fontes.


    Se alguem puder expor as ideias para poder ajudar.

    Obrigado a todos.

    Um abraço,

    Alexandre Pereira

  14. 3 horas atrás, emotta disse:

    esse é um projeto descontinuado, é fria, nem perca tempo.

    A melhor forma de rodar o sistema em um mac seria alguma solução como essa do video abaixo. É gambiarra mas deve resolver.

    Nunca usei solução como essa, eu estava estudando essa possibilidade a alguns anos antes de reescrever parte do sistema para web usando outras linguagens.

    Mod_harbour ainda era um protótipo quando eu fiz a mudança. Se fosse hoje em dia eu separaria um tempo para estudar essa possibilidade, embora ainda não tenha visto nenhum projeto de fato funcional usando ele.

     

    Esta solução é exatamente o TSPLUS.

    Já usamos há um tempo aqui na empresa e estamos tendo bons resultados.

    Um abraço,

    Alexandre Pereira

  15. Pra te falar a verdade eu nem sei qual a versão da SQLLIB. Eu uso com o Fivewin 14.12 e xHarbour123. Mas tenho clientes que usam versões mais novas.

    Quanto à versão do MySQL/MariaDB não vejo nenhuma restrição, uso desde a versão 4 até as versões atuais sem nenhum problema (tenho diversos tipos de clientes), ele usa o conector da própria DLL do MySQL.

    Um abraço,

    Alexandre Pereira

  16. Olá amigo.

    Cara, fica tranquilo e entre de cabeça. Você só tem a ganhar.

    Comece com um cursinho básico de MySQL. Instale o MariaDB ou MySQL (eles são gratuítos). Instale também o SQLYOG Comunity, ele é um aplicativo onde vc acessa o SQL e consegue executar as querys.

    Por fim pratique bastante e tente usar RDDS que vão te deixar bem a vontade com os comandos do DBF (dbskip, dbusearea...). Eu utilizo o SQLLIB há mais ou menos uns 17 anos e sou muito tranquilo com isso. Prefiro usar nativamente, mas tem situação onde dbusearea é extremamente rápido de usar.

    Qualquer coisa o fórum está aqui para te ajudar no que for necessário.

    Um abraço,

    Alexandre Pereira

×
×
  • Create New...