Painel de líderes
Conteúdo popular
Showing content with the highest reputation on 05-02-2019 em todas as áreas
-
Olá pessoal, Para quem ainda não conhece, o Lazarus/FPC é uma poderosa IDE e compilador da Linguagem Object Pascal, muito semelhante ao Delphi, e desenvolvido totalmente em Código Aberto... ( Saiba mais em: https://www.lazarus-ide.org/index.php?page=about ) Hoje ocorreu o lançamento da versão 2.0.0 do Lazarus... O anúncio oficial, pode ser lido no fórum do Lazarus: http://forum.lazarus-ide.org/index.php/topic,44161.0.html Essa versão ainda usa o FPC (Free Pascal Compiler), na versão 3.0.4, então não devemos ter mudanças brusca na compilação dos projetos existentes... Você pode baixar o Lazarus 2.0, na página oficial do Projeto: https://www.lazarus-ide.org/ (Observe porém, que o Download sugerido, provavelmente será de um Compilador para Windows 64... O que muitas vezes não é o desejado, para manter a compatibilidade com as diferentes versões de Windows e as DLLs existentes) Portanto, recomendo selecionar a versão 32 Bits, conforme destacado, na imagem abaixo... Se você quer realmente gerar aplicações 64 bits, ainda poderá fazer um Cross-compiling , baixando um instalador complementar em: https://sourceforge.net/projects/lazarus/files/Lazarus Windows 32 bits/Lazarus 2.0.0/ O ACBr tem um ótimo suporte ao Lazarus/FPC, isso porque a maioria dos Consultores do Projeto ACBr, usam Lazarus/FPC como principal IDE para Desenvolvimento, e todos os nosso projetos, como: ACBrMonitorPLUS, e ACBrLib, são desenvolvidos em Lazarus/FPC. Abaixo segue um Screen Shot da minha IDE de trabalho (clique para aumentar) Quer conhecer mais aplicações desenvolvidas em Lazarus ? Veja esse Link: http://wiki.freepascal.org/Lazarus_Application_Gallery8 pontos
-
Instalando o FixInsight para utilizar no seu projeto Para utilizar o TMS FixInsight no seu projeto, primeiro faça o download da versão trial no site oficial. O FixInsight está disponível para todas as versões do Delphi a partir do Delphi 2006. A versão pro possui linha de comando, permitindo você executar a ferramenta mesmo quando o Delphi não está aberto. Isso permite você integrar com seu sistema de Build ou sistema de integração contínua. A instalação é muito simples, bastando escolher em qual versão do Delphi você quer instalar. Após a instalação as seguintes entradas vão aparecer no menu Project: E também no "Project Manager" (clique com botão direito no projeto): A entrada "FixInsight Settings..." configura a ferramenta e pode habilitar ou desabilitar as mensagens geradas. Ela abre uma tela como essa: Na imagem acima você pode observar que a mensagem "C101 Method '%s' is too long (%d lines)" está selecionada e permite a configuração de quantas linhas para você um método, function ou procedure não deve exceder. Dá pra ver também que as mensagens C102 e C103 estão desabilitadas e assim não geram avisos. A entrada "Run FixInsight for unit1.pas" executa a ferramenta para a unit aberta atualmente (neste caso Unit1.pas). A entrada "Run FixInsight" executa a ferramenta no projeto atual inteiro. Rodando o FixInsight no seu projeto Como mencionado, é por meio da entrada 'Run FixInsight" que você executa a ferramenta no seu projeto. Então basta abrir o seu projeto e executar por meio do menu Project -> Run FixInsight. Ele vai ser executado e abrir uma aba na janela de mensagens como na imagem abaixo. Dois cliques te jogam na unit e linha relacionada a mensagem: Agora é com você. Você analisa a mensagem o código e verifica se algo pode ser feito.6 pontos
-
Foto por David Siglin em Unsplash. Olá pessoal, É bom quando encontramos uma ferramenta que facilita ou melhora nosso trabalho, não? Todos devem ter notado que ultimamente temos enviado vários commits ao SVN de remoção de warnings e hints, muitas vezes mencionando a ferramenta FixInsight. Para quem não conhece, essa ferramenta faz uma análise do seu código e aponta possíveis erros e sugere otimizações. Ela é uma ferramenta muito boa, tanto que foi comprada pela TMS e se tornou TMS FixInsight. Já tem um tempo que conheço a ferramenta e sempre tive o desejo de rodá-la em todo o código do ACBr. Mas devido ao tempo não tinha sido possível. Depois de um incentivo (valeu @Waldir Paim), eu resolvi baixar a versão trial e fazer isso. E que bom que fiz. Gostaríamos de compartilhar com vocês algumas coisas que encontramos no nosso código com a ajuda dessa ferramenta. Encontrando pequenos problemas num código gigante Vamos começar por um código que estava no ACBrValidador. Vejam esse código, onde a função ValidarCEP de baixo chama a função ValidarCEP de cima, e tente encontrar um problema: function ValidarCEP(const ACEP, AUF: String): String; begin Result := ValidarDocumento( docCEP, ACEP, AUF); end; function ValidarCEP(const ACEP: Integer; AUF: String): String; begin ValidarCEP( FormatarCEP(ACEP), AUF ); end; Conseguiu ver o problema? Essa função nunca retornaria que um CEP é inválido se você passasse o CEP como inteiro. Precisava de um “Result := ” no início. Simples? Nem tanto quando lembramos do tamanho do projeto ACBr. Temos mais de 200 componentes e mais de 779 mil linhas de código, contribuídos por dezenas ou talvez centenas de programadores, embora a nossa equipe de commiters seja realmente pequena. Só a unit ACBrValidador.pas em questão tem atualmente cerca de 2070 linhas. Não fica muito mais fácil quando uma ferramenta aponta pra você? [FixInsight Warning] ACBrValidador.pas(294): W521 Return value of function 'ValidarCEP' might be undefined Vamos a outro exemplo no pacote ACBrSerial, componente ACBrECF: [FixInsight Warning] ACBrECFDaruma.pas(4638): W503 Assignment right hand side is equal to its left hand side Veja o código (só a parte interessante): else if StrToIntDef(fsNumVersao, -1) >= 345 then begin RetCmd := EnviaComando( ESC + #240 ); RetCmd := Copy(RetCmd, 92, Length(RetCmd)); RetCmd := RetCmd; //<--- Viu aqui??? for A := 0 to fpAliquotas.Count-1 do begin fpAliquotas[A].Total := RoundTo( StrToFloatDef(Copy(RetCmd,(A*14)+1,14),0) / 100, -2 ); end; end; end; Uma linha que não faz absolutamente nada a não ser gastar espaço, memória e CPU. Uma linha desnecessária a menos no código. E você consegue encontrar um no seu aplicativo código que nunca será executado? Ainda no mesmo pacote, veja esse exemplo: [FixInsight Warning] ACBrECFDataRegis.pas(1838): W509 Unreachable code Nesse código: if (fsArqPrgBcoTXT <> '') and (not FileExists( fsArqPrgBcoTXT )) then begin Msg := ACBrStr( 'Arquivo '+fsArqPrgBcoTXT+' não encontrado. '+ 'Valores padrões serão utilizados.' ) ; raise EACBrECFErro.Create( Msg ); fsArqPrgBcoTXT := '' ; //Essa linha nunca vai ser executada porque tem um raise acima. end ; Mais uma vez, tente imaginar procurar esse problema num projeto tão grande. Não é facilmente percebido se você não tiver olhos treinados e estiver procurando problemas. Vamos a outro exemplo ainda no componente ACBrECF: [FixInsight Warning] ACBrECFEscECF.pas(1222): W517 Variable 'CHK' hides a class field, method or property Veja esse código: procedure TACBrECFEscECFResposta.SetResposta(const AValue: AnsiString); Var Soma, I, F, LenCmd : Integer ; CHK : Byte ; begin O problema desse código é que ele confunde uma variável local (CHK) com uma propriedade da classe (TACBrECFEscECFResposta.CHK). É preciso analisar todo código em cada lugar que isso acontece para ter certeza quando você está se referindo a propriedade e quando é a variável. Imagine se você confunde uma com a outra. Uma hora você pensa que sua variável está recebendo valores estranhos. Outra hora você pensa que sua propriedade não está sendo atualizada. Nesse caso específico, a variável foi renomeada para vCHK evitando a confusão com a propriedade CHK. O importante é que quando você for ler o código, não precise ficar pensando “Isso aqui é uma variável ou uma propriedade?”. Veja outro exemplo, agora no ACBrSMS: [FixInsight Warning] ACBrSMSClass.pas(192): W511 Object 'ListaSMS' created in TRY block begin try Self.Clear; if not FileExists(APath) then raise EACBrSMSException.CreateFmt('Arquivo "%s" não encontrado.', [APath]); ListaSMS := TStringList.Create; ListaSMS.LoadFromFile(APath); if ListaSMS.Count = 0 then Exit; //(bla bla bla...) finally FreeAndNil(ListaSMS); end; Não é apropriado esse código. O correto é mover a criação do objeto para fora do try..finally. Pense bem, se o objeto não for construído, você não quer que ele seja destruído. A mensagem ajudou a perceber também que esse bloco poderia ser escrito de outra maneira. Aquele raise não precisava estar dentro do try..finally. Evitando problemas futuros Rodando no pacote ACBrOpenSSL tivemos a seguinte mensagem no componente ACBrEAD: [FixInsight Optimization] ACBrEAD.pas(268): O804 Method parameter 'AChavePublicaOpenSSL' is declared but never used Quer dizer, parâmetro ‘AchavePublicaOpenSSL’ declarado mas não utilizado. Veja abaixo a a parte importante da função: function TACBrEAD.ConverteChavePublicaParaOpenSSH( const AChavePublicaOpenSSL: String): String; Var Buffer, Modulo, Expoente: AnsiString; {...} begin // https://www.netmeister.org/blog/ssh2pkcs8.html CalcularModuloeExpoente(Modulo, Expoente); Buffer := EncodeBufferSSH('ssh-rsa') + EncodeHexaSSH(Expoente) + EncodeHexaSSH('00'+Modulo); Result := 'ssh-rsa '+ EncodeBase64(Buffer); end; É estranho esse método ConverteChavePublicaParaOpenSSH não utilizar o parâmetro da chavePública. Qualquer pessoa que visse o método e tentasse chamar passando a chave pública não teria o resultado desejado. Analisando o código melhor vemos que o componente lê a chave pública por meio do método “LerChavePublica”. Nesse caso o correto seria remover o parâmetro para que não haja nenhuma confusão. E essa mensagem no TACBrBALToledo2090: [FixInsight Warning] ACBrBALToledo2090.pas(107): W508 Variable is assigned twice successively if (Length(wStrListDados[1]) = 16) then wDecimais := 1000; {APENAS BLOCO PROCESSADO} wResposta := wStrListDados[1]; //<---- sobreposto pela linha seguinte wResposta := Copy(wStrListDados[1], 5, 7); if (Length(wResposta) <= 0) then Exit; Veja que os dados de uma linha é sobreposta pela outra. O compilador nunca daria um aviso sobre isso. Mais dois exemplos de mensagens e o código a seguir: [FixInsight Warning] ACBrEscEpsonP2.pas(97): W514 Loop iterator could be out of range (missing -1?) [FixInsight Warning] ACBrEscEpsonP2.pas(100): W514 Loop iterator could be out of range (missing -1?) For I := 0 to Length(cTAGS_BARRAS) do TagsNaoSuportadas.Add( cTAGS_BARRAS[I] ); For I := 0 to Length(cTAGS_ALINHAMENTO) do TagsNaoSuportadas.Add( cTAGS_ALINHAMENTO[I] ); Essa eu não sei como não foi detectada antes. Por algum motivo não está sendo emitida a mensagem estouro quando o valor de I chega a 16 no primeiro caso e 3 no segundo. Encontrando erros gerados por Ctrl+C..Ctrl+V No pacote ACBrPAF veja a mensagem gerada: [FixInsight Optimization] ACBrPAF_T_Class.pas(137): O804 Method parameter 'ACampo2' is declared but never used function OrdenarT2(const ACampo1, ACampo2: Pointer): Integer; var Campo1, Campo2: String; begin Campo1 := FormatDateTime('YYYYMMDD', TRegistroT2(ACampo1).DT_MOV) + TRegistroT2(ACampo1).TP_DOCTO + TRegistroT2(ACampo1).SERIE + TRegistroT2(ACampo1).NUM_ECF; Campo2 := FormatDateTime('YYYYMMDD', TRegistroT2(ACampo1).DT_MOV) + TRegistroT2(ACampo1).TP_DOCTO + TRegistroT2(ACampo1).SERIE + TRegistroT2(ACampo1).NUM_ECF; Result := AnsiCompareText(Campo1, Campo2); end; Essa função é utilizada para ordenar os registros T2 do PAF. Mas veja que ela compara o registro “ACampo1” com ele mesmo. Suspeita: Ctrl+C e Ctrl+V... Quem nunca??... Outra situação diferente, mas relacionada com ordenação apareceu no ACBrSintegra. Na verdade 4 situações no ACBrSintegra, semelhantes entre si. Vou mostrar apenas uma, mas dessa vez a mensagem do FixInsight fica pra depois. Vamos a um jogo dos sete erros entre os ifs e else no código abaixo: function Sort60A(Item1, Item2: Pointer): Integer; var witem1, witem2 : TRegistro60A; begin witem1 := TRegistro60A(Item1); witem2 := TRegistro60A(Item2); if witem1.Emissao>witem2.Emissao then begin if witem1.NumSerie>witem2.NumSerie then Result:=1 else if witem1.NumSerie=witem2.NumSerie then Result:=0 else Result:=-1; end else if witem1.Emissao = witem2.Emissao then begin if witem1.NumSerie>witem2.NumSerie then Result:=1 else if witem1.NumSerie=witem2.NumSerie then Result:=0 else Result:=-1; end else begin if witem1.NumSerie>witem2.NumSerie then Result:=1 else if witem1.NumSerie=witem2.NumSerie then Result:=0 else Result:=-1; end; end; Conseguiu encontrar os erros? Bem, se você procurou diferenças, não deve ter encontrado nada. E não existe mesmo. Veja a mensagem da ferramenta: [FixInsight Warning] ACBrSintegra.pas(3410): W507 THEN statement is equal to ELSE statement São dois if e um else pra fazer a mesma coisa... A correção foi remover o IFs e ELSE. Agora vamos ao pacote ACBrSPED. Depois de remover muitos e muitos parâmetros desnecessários apontados pelo FixInsight, veja esse código: function CodAjToStr(const AValue: TACBrCodAj): string; begin if AValue = codAjAcaoJudicial then Result := '01' else if AValue = codAjAcaoJudicial then Result := '02' else if AValue = codAjLegTributaria then Result := '03' else if AValue = codAjEspRTI then Result := '04' else if AValue = codAjOutrasSituacaoes then Result := '05' else if AValue = codAjEstorno then Result := '06'; end; A mensagem é a seguinte: [FixInsight Warning] ACBrEPCBlocos.pas(2071): W512 Odd ELSE-IF condition (review lines 2071 and 2073) Viu lá? Os dois primeiros ifs estão comparando AValue com o mesmo valor, "codAjAcaoJudicial". O segundo deveria ser "codAjProAdministrativo". Provavelmente mais um Ctrl+C..Ctrl+V. Mensagens para otimização de código Nem todas as mensagens geradas são de erros. Algumas são mensagens de otimização. Muitos dos commits que temos feito estão relacionados a uma mensagem como estas abaixo: [FixInsight Optimization] ACBrSATClass.pas(776): O801 CONST missing for unmodified string parameter 'CNPJvalue' [FixInsight Optimization] ACBrSATClass.pas(776): O801 CONST missing for unmodified string parameter 'assinaturaCNPJs' Ela pode ser gerada numa função como essa: function TACBrSATClass.AssociarAssinatura( CNPJvalue, assinaturaCNPJs : AnsiString) : String ; begin ...// um código que não altera nenhum dos parâmetros citados end; Essas mensagens estão dizendo que os parâmetros 'CNPJvalue' e ‘assinaturaCNPJs’ do tipo string não estão sendo alterados dentro da função a que eles pertencem. Nesse caso é bem provável que os parâmetros devessem ter um prefixo CONST na sua declaração, como abaixo: function TACBrSATClass.AssociarAssinatura(const CNPJvalue, assinaturaCNPJs : AnsiString) : String ; begin ...// um código que não altera nenhum dos parâmetros citados end; Não vou entrar em muitos detalhes sobre isso, mas usar CONST tem alguns benefícios, principalmente em caso de strings: A execução é mais rápida, porque o compilador pode otimizar o código. No caso de strings, não tem contagem de referências; O compilador garante que você não vai alterar os parâmetros passados gerando um efeito colateral indesejado em quem chamou as funções; O código fica mais legível, porque você pode ler que a intenção é não alterar o parâmetro passado; Como os parâmetros são imutáveis, pode tornar o código mais ThreadSafe; Se quer saber um pouco mais sobre isso, recomendo os seguintes links: All hail the “const” parameters! Is the use of ‘const’ dogmatic or rational? Concluindo... Bom pessoal, ainda temos bastante pra fazer. Contudo, queremos dizer que o FixInsight tem nos ajudado melhorar nosso código. Ficamos tão satisfeitos que entramos em contato com a TMS e eles generosamente nos cederam uma licença da versão Pro pra continuar nosso trabalho. Muito obrigado TMS. Agora, se você quer nossa opinião, essa é uma ferramenta altamente recomendada e está disponível pra toda versão do Delphi a partir do Delphi 2006. Se você tem alguma dúvida, baixe a versão trial e comece agora mesmo a usar no seu código. A versão trial limita as mensagens a 5 por units e funciona por 30 dias. Mas é o suficiente pra se perceber como é muito útil, como aconteceu com a gente. Quer um passo a passo em como utilizá-la? Veja o próximo post logo abaixo.3 pontos
-
Atualização da homologação - Rev. 1: O ACBr é um projeto vivo que recebe atualizações diárias. Essas atualizações, normalmente, envolvem correções e novas funcionalidades. Para acompanhar esta realidade, adição de novos testes e revisão dos existentes são frequentes em novas homologações. Fica evidente também, que homologações antigas necessitam de revisões. Por conta disso, adicionamos nesta postagem, informações adicionais e novos testes comumente encontrado em homologações recentes. Quando houver novas funcionalidades nos componentes ocasionando a necessidade de novos testes, serão feitas novas postagem, no mesmo tópico, informando novos testes realizados com o acréscimo da revisão. Ex.: Rev. 2, Rev. 3 … Rev X. Ambiente: Computador Desktop Sistema Operacional Windows 10 64Bit atualizado (31/01/2019) Processador Intel Core 2 Duo E5400 2.20GHz Memória 2 GB USB 2.0 Testes usando os componentes e Demos do ACBr Utilizamos a versão 3.1.2 do PosPrinterTeste.exe, demo do ACBrPosPrinter, parte do projeto ACBr, para efetuar testes na impressora. A ultima versão do PosPrinterTestes.exe está disponível neste link: Durante os testes deixamos as configurações desta forma: Modelo: ppEscPosEpson; Porta: RAW:ELGIN RM22(USB); Colunas: 32; Espaços: 10; Linhas Pular: 2; Pag. codigo: pc860; KC1: 1; KC2: 0; FatorX: 1; FatorY: 1; Demais configurações não alteramos; Resultados: Logotipo: *Nota: Oficialmente, essa impressora não suporta armazenamento e impressão de logotipos. Contudo, ela suportou, com algumas limitações, os comandos enviados pelo componente ACBrPosPrinter. As limitações que encontramos são: - FatorX não pode ter valor 2. A impressora consegue imprimir, mas a imagem fica cortada. - O logotipo não imprime centralizado ou alinhado à direita. Apenas alinhado à esquerda é suportado. Page Mode: Funcionou, com pequenas limitações, de forma satisfatória. Contudo foi preciso adaptá-la ao tamanho do papel usado: Observações importantes: 1- Onde está escrito 4 posições, demonstra os espaço que sobrou para adicionar algum texto; 2- A propriedade Condensada(<c>) não funcionou para PageModes orientados Topo/Baixo (<mp_direcao>1</mp_direcao>) e Direita/Esquerda (<mp_direcao>2</mp_direcao>); Suporte a impressão de imagens e gravação de logotipos: Realizamos os testes de impressão de imagens e gravação de logotipo na impressora, através de comandos Esc/Pos. Maiores detalhes destas funcionalidades podem ser conferidos neste tópico: ok Impressão de imagem; ok Gravar logotipo na memória da impressora; ok Apagar logotipo na memória da impressora; ok Imprimir logotipo gravado na memória da impressora; Teste de acentuação: Atualizamos o teste de acentuação para demonstrar o suporte da impressora com fontes do Tipo B. Esta funcionalidade está presente na ultima versão do PosPrinterTeste.exe: Resultados: pc473: Alguns acentos circunflexos, crases e todos os til foram ignorados; pc850: Todos os acentos foram impressos corretamente; pc852: Alguns acentos circunflexos, todas as crases e os til foram ignorados; pc860: Todos os acentos foram impressos corretamente; pc1252: - Tipo A: Todos os acentos foram impressos corretamente; - Tipo B: Os caracteres com acentuação não foram interpretados corretamente pela impressora; Impressão de extrato do SAT com QRCode e Logotipo lateral: A impressora suportou os comandos enviados. Contudo, não imprimiu corretamente o cupom. Acreditamos que, o problema esteja na relação entre o tamanho do QRCode e a largura do papel, utilizada pela impressora. Os testes foram realizados com o uso do SATTeste na versão 2.1. Ele é um demo do ACBrSAT, parte do projeto ACBr. Ele está disponível neste link: https://www.projetoacbr.com.br/forum/files/file/316-sattesteexe/ Impressão de um extrato do SAT, com logotipo, usando o SATTeste: Graças a nova funcionalidade, do ACBrPosPrinter, de gravar logotipos na memória da impressora, através de comandos Esc/POS, realizamos a impressão de um extrato de SAT com o tal logotipo:3 pontos
-
Para o CTe-OS você deve usar ACBrCTe.WebServices.EnviaOS. Ou ACBrCTe.Enviar que já executa os métodos de assinatura, validação, envio de acordo com o modelo e impressão do DACTE.3 pontos
-
Boa tarde Suas sugestões foram disponibilizadas nos fontes do Projeto ACBr. Obrigado pela contribuição!2 pontos
-
Boa tarde Waldir, Ajustes disponíveis no SVN, juntamente com outras correções deste banco. Favor atualizar os fontes... Obrigado!2 pontos
-
conf manual qVol Quantidade de volumes transportados tem ocorrência 0-1 e tamanho de 1-15. A regra terá que ser a mesma para homologação e produção. Lembrando que qVol é uma informação requerida pelas transportadoras para emissão de CT-e e MDF-e.2 pontos
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.2 pontos
-
@Italo Jurisato Junior Enviei um e-mail para a prefeitura para verificar as questões do campos faltantes, provisoriamente estou informando manualmente no componente antes da impressão. Agradeço.2 pontos
-
Boa tarde Italo, Após atualização dos fontes as notas puderam ser canceladas com sucesso.2 pontos
-
2 pontos
-
Boa tarde Henrique, Favor atualizar os fontes e refaça os testes. Me parece que configurando com o libCapicom o cancelamento funciona, já com o libWinCrypt não. O motivo é que com o libWinCrypt a assinatura e inserida no lugar errado.2 pontos
-
Boa tarde, Conforme manual este campo é do tipo AlfaNumerico, por isso começa a contar posições a partir da esquerda: copy(Linha, 38, 11) Como está vindo sendo o arquivo de retorno? Se possível anexe aqui.2 pontos
-
O ACBr é Open Source... Já tentou debugar essa rotina ?2 pontos
-
O que é o ACBrPosPrinter e Esc/Pos ? Para quem ainda não conhece, o ACBrPosPrinter é o nosso componente para acesso a Impressoras de Bobinas, Não fiscais... Essas impressoras, denominadas Impressoras POS (Point of Sale), contemplam uma linguagem de impressão de linha, interna, onde podemos realizar tarefas como: Modificar os atributos de impressão Imprimir códigos de barras 1D e 2D (QRCode) Acionar dispositivos ligados a Impressora, como Gaveta de Dinheiro, Guilhotina Ler status da Impressora (Tampa aberta, pouco ou sem papel, etc) No mercado brasileiro, há vários modelos, que contemplam várias linguagens, como por exemplo: EscPos, EscBema, EscDaruma, etc... As linguagens são chamadas de "Esc", pois os comandos geralmente iniciam com o caractere não imprimível, ESC ou #27... Exemplo: se enviarmos para a Impressora a String: chr(27) + 'E' + chr(01), ligaremos o modo Negrito A grande maioria dos fabricantes, procurou seguir o padrão Epson, que é a marca mundialmente líder nesse segmento, e a sua linguagem Epson Esc/Pos... O componente ACBrPosPrinter suporta a grande maioria das linguagens e modelos existentes no mercado brasileiro... mas nem todos os recursos, estão disponíveis em todas as linguagens... Usar o ACBrPosPrinter é extremamente simples, e não requer o conhecimento de Esc/Pos... Através de suas Tags, você pode construir ricos relatórios, com várias formatações de fontes, alinhamento, Imagens, códigos de barra e QRCode... A título de Exemplo, usamos o próprio componente ACBrPosPrinter, para criar o Extrato do SAT, Unit ACBrSATExtratoESCPOS.pas e o DANFCe, unit ACBrNFeDANFeESCPOS.pas Se você usa o ACBrMonitorPLUS, poderá acessar o ACBrPosPrinter pelo objeto ESCPOS... Veja no manual: https://acbr.sourceforge.io/ACBrMonitor/ESCPOSImprimirTags.html Você pode baixar um Demo compilado do ACBrPosPrinter em: Você pode baixar uma Apresentação sobre o ACBrPosPrinter em: Se você não programa em ObjectPascal (Delphi/Lazarus), pode baixar a biblioteca (DLL) ACBrLibPosPrinter em: https://www.projetoacbr.com.br/forum/files/category/35-acbrlibposprinter/ Sobre a Impressão de Imagens no ACBrPosPrinter A muito tempo eu sentia falta dos seguintes recursos, no componente ACBrPosPrinter Impressão de Imagens Gravação e manipulação de Logos na memória da Impressora... Agora isso já é possível... Após muita pesquisa, e com a ajuda de vários outros artigos que encontrei na Internet (veja referência nos fontes), consegui implementar a Impressão de Imagens no modo "Raster Image"... Devido a característica desses equipamentos, apenas a impressão de Imagens monocromáticas é suportada. Existem vários sites de conversão de Imagem, para BMP Monocromático, on-line, como por exemplo: https://online-converting.com/image/convert2bmp/ Novos métodos no componente ACBrPosPrinter procedure ImprimirImagemStream(ABMPStream: TStream); // Permite Imprimir uma Imagem, no formato BMP Monocromático, de um Stream procedure ImprimirImagemArquivo(ArquivoBMP: String); // Carrega e imprime uma Imagem de um Arquivo. Em aplicações visuais (não console) será usado o Objeto TPicture, que permite carregar vários formatos de Imagem, podendo ser Colorida ou em Escala de cinza. A Imagem será convertida para BMP Monocromática. Entretanto, procure sempre usar Imagens BMP Moncromáticas, para evitar processamento desnecessário procedure ImprimirImagemRasterStr(const ARasterStr: AnsiString; AWidth, AHeight: Integer); // Imprime uma Imagem a partir de uma String no formato "Raster Image" (veja abaixo) procedure ImprimirLogo(AKC1: Integer = -1; AKC2: Integer = -1; AFatorX: Integer = -1; AFatorY: Integer = -1); // Imprime um Logo préviamente gravado na memória da Impressora. Se os parâmetros não foram informados, serão usados os valores de ACBrPosPrinter.ConfigLogo procedure GravarLogoStream(ABMPStream: TStream; AKC1: Integer = -1; AKC2: Integer = -1); // Grava uma Imagem de Logo, no formato BMP Monocromático, a partir de um Stream, nas posições informadas. Se os parâmetros não foram informados, serão usados os valores de ACBrPosPrinter.ConfigLogo procedure GravarLogoArquivo(ArquivoBMP: String; AKC1: Integer = -1; AKC2: Integer = -1); // Grava uma Imagem de Logo, a partir de um arquivo em Disco, nas posições informadas. Se os parâmetros não foram informados, serão usados os valores de ACBrPosPrinter.ConfigLogo procedure ApagarLogo(AKC1: Integer = -1; AKC2: Integer = -1); // Remove um Logo da memória da Impressora. Se os parâmetros não foram informados, serão usados os valores de ACBrPosPrinter.ConfigLogo Nova Tag de Bloco <bmp> - Imprime Imagem BMP monocromática. Conteúdo pode ser: Path da Imagem, Stream em Base64 ou AscII Art (0 e 1) Veja alguns exemplos de uso: Inicializa </zera>, define o alinhamento no centro </ce>, e efetua a impressão da Imagem em disco, no Path "C:\temp\acbrmono.bmp" </zera></ce><bmp>C:\temp\acbrmono.bmp</bmp> Imprimir uma Imagem de BMP Mono, codificada em Base64 <bmp> Qk3eDQAAAAAAAD4AAAAoAAAA+gAAAG0AAAABAAEAAAAAAKANAAAAAAAAAAAAAAIAAAAAAAAAAAAAAP///wD/////////////////////////////////////////wP/////////////////////////////////////////A/////////////////////////////////////////8D/////////////////////////////////////////wP4AAAAAAAAAAAAAAA8A8AAAAAAAAAAAAAAAAAAAAD/A/AAAAAAAAAAAAAAADwD4AAAAAAAAAAAAAAAAAAAAD8D4AAAAAAAAAAAAAAAPAHwAAAAAAAAAAAAAAAAAAAAHwOAAAAAAAAAAAAAAAA8APgAAAAAAAAAgAAAAAAAAAAHAwAAAAAAAAAAAAAAADwAfAAAAAAAAAcAAAAAAAAAAAcDAAAAAAAAAAAAAAAAPAA+AAAAAAAAfgAAAAAAAAAAAwIAAAAAAAAAAAAADgAQAB8AAAAAAAH+AAAAAAAAAAABAgAAAAAAAAAAAAACAAAABAAAAAAAAAAAAAAAAAAAAAEAAAAAADDvjnnNn489ngHw4zM+cPM/MD8w7PO4AAAAAAAAAAAAMN+e/c2fn7+/A/nzMz9x+z8wP7Hd27gAAAAAAAAAAAA/2ZnNzZ2YO7ODGxszf3ODOzAxsdx7uAAAAAAAAAAAABmZmc3Nj7gfs4cDGzN/c4MfMDO4ffu4AAAAAAAAAAAAH5mYzd2BmYOzBwObuzNzmxMwPzgdg7gAAAAAAAAAAAAfGb55+5+fHx4HAfP/Pn3zHzAzvvz7uAAAAAAAAAAAAA8AGAAAAAAAAAO4AAAAAAAAMDOAAAA4AAAAAAIAAAAADwAIAAAAAB4AA/AAAMAAAwAwPwAAA7gAAAABAgAAAAAAAAAAAAAAADwA4A+H/4AADwAAAAAAAAAAAAEDAAAAAAAAAAAAAAAAPAAAB//4AAAfAAAAAAAAAAAAAwOAAAAAAAAAAAAAAAA8AAAD/8AAAB4AAAAAAAAAAAAHA8AAAAAAAAAAAAAAADwAAAH/AAAAHAAAAAAAAAAAAA8D4AAAAAAAAAAAAAAAPAAAAPAAAAA4AAAAAAAAAAAAHwP4AAAAAAAAAAAAAAA8AAAAAAAAAHgAAAAAAAAAAAB/A/////////////////////////////////////////8D/////////////////////////////////////////wP/////////////////////////////////////////A/////////////////////////////////////////8D///////gAP///Af////gA//////+Af//4B///////wP///+AAeAB4AB4D+AAB/ADwAAAAf+B4AHgH///////A////4AA4AHgAHgfgAAB+APAAAAAH8HgAeAf//////8D////wADgAeAAeD4AAAB8A8AAAAAHweAB4B///////wP////AAPABwABw+AAAAB4DwAAAAAHx4AHgH///////A////+AA///AAPD4AAAAHwPAAAAAAPHgAeAf//////8D////4AB//8AA4eAAAAAHg8AAAAAAeeAB4B///////wP////wAH//wAHj4AAAAAeDwAAAAAB54AHgH///////A/////AAf/+AAePAAAAAA8PAAAAAADngAeAf//////8D////8AAAAAADx4AAAAAD48AAAAAAPeAB4D///////wP////wAAAAAAPHAAAAAAHjwAAAAAA94AHgP///////A/////gAAAAAA48AAP8AAOPAAP/gAB3gAeA///////8D////+AAAAAADjwAB/4AA48AA//AAH+AB4D///////wP////8AAAAAAe+AAP/wADzwAD/+AAf4AHgf///////A/////wAAAAAB/4AB8PgAPPAAOf4AB/gAeB///////8D/////AAAAAAP/AAHgfAAc8AA7zgAH+AB4H///////wP////+AAAAAA/8AA8A8AP7wAD/+AAd4AHg////////A/////4AAAAAD5wADgBwH/vAAP/4AD3gAeD///////8D/////wAH/AAePAAOAHB/+8AA//AAPeAA4P///////wP/////AAf8ABw8AA4Af/8DwAD/gAA54ADg////////A/////8AB/gAPDwAHgB//APAAAAAAHngAPH///////8D/////4AH+AA8PAAeAD+AA8AAAAAA+eAAf////////wP/////gAf4ADw8AB4APgADwAAAAAHx4AB/////////A/////+AA/gAf7wAHgAwAAPAAAAAA+HgAH////////8D/////8AD8AB//AAeAAAAA8AAAAAfweAAHP///////wP/////wAHwAH/8AB4AAAADwAAAAB+B4AAAf///////A//////gAfAA8fwAHgA4AAPAAAAAB8HgAAA///////8D/////+AB4ADwPAAOAH+AA8AAAAADweAAAD///////wP/////4ADgAeA8AA4Af/gDwAAAAAHh4AAAP///////A//////wAMAB4BwADgB//+PAAP/AAPHgAgAf//////8D//////AAwAHAHAAPAHP/+8AA/+AA8eACAB///////wP/////+ADAA8AcAAfx8A/7wAD/4ADx4AMAD///////A//////4AEADgB4AB//gAPPAAODgAHHgA4AP//////8D//////gAQAOAHgAD/+AA88AA8+AAeeADwB///////wP//////AAAB4AOAAH/gADjwAD/4AB5////////////A//////8AAAHgA8AAP8AAOPAAP/gAHn///////////8D//////wAAA8ABwAAAAAB48AA/wAAef///////////wP//////gAADwAHgAAAAAPDwAAAAABwAAH/////////A//////+AAAOAAOAAAAAA8PAAAAAAPAAAf////////8D//////8AAB4AA+AAAAAHg8AAAAAA8AAD/////////wP//////wAAHgAB4AAAAA8DwAAAAADgAAf/////////A///////AAA8AAD4AAAAHwPAAAAAA/AAD/////////8D//////8AADwAAPgAAAA+A8AAAAAD+AAP/////////wP//////4AAPAAAfgAAAHwDwAAAAAf4AB//////////A///////gAA4AAAfgAAB+APAAAAAHzwAP/////////8D///////AAHgAAA/gAAfwA8AAAAD/PgA//////////wP/////////8AAAB////8AD//////wfAH//////////A//////////wAAAB////gAP//////88A//////////8D//////////gAAAB///4AB////////4H//////////wP//////////AAAAAP/wAAHgAAAAB//w///////////A//////////+AAAAAAHAAA8AAAAAAf/n//////////8D//////////8AAAAAAcAAHwAAAAAAB////////////wP//////////4AAAAABwAAeAAAAAAAAf///////////A///////////wAAAAAHAADwAAAAAAAA///////////8D///////////gAAAAAcAAeAAAAAAAAH///////////wP///////////AAAAABwAD4AAAAAAAA////////////A////////////AAAAAHAAeAAAAAAAAH///////////8D///////////8AAAAAeAD4AAAAAAAA////////////wP///////////4AAAAB4APAAAAAAAAH////////////A////////////4AAAAHgB4AAAAAAAB////////////8D////////////wAAAAeAPAAAAAAAAP////////////wP////////////wAAAB4B8AAAAAAAD/////////////A/////////////gAAAHgHgAAAAAAAf////////////8D/////////////AAAAOA8AAAAAAAD/////////////wP/////////////AAAA4HwAAAAAAA//////////////A//////////////AAADgeAAAAAAAP/////////////8D//////////////AAAPHwAAAAAAD//////////////wP//////////////AAA8eAAAAAAA///////////////A///////////////AADz4AAAAAAH//////////////8D///////////////AAPeAAAAAAD///////////////wP///////////////gA/4AAAAAA////////////////A////////////////wD/AAAAAA////////////////8D////////////////wH4AAAAAP////////////////wP////////////////4fAAAAAH/////////////////A//////////////////8AAAAP/////////////////8D//////////////////8AAA///////////////////wP/////////////////////////////////////////A/////////////////////////////////////////8D/////////////////////////////////////////wA== </bmp> Imprimir uma Imagem, baseado em ASCII ART Na Unit ACBrImage.pas, do pacote ACBrComum, é onde a mágica acontece... essa Unit implementa os seguintes métodos function IsPCX(S: TStream; CheckIsMono: Boolean = True): Boolean; // Retorna True se o Stream contém uma Imagem em PCX function IsBMP(S: TStream; CheckIsMono: Boolean = True): Boolean; // Retorna True se o Stream contém uma Imagem em BMP procedure RasterStrToAscII(const ARasterStr: AnsiString; AWidth: Integer; InvertImg: Boolean; AscIIArtLines: TStrings); // Converte uma String codificada em "Raster Image", para ASCII ART procedure AscIIToRasterStr(AscIIArtLines: TStrings; out AWidth: Integer; out AHeight: Integer; out ARasterStr: AnsiString); // Converte uma String codificada em ASCII ART para "Raster Image" procedure BMPMonoToRasterStr(ABMPStream: TStream; InvertImg: Boolean; out AWidth: Integer; out AHeight: Integer; out ARasterStr: AnsiString); // Converte uma Imagem no formato BMP Monocromático, gravada em um Stream, para uma String codificada em "Raster Image" procedure RasterStrToBMPMono(ARasterStr: AnsiString; AWidth: Integer; InvertImg: Boolean; ABMPStream: TStream); // Converte uma String codificada e "Raster Image", para uma Imagem no formato BMP Monocromático, gravando-a em um Stream {$IfNDef NOGUI} procedure BitmapToRasterStr(ABmpSrc: TBitmap; InvertImg: Boolean; out AWidth: Integer; out AHeight: Integer; out ARasterStr: AnsiString; LuminosityThreshold: Byte = C_LUMINOSITY_THRESHOLD); // Apenas disponível se a aplicação não for console. converte uma Imagem de um TBitMap, para uma String codificada e "Raster Image" {$EndIf} Use a força, leia os fontes Não deixe de estudar os fontes do Projeto Demo, PosPrinterTeste, na pasta: \ACBr\Exemplos\ACBrSerial\ACBrPosPrinter\Delphi Nesse projeto há vários exemplos de como Imprimir Imagens, e manipular Logotipos, usando as Tags e Métodos do componente ACBrPosPrinter O que é o modo "Raster Image" ? O Modo Raster é um fluxo de Bytes que representam os Pixels da Imagem... https://pt.wikipedia.org/wiki/Raster Exemplo: Imagine a Seguinte imagem, de 16 x 16 Pixels... Se fôssemos representá-la em ASCII ART, teríamos: 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 Para transformá-la em Raster, agrupamos os Bits, em Bytes (8 bits)... portanto a primeira linha ficaria: Em Binário: 10101010 + 10101010 Em Hexa: AA + AA Em Decimal: 170 + 170 Então a String em Raster Image, da Imagem acima seria o equivalente a: #170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170 Para imprimir uma String em Raster, é fundamental sabermos qual a largura em Pixels, da imagem A Epson disponibiliza utilitário, para converter imagens para o formato Raster: Epson BmpToRaster (o estudo do conteúdo do arquivo gerado por esse Utilitário, foi essencial na implementação dos métodos de ACBrImage)1 ponto
-
Não tenho ideia se a SEFAZ valida o regime da empresa. Essa é uma boa pergunta, e é provável que precise ser tirada com um contador. Vou mencionar o que eu penso que pode ser a resposta. As situações citadas me parecem gerar um novo documento, ou pelo menos, uma alteração do documento. Como as notas devem ser informadas com enfoque no declarante, é possível que seja no enquadramento atual da empresa.1 ponto
-
Boa tarde, jjw.roberto. A melhor maneira de você descobrir, é entrando em contato com a homologadora que você faz... Digo isso, porque já participei de várias homologações que cada certificadora solicitava uma coisa diferente. Mas na legislação informa que não pode ficar no mesmo lugar que possui ECF instalado.1 ponto
-
Suas sugestões foram disponibilizadas nos fontes do Projeto ACBr. Obrigado pela contribuição!1 ponto
-
Boa tarde Adicionado ao SVN correção sugerida, mantendo validações anteriores para não haver quebra de compatibilidade, pois algumas Cooperativas deste banco continuam validando versão anteriores. Obrigado1 ponto
-
Boa tarde Suas sugestões foram disponibilizadas nos fontes do Projeto ACBr. Obrigado pela contribuição!1 ponto
-
Realmente é confuso... a documentação do fabricante, não deixa clara, essa dependência das DLLs1 ponto
-
Deu certo. O meu problema era o cNf que estava sendo passado igual ao nNf. Obrigado. É uma pre-venda mesmo, mas já contém a chave da nota que será gerada (Tentando agilizar o processo). Isso também será utilizado no caso de uma contingência. Obrigado1 ponto
-
Boa Tarde, Italo! Verifiquei no site e o evento é o dia inteiro todos dias, menos o dia 18 que é abertura, fica dificil para participar como trabalho sozinho. vou esperar mais perto para ver se consigo ir. tem que confirmar presença ate o dia 13/02.1 ponto
-
Boa tarde, Rafael Machado. Está faltando você informar o elemento 'pag', pois o mesmo está vazio1 ponto
-
Boa tarde. O @José M. S. Junior ficou de analisar. Att.1 ponto
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.1 ponto
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.1 ponto
-
Bom.. em teoria esses equipamentos passam por rigorosos testes de certificação... Veja como está descrito no Manual da Especificação SAT, 2_26_4, pag 78 o que dá a entender que Zero é permitido...1 ponto
-
Bom dia, Segue unit corrigida. Aguardo atualização no svn. ACBrEFDBloco_C_Class.pas1 ponto
-
Prazo para implementação das alterações para CTe/CTe-OS trazidas pela NT 2018.002 v1.001 conforme resumo a seguir: Permitir relacionar NF-e emitida por emitente pessoa física com inscrição na relação de documentos transportados; Inclusão do grupo de informações do responsável técnico pelo desenvolvimento do sistema de emissão do DF-e; Inclusão da data/hora da viagem e tipo de fretamento no CT-e OS de transporte de pessoas; Inclusão de validações para o tipo de Serviço e para preenchimento do TAF ou Registro Estadual no CT-e OS Fonte: http://www.cte.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=6NPZPVLwFnw=1 ponto
-
Bom conforme leu acima o código não foi incorporado por existir muitas diferenças. é necessário implementar no fonte atual e anexar novamente1 ponto
-
Por favor, anexe os arquivos alterados para que possa ser analisado.1 ponto
-
Bom dia Milton, Colocou nesse cliente que esta ocorrendo o problema os mesmos schemas de um cliente que não ocorre o problema? Esse cliente é da mesma UF dos demais? O tipo de certificado é o mesmo dos demais? As configurações do componente é a mesma dos demais?1 ponto
-
Maiquel, Se no XML de retorno que é o XML da NFS-e não consta essas informações, então o problema é o provedor que não esta gerando. Favor entrar em contato com o provedor.1 ponto
-
Bom dia, Uma coisa é a configuração do componente, outra coisa é alimentar o componente com os dados da venda. Com certeza você tem na sua aplicação uma procedure que alimenta o componente com os dados da venda, é nessa rotina que você tem que incluir o fragmento de código que postei. Outra coisa, o ambiente de homologação da NF-e só vai estar disponível para os testes a partir do dia 25/02/2019.1 ponto
-
Já consegui resolver! O problema estava em como as bibliotecas estavam sendo compiladas. Ajustando os arquivos .so para EmbeddedNativeLibrary e o .jar para EmbeddedJar tudo ocorreu como planejado. Podem fechar o tópico.1 ponto
-
Bom dia Roberto, A NFS-e Nacional que você se refere é a NFS-e Padrão Nacional (o novo) ou o layout da ABRASF que muitos por ai diz ser o padrão nacional? No momento as prefeituras contratam empresas que chamamos de Provedores. Esses provedores implementam o webservice que vai recepcionar o RPS, gerar a NFS-e e por fim disponibilizar os dados para a prefeitura. Na minha lista tenho por volta de 80 provedores, sendo que 10 tem o seu próprio layout, 35 usam a versão 1 do layout da ABRASF e os outros 35 usam a versão 2 do layout da ABRASF. Se a documentação que você tem se refere a nova NFS-e Padrão Nacional que visa estabelecer um único layout para todas as cidades brasileiras bem como um único webservice, se possível for gostaria de ver essa documentação.1 ponto
-
1 ponto
-
Matou a charada ! Estava com este problema e com esta dica resolveu. Gratidão ! Moacir1 ponto
-
Bom dia O manual do CNAB400 deste banco segue a especificação "A" e "B" para o código de Mora. Talvez então seja necessário adicionar os dois tipos (''AB012'') no construtor. Note que a propriedade "CodigoMora" não está sendo usada no CNAB240, por isso não houve a necessidade de alteração até o momento.1 ponto
-
Arquivo ACBrBoleto.pas com tratamento para evitar erro de conversão; ACBrBoleto.pas1 ponto
-
1 ponto
-
Boa tarde. Recomendo que faça o processo em duas operações distintas, numa você realiza a geração dos PDFs e na segunda gera a remessa com todos os titulos. Att.1 ponto
-
Boa Tarde, Só para avisar, essa semana já vou finalizar a atualização do 2240. Assim que eu finalizar e realizar os testes, postarei os fontes aqui. Obrigado!1 ponto
-
Boa tarde Allan, Muito obrigado pela colaboração, estamos analisando, caso esteja tudo OK enviaremos para o repositório.1 ponto
-
Segundo ouvi dizer do pessoal da certificadora isso será apenas mais uma opção à assinatura digital, mas ainda está fase de testes e está dando muitos problemas, tanto que só a Certisign está vendendo e sem ao menos explicar direito como funciona. Acredito que para NFC-e perderá a funcionalidade da emissão em off-line. Acho precoce se preocupar com isso agora, mesmo porque só empresas grandes com muitos pontos de acesso que optarão por isso, ou não.1 ponto
-
Bom dia @Sandro TC Até o momento não é possível a utilização do ACBrNFSe por desenvolvedores Não Pascal, mas acredito que no futuro exista a possibilidade por meio do ACBrLib. Att.1 ponto
-
Notei que muitas das impressoras recém lançadas, e que Emulam Epson Esc/Pos, não estavam funcionando com comando de gravação de logotipo... Investigando o problema, notei que elas não implementam (não são compatíveis) com o comando "GS 8L", função 67 - "Define the NV graphics data (raster format)"... e usam apenas o comando legado "FS q" Fiz um ajuste, para que o comando legado seja usado, dependendo do valor definido em Keycode1 e 2 { Verificando se informou o KeyCode compatível com o comando Novo ou Antigo. Nota: O Comando novo da Epson "GS + '8L'", não é compatível em alguns Equipamentos (não Epson), mas que usam EscPosEpson... Nesse caso, vamos usar o comando "FS + 'q'", para tal, informe: KeyCode1 := 1; KeyCode2 := 0 } Portanto use os valores KeyCode1 := 1 e KeyCode2 := 0 , se a impressora não suportar o novo comando... Os ajustes já estão no SVN, e o Demo do PosPrinterTeste, já foi atualizado na área de downloads do fórum...1 ponto
-
Boa tarde dataol Segue a minha função para tratar as mensagens que correspondem ao cStart....claro que deve estar faltando alguns códigos rescentes, mas já te ajuda FuncaoMotivoNfe.txt1 ponto