Leaderboard
Popular Content
Showing content with the highest reputation since 05/09/2023 in all areas
-
Bom dia a todos. Pessoal criei um vídeo onde demonstro algumas funcionalidades da Api rodando em Fivewin. Deus Abençoe a todos, uma ótima semana. Link: https://bit.ly/3PCCDMJ2 points
-
top, deu certo2 points
-
Olá pessoal. Desculpa aos adms, sei que aqui não é o lugar para postagem, mas aqui é o forum mais visitado. Criei uma api em node.js e está rodando em webservice. Ela possui mais de 80 funções para whatsapp, e fiz a comunicação em fivewin+xharbour com as principais (ativar sessão, ler qrcode, enviar mensagem, fechar sessão) para exemplificar o uso nas outras. Se alguém se interessar, me chame por gentileza que envio um demo do funcionamento. Na api tem toda a documentação em Swagger, para facilitar a comunicação e desenvolvimento. Contato: (16) 9 8874-6745 Obrigado.1 point
-
Resolvido: FUNCTION GetFatorVencimento( dData ) LOCAL nFator nFator := dData - Stod( "19971007" ) WHILE nFator > 9999 nFator -= 9000 ENDDO RETURN nFator1 point
-
Aposentadoria... Parar ou Não Parar ?
Luiz Fernando reacted to emotta for a topic
sensacional Luiz, passei por grande parte das situações que vc passou, as que não são iguais foram muito parecidas. Eu conheci o Fivewin na Microsiga, por uma situação especifica eu tinha que simular uma situação que não funcionava em ADVPL mas para que o pessoal responsável pela linguagem fizesse a correção eu precisava simular a mesma situação em clipper/fivewin. Eles me forneceram os disquetes de instalação do clipper 5.3 e do fivewin e eu simulei o problema e eles então corrigiram a linguagem. Era coisa boba, mas foi necessário isso. Foi no ano 2000 que isso aconteceu. Pesquisei mais sobre o assunto e cai na news do fivewin, basicamente vc usava o forum direto no outlook, lá conheci o Gilmer, Clemerson, Vagner e outros que agora não recordo os nomes. Essa foi a inspiração para que eu começasse a reescrever um software de ponto que eu fiz em clipper em 1998 para uma empresa, fiz como bico. Apenas pra passar o tempo comecei a reescrever a aplicação "for windows" que era como se falava na época e em 2002 quando pedi a conta da Microsiga e voltei para o interior foi esse novo software eu comecei a buscar clientes e montar um negócio. Aproveitei o tempo livre que ainda não tinha clientes e portei de clipper pra xHarbour. Depois disso em 2006 comprei o xHarbour com SQLRDD e portei a aplicação para funcionar também em SQL, foi um grande avanço pra gente na época. Foi neste ano também que abandonei o Edit e comecei a editar os fontes no xDevStudio (obrigado Vailton). Segui assim até 2020 quando mudei para o VSCODE. Bons tempos, boas lembranças mas o ponto que temos que observar é que de tempos em tempos precisamos rever as tecnologias que usavamos. Muitos começaram no DBASE e mudaram para clipper, depois passaram a usar fivewin, depois xHarbour, depois SQL, enfim, as coisas mudam e em alguns momentos as mudanças são maiores e exigem um pouco mais de esforço e sacrificio. Muito grato a todos aqui e sigo frequentando e ajudando como posso, e sendo ajudado tb, mesmo já não compilando uma aplicação fivewin a 3 anos, porem muito agradecido pelo que já me proporcionou.1 point -
Aposentadoria... Parar ou Não Parar ?
Luiz Fernando reacted to emotta for a topic
Perfeito Luiz, é exatamente disso que estou falando. Passei por está mesmo situação a alguns anos atrás, foi dolorido voltar a ser um iniciante e estudar tudo novamente, mas a experiência torna a curva de aprendizado bem mais rápida. Termos como git, vscode, docker e outras coisas relacionadas eram desconhecidas por mim, estudei, aprendi e tento aqui animar outros a fazer o mesmo e ter essa virada profissional que tanto foi benéfica pra mim. Parabéns Luiz por seguir esse caminho e vamos em frente Abraços1 point -
Aposentadoria... Parar ou Não Parar ?
Rogerio Figueira reacted to emotta for a topic
Que legal hein Rogério, inveja no bom sentido ! Mas parabéns pela forma como conseguiu isso pra vc, muito bom !1 point -
Bom dia Theotokos Deu certo na verdade em vez de fechar o programa ele fecha a conexao do usuario que esta aberto e abre a tela para logar de novo ou seja usei a sua ideia Obrigado1 point
-
Claro que não Vem ao caso, mas fiz uma tela de mesas, usando XBROWSE com Array,e imagens, fica bem legal. Claro que não se aplica a sua realidade, isso, mas serve pra voce tirar ideias. Nesse casos as mesas são dinâmicas( tem cliente com 500 mesas, tem com 30) e são cadastradas no BD. Tem um Time que atualiza essa tela abaixo em tempos em tempos. Claro que terá que fazer conforme a sua realidade, mas poderia colocar a foto do veiculo, ou a placa dele no lugar o "icone do garçon", etc... Se precisar de mais informaçoes, pode me chamar no Zap (32)9 8892-50941 point
-
Bom dia a todos. Mais uma funcionalidade da Api, agora trazendo as imagens dos contatos e grupos e mostrando que é possível também receber mensagens. Link: https://bit.ly/3vBmMHo Deus abençoe a todos. Boa semana.1 point
-
Sistema EXE de fluxo de caixa para servidor em nuvem!
rochinha reacted to Arlindooliveira for a topic
Boa Noite; Desenvolvi um sistema teste de fluxo de caixa para servidor em nuvem. Feito Fivewin/xHarbour. Não utilizo nenhuma DLL ou Lib para comunicacao. Coloquei no servidor o banco de dados (MySql) e utilizo apenas uma API feito em php para comunição, se os amigos poderem testar, agradeceria muito. É apenas um EXE e uma pasta de bitmaps. Bem leve. Link download: https://ar2plus.com.br/download Para entrada no sistema; USUARIO: usuario SENHA: usuario Muito obrigado;1 point -
htmp := Hash() htmp["001","A"] = 4 htmp["003","A"] = 21 htmp["004","A"] = 14 htmp["002"] = hClone(htmp["003"]) htmp["003"] = hClone(htmp["004"]) // se precisar deletar a 004 considere a linha abaixo hDel(htmp, '004') * Sinceramente estou achando um pouco estranho essa sua necessidade, eu uso Hash a anos e nunca precisei fazer algo assim, acredito que você esteja usando Hash com o pensamento voltado a array.1 point
-
Tudo que é novo, é melhor: https://forums.fivetechsupport.com/viewtopic.php?f=16&t=33542&sid=633bd6c9289881bf6095b9f1458d5079&start=30 Regards, saludos.1 point
-
Explique melhor o intuito disso, pls. Regards, saludos.1 point
-
KKKKKKKKKKKKKK, Thanks friend!1 point
-
Enviar Objeto como parâmetro
rochinha reacted to Ladinilson for a topic
Tente dar uma "aliviada" na memória a cada envio com : HB_GCALL( .T. ) Espero que ajude. E o Corinthinas e Vasco começa seu ano bem kkkkkk1 point -
Amiguinhos, Eu não tinha ciencia desta plataforma para este fim, afinal o que não falta são estas plataformas por ai, mas se o seu cliente adquiriu creio que foi pelo preço que está muito bom em relação à outras. No que tange a integração eu creio que você precisará inicialmente fazer 4 interações iniciais sendo: Inclusão de Categoria, Exclusão de Categoria, Inclusão de Produtos e Exclusão de produtos. Veja na API se a mesma possui exemplo via CURL(que serão comandos a base de prompt) e comece a fazer os envios de comandos. Vendo que eles funcionam faça com que seu sistema gere o teto do comando e acione o CURL. Quando se sentir seguro integre usando as chamadas à API. Bom trabalho.1 point
-
Amiguinhos, [b]Theotokos[/b] o CartPanda tem API com documentação1 point
-
conforme o João passou, procurei lá e consegui achar uma forma segue abaixo function orion_jornada_AchaEndereco(mLat, mLong) local cGoogleURL := "https://nominatim.openstreetmap.org/reverse?format=xml&" local cAddress := "lat="+alltrim(mLat)+"&lon="+alltrim(mLong) local aReturn, i, cTxt := "" if empty(mLat) mLat := jornada->latitudegps mLong := Jornada->longitudegps cAddress := "lat="+alltrim(mLat)+"&lon="+alltrim(mLong) endif // aReturn := hb_jsonDecode( WebPageContents( cGoogleURL + cAddress) ) // *** Change this *** cDocXML := WebPageContents( cGoogleURL + cAddress) * hb_jsondecode( aReturn, @aReturn ) && se lá na URL vc colocar format "json" - eu uso "XML" if !empty(cDocXML) mRodovia := LerTag(cDocxml, "road") mCidade := LerTag(cDocxml, "town") mArea := LerTag(cDocxml, "municipality") mEstado := LerTag(cDocxml, "state") mRegiao := LerTag(cDocxml, "region") mRodovia := iif(len(rtrim(mrodovia))>0,mRodovia+", ","") mCidade := iif(len(rtrim(mCidade))>0,mCidade+", ","") mestado := iif(len(rtrim(mEstado))>0,mEstado+", ","") mRegiao := iif(len(rtrim(mRegiao))>0,mRegiao+", ","") cTxt1 := mRodovia + mcidade + mEstado + mRegiao + mArea cTXT := U8ToUni(cTXT1,"UTYPE_ANSI") if len(alltrim(ctxt)) < 10 cTxt:="Localização não Encontrada" endif else cTxt:="Localização não Encontrada" endif dbselectarea("jornada") mregistro := jornada->( recno()) grava_dados("A","jornada",{ "local" }, { cTxt }, alias(), "S") return nil1 point
-
Marcio, esse tipo de situação se resolve com expressão regular. Infelizmente não vou conseguir te ajudar muito pois esse é um assunto que não domino, nas poucas vezes que precisei eu estudei o assunto, resolvi e como uso muito pouco acabo esquecendo como funciona de fato. Já usei pra validar email (por exemplo) e algumas outras coisas pontuais. Se quiser estudar o assunto pesquise sobre a função HB_RegExAll, ou pesquise sobre expressão regular, esse é um conceito que existe em todas as linguagens que programação. Veja tb o link abaixo no wikipedia explicando o que é: Expressão regular – Wikipédia, a enciclopédia livre (wikipedia.org)1 point
-
Opa, olá a todos, mas essa informação vem de um celular, e no APP não tem essa trava, então o dado é inserido na nossa base de dados, mas vamos rodar um "tratamento" e ajustar. Obrigado1 point
-
1 point
-
FUNCTION GetNewArray( xVal ) LOCAL aNewArray := {} LOCAL aArrayAux := {} LOCAL nX FOR nX := 1 TO Len( aCartelas ) aArrayAux := aCartelas[ nX ] IF AScan( aArrayAux, { | aX | aX == xVal } ) <> 0 aAdd( aNewArray, AClone( aArrayAux ) ) ENDIF NEXT RETURN aNewArray1 point
-
TheoTokos muito obrigado pela dica somente a parte do oBrw:SetArray( aVerPar_ ) me ajudou... estava deixando isso passar batido1 point
-
Tarde: Gentileza Reportar diretamente o Enrico Maria Giordano aqui: https://forums.fivetechsupport.com/viewtopic.php?f=16&t=33542&sid=246a5d831c74bb3dfd6b44c29fb55526&start=60 Como não uso a SQLRDD, não saberia reportar o erro e em qual momento, ok? Reporte em Inglês ou Espanhol que ele entende, se bem que ele é fluente em Inglês e Italiano. Obg. abs. Regards, saludos.1 point
-
HBCOMPAT.CH? Xeiro! kkkkkkkkkkkkkkk1 point
-
O Marcos gambeta adicionou ao seu repositório do hb++, e dá pra ser compilado com o harbour 3.2 e 3.4, assim como também já removeu a dependência do bison pra compilar o mesmo, e disse que pretende remover a dependência de usar o xhb.hbp na compilação, o que seria ideal também. Está caminhando, em breve acredito que vai estar no repositório do harbour na pasta contrib. Baixe os fontes já corrigidos para harbour aqui neste link: https://github.com/marcosgambeta/sqlrddpp/tree/main1 point
-
Olá a Todos Depois da ajuda do amigo *Jmsilva* Muito obrigado mesmo pela dedicação. O problema é que tem espaços no campo de 'Nao Inf.' tem que ser 'NaoInf.' ou seja o espaço em branco entre as palavras não pode cMsg := IF(!EMPTY(v_Documento),v_Documento,'Nao Inf.')1 point
-
Baxei aqui na minha maquia e compilei apenas o sqlrdd. so ficou 6 arquivos que nao conseguir compilar por que nao conseguir encontrar alguns include existentes neste arquivos sqlact.c sqlex1ora.c sqlex2ora.c sqlex3ora.c sqllex.c sqlora.c Depois de compilado conseguir fazer o seguinte teste com xharbour1.2.3 bcc7 : RddSetDefault( "SQLRDD" ) SET DELETED ON IF SR_ExistTable( "clientes" ) USE clientes NEW alias temp VIA "SQLRDD" BROWSE() endif dbcloseall()1 point
-
Faça uma busca aqui: http://www.pctoledo.com.br/forum/viewtopic.php?f=57&t=27034&p=160878&hilit=POSTGRESQL#p160878 Regards, saludos.1 point
-
Foi relatado problema ao compilar o código C usando xharbour open source. Eu corrigi para tornar compatível tanto no comercial (o que eu uso) como no open source. Basta pegar o código atualizado e fazer o teste.1 point
-
identificar campo obrigatorio no GET
ricardomouramarques reacted to kapiaba for a topic
Aqui Ricardo, os Links para usar o WORKSHOP.exe the best. https://forums.fivetechsupport.com/viewtopic.php?f=6&t=43426&sid=e424e6f31fb5d164ebb9f43f3eb8cd0f&start=30#p261753 Abs. Saludos.1 point -
identificar campo obrigatorio no GET
ricardomouramarques reacted to kapiaba for a topic
Fechado!! 6 brejas(para iniciar... kkkkk) no centro de Sampa, bora? Não vale copiar o meu exemplo. kkkkkkkkkkkkkk Regards, saludos.1 point -
Já consegui uma vaga, obrigado a todos que enviaram mensagens1 point
-
Olá, agora entendi. select a.Date, ( SELECT COUNT(*) from process AS p WHERE a.Date >= p.dtcalc1 and If( TIMESTAMPDIFF(DAY, p.dtcalc1, p.dtcalc2) = 0 , a.Date <= p.dtcalc2, a.Date < p.dtcalc2 ) GROUP BY a.Date) AS ocorrencia from ( select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) ) DAY as Date from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d ) a where a.Date between '2023-06-01' and '2023-06-07' GROUP BY a.Date ORDER BY a.Date Essa query vai retorna algo assim 2023-06-01 - NULL 2023-06-02 - NULL 2023-06-03 - 1 2023-06-04 - 3 2023-06-05 - 1 2023-06-06 - 2 2023-06-07 - NULL Att., Oliveiros Junior1 point
-
revolvido, os paramentro tem que ser maiúsculo DLL32 FUNCTION SetClientTCP(ip AS STRING, porta AS LONG)1 point
-
IMPRESSORA L42 PRO FULL
Theotokos reacted to Ladinilson for a topic
Desculpe a brincadeira mas olhando esses código me lembrei da minha vida antes de conhecer o FastReport, acertar e ajeitar isso era terrível, um castigo que nenhum programador merece kkkk1 point -
Não pega FONT nem a pau!
rochinha reacted to Ladinilson for a topic
Tenho esse conhecimentro amigo, é que em determinado momento quase TODOS aqui já tiveram algum problema com fonts e é comum na linguagem. Estou tentando outras alternativas para contornar esse problema. Obrigado1 point -
Comparar Estrutura tabela MYSQL
Luiz Fernando reacted to alex2002 for a topic
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 lRetorno1 point -
Atualizar Versao do Sistema
lucimauromelo reacted to emotta for a topic
segue a funcao CompFile que retorna se os arquivos são iguais ou diferentes Function Teste() Local cFile1 := "arq1.txt" Local cFile2 := "arq2.txt" Local cFile3 := "arq3.txt" Local cCont1 := "testando texto para arquivo 1" Local cCont2 := "testando texto para arquivo 1" Local cCont3 := "testando texto para arquivo 3" MemoWrit(cFile1, cCont1) MemoWrit(cFile2, cCont2) MemoWrit(cFile3, cCont3) If CompFile(cFile1, cFile2) ? cFile1 + " é igual a " + cFile2 Else ? cFile1 + " é diferente de " + cFile2 EndIf If CompFile(cFile1, cFile3) ? cFile1 + " é igual a " + cFile3 Else ? cFile1 + " é diferente de " + cFile3 EndIf ? "fim" return Static Function CompFile(cFile1, cFile2) Local cHash1 := HB_MD5File( cFile1 ) Local cHash2 := HB_MD5File( cFile2 ) Return cHash1 == cHash21 point