quarta-feira, 31 de março de 2010

Lendo uma NFE - Nota Fiscal Eletrônica (XML) no Delphi 2006.

Este é um artigo que gostei muito de fazer. O Delphi 2006 tem algumas facilidades para mexer com arquivos XML que tornam o trabalho muito fácil, e porque não dizer, divertido. Coloquei no título NFE, mas serve para qualquer XML que você queira importar.
Agora com a demanda de arquivos XML rodando por aí, seja na área fiscal, contábil, e até na área de saúde, ter uma opção para abrir e mapear arquivos XML é imprescindível.
Eu vou mostrar como mapear e abrir um XML no Delphi como se fosse um DataSet. Ou seja, você poderá navegar no arquivo, ver ele em DBEdit e em DBGrid. Depois disso a importação é brincadeira de criança.
O Delphi 2006, e posteriores (não sei exatamente em que versão saiu) possui uma ferramenta chamada XML Mapper, que fica em Tools / XML Mapper.Veja na imagem:

Clique na opção File / Open e abra um arquivo XML, no meu caso abri uma nota fiscal eletrônica. A estrutura do XML vai aparecer no lado esquerdo, clique com o botão direito em algum elemento do XML e use a opção Select All. No grid do meio vão aparecer os elementos do XML. Depois no menu, vá na opção Create / Datapacket from XML. Isso irá preencher o lado direito com as tags do XML e seus respectivos tipos.

Clique no botão “Create and Test Transformation”. O programa abrirá uma DBGrid, com os dados do arquivo XML, tendo como campos as Tags. Isso dá uma prévia do que teremos como resultado final. Feche a tela de teste e clique com o botão direito na tela do meio, e use a opção “Save Transformation”. Isso vai gerar um arquivo XTR, que funciona como um “mapa” para o Delphi abrir um XML como dados.

Para finalizar, vamos fazer isso funcionar. Crie um novo projeto no Delphi, e adicione ao Form1, um TDataSource, um TClientDataSet, um TXMLTransformProvider e um TDBGrid para vermos os dados. Na propriedade DataSet do DataSource1, coloque o ClientDataSet1. Na propriedade ProviderName do ClientDataSet1, coloque XMLTransformProvider1. Na propriedade DataSource do DBGrid1, coloque DataSource1. Clique no + da propriedade TransformRead, do XMLTransformProvider1, e depois em TransformationFile, escolha o arquivo XTR que você criou anteriormente. E em XMLDataFile escolha um arquivo XML, que no casso desse exemplo é uma nota eletrônica. No ClientDataSet mude Active para True e os dados devem aparecer no grid, conforme a figura.

Concluindo, existe uma facilidade muito grande em se trabalhar com arquivos XML no Delphi. E isso vai se tornando cada vez mais útil visto o aumento de uso desse tipo de comunicação.


37 comentários:

  1. diogo, foi muito boa esta dica, mas mesmo assim fica uma dúvida, eu fiz aqui e ele leu, mas como ele interpreta os itens da nota visto q a nota q eu li tem 5 itens, aí ele traz uma linha só... como eu faço pra ler os itens???

    ResponderExcluir
  2. Isso aconteceu porque fiz o mapeamento pela capa da nota, para aparecer um registro para cada item, você deve mapear na tag dos itens. Em sistemas em produção, o que faço é usar um dataset, e portanto um mapeamento para cada parte da nota.

    ResponderExcluir
  3. Diogo, Obrigado pela dica e parabens pela iniciativa de compartilhar informações. É este tipo de atitude que nos fortalece e nos faz cada dia melhores, tanto profissionalmente como pessoal.
    Um abraço.
    Piery Modesto

    ResponderExcluir
  4. Parabéns, me ajudou muito, valeu mesmo!

    ResponderExcluir
  5. Boa noite,

    Fiz o procedimento e deu certo, mas preciso importar todas as NFe (XML) de uma determinada pasta, tem como fazer isso??

    ResponderExcluir
  6. Muito legal, mas tenho uma dúvida.
    O grid exibiu apenas a "capa" da nf.
    Como faço para exibir os ítens(produtos) da nf?
    escrevaparamarcos@hotmail.com

    ResponderExcluir
  7. Eu de novo...
    Resolvi o problema com os ítens.
    Agora, preciso de fazer o caminho inverso: exportar dados de um cds para um arquivo xml no formado da nf eletrônica.
    Alguém pode ajudar?
    escrevaparamarcos@hotmail.com

    ResponderExcluir
  8. Alguem tem algum exemplo de como carregar os itens se tiverem eu agradeço, preciso urgentemente.
    marcos.marcaum@hotmail.com ou suporte@logsistemas.com.br

    Grato.

    ResponderExcluir
  9. Da pra carregar os itens, quando voce for mapear o xml use a tag dos itens no xml ao inves da tag ta nota.

    ResponderExcluir
  10. Marco, pra exportar, o delphi tem um componente TXMLDocument, procure informacoes sobre ele.

    ResponderExcluir
  11. aqui tem um exemplo http://www.caiooliveira.com.br/?p=73

    ResponderExcluir
  12. Parabéns pela dica !
    Reinaldo Holanda

    ResponderExcluir
  13. Diogo, parabéns pelas dicas.
    Preciso importar XML dentro da própria aplicação, sem utilizar o xml mapper. É possível fazer isso?
    Obrigado.

    ResponderExcluir
  14. Thiago, dá pra importar, mas vai ser um processo mais manual.

    ResponderExcluir
  15. kara to me matando fazendo tudo por uma funçao chamada xlstostringgrid(que alias é otima e ja me salvou varias vezes) mas desse geito me cortou 90% do trabalho valeu kara...

    ResponderExcluir
  16. Como faço para mapear apenas os itens ?

    ResponderExcluir
  17. Voce teria que selecionar apenas a tag dos itens para fazer isso, na aba da direita voce também pode excluir as tags que nao vai utilizar

    ResponderExcluir
  18. Olá Diogo!
    em tempo de execução, qdo dou o cds.refresh não acontece nada. O que será que estou fazendo de errado? Ou será que falta alguma coisa? O cod do meu botão é:
    XMLTPDNFe.XMLDataFile := Trim(EdFilename.Text);
    XMLTPItNFe.XMLDataFile := Trim(EdFilename.Text);
    XMLTPDuplicatas.XMLDataFile := Trim(EdFilename.Text);
    cdsDNfe.Refresh;
    cdsItNfe.Refresh;
    cdsDuplicatas.Refresh;

    ResponderExcluir
  19. estou com uma dúvida em relação a exibição dos itens do arquivo xml referente a uma nota fiscal.

    Eu não tenho habilidade com o programa delphi 2006, porém eu conseguir abrir o xml com item no excel 2007, o problema é que eu não consigo importar vários arquivso de uma só vez.

    Meu objetivo é abrir varios arquivos xml com item, e colocar todas notas fiscais em uma tabela dinâmica no excel, é possível?

    Me ajuda nessa missão.


    Obrigado pela atenção!!


    Ats.,

    Daniel Pereira
    DANIELNP19@HOTMAIL.COM

    ResponderExcluir
  20. Diogo, parabens pelo artigo.

    Estou com o mesmo problema do amigo acima. Gostaria de importar todos os itens de várias NF-e para um banco de dados.
    Não gostaria de importar de uma a uma. Tem alguma forma de importar várias de uma vez???

    Abç,

    Danilo

    ResponderExcluir
  21. Diogo nao vi vc responder a uma pergunta muito comum sobre este assunto, como faco para carregar no dbgrid o conteudo de uma pasta do windows com varios arquivos xml? ex: c:\xml\*.xml

    Voce pode me ajudar com isso?

    Obrigado.

    ResponderExcluir
  22. Olá. desculpem a demora em responder, dá para importar todos ao mesmo tempo sim. primeiramente voce terá que montar a lista em uma string grid dos arquivos. Depois basta fazer um loop para importar os arquivos.

    ResponderExcluir
  23. Boa tarde!

    Desculpe a ignorancia, mas como faço para mapear os itens?

    Sds

    Marcos

    ResponderExcluir
  24. No Delphi 7 n tem esse componente???

    ResponderExcluir
  25. Para mapear os itens voce precisa selecionar um item no XML Mapping Tool. E esse componente eu vi apenas no 2006 para cima, no delphi 7 não tem.

    ResponderExcluir
  26. consegui resolver isso criando dois arquivos .xtr. Um para itens e outro para notas. nao sei se é a forma mais correta, mas funcionou

    Sds

    Marcos

    ResponderExcluir
  27. Agora como faz para carregar vários xml de uma só vez?

    ResponderExcluir
  28. Diogo,

    Estou tentando abrir um XML, pelo Mapper em Tools do delphi7, e está dando uma mensagem:
    "XML Parse Errtor:
    Reason: Declaração xml inválida.

    Error on line 1, position 5"

    linha 1 do arquivo é ""
    poderia me ajudar.

    ResponderExcluir
  29. Ótimo artigo. O XML Mapper está disponível desde o Delphi 7, que aliás eu uso ainda para implementar alguns protótipos de programas que depois serão reformulados em outras linguagens.

    ResponderExcluir
  30. Boa Noite, Voce pode me ajudar como faco para importar os produtos. Nao Consegui entender, tenho o delphi 7.
    Mario Moreira

    ResponderExcluir
  31. Amigos, em casos onde temos produtos que possuem tipos de impostos diferentes como por exemplo um produto cujo CST seja 0-10 e outro como 0-60 o XML cria tags diferentes. Neste caso como criei um .xtr utilizando uma nota que so tinha produtos como cst 0-10 quando mando ler uma nota que contem o CST 0-60 estes dados nao sao mostrados no dataset. Como resolver este caso ?

    ResponderExcluir
  32. Estou com o mesmo problema da CST no item da NF, onde o mesmo pode variar, e o xtr ja fica mapedado com um determinado CST.

    ResponderExcluir
  33. Acredito que a única forma seria criar um modelo XML com todas as possibilidades de CST 00 60 40 etc no mesmo arquivo, assim ele mapeará todos.

    ResponderExcluir