Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Srs,
Estou com uma dúvida acerca de qual seria a melhor solução para a minha questão que segue:
Tenho um app que captura os xml's de notas fiscais de abastecimento e os "traduz" conforme script abaixo:
LOAD "XML",
TextBetween(XML,'KM:','.') as [NFe Abast - KM],
TextBetween(XML,'PLACA:','KM:') as [NFe Abast - Placa],
TextBetween(XML,'<chNFe>','</chNFe>') as [NFe Abast - Chave de Acesso],
TextBetween(XML,'<vUnCom>','</vUnCom>') as [NFe Abast - Valor Unitario],
len(TextBetween(XML,'<vUnCom>','</vUnCom>')) as [Nfe Abast - Un. Medida],
TextBetween(XML,'<vProd>','</vProd>') as [NFe Abast - Valor Total],
TextBetween(XML,'<uCom>','</uCom>') as [NFe Abast - Un Medida],
TextBetween(XML,'<xProd>','</xProd>') as [NFe Abast - Produto],
TextBetween(XML,'<nNF>','</nNF>') as [NFe Abast - Numero],
TextBetween(XML,'<xNome>','</xNome>') as [NFe Abast - Emitente Razao Social],
TextBetween(XML,'<xFant>','</xFant>') as [NFe Abast - Emitente Nome Fantasia],
TextBetween(XML,'<qCom>','</qCom>') as [NFe Abast - Quantidade],
date(SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1)) as [NFe Abast - Data Emissao],
Year((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Ano Emissao],
Month((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Mes Emissao],
Day((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Dia Emissao],
Time(SubField(SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',2),'-',1),'hh:mm') as [NFe Abast - Hora Emissao],
TextBetween(XML,'<xMotivo>','</xMotivo>') as [NFe Abast - Status]
FROM [lib://CARGA/NOTAS_ABASTECIMENTO.qvd](qvd);
Até aí tudo funciona "de boa" se, e somente se, a nota contiver apenas um item (o que ocorre em 99% dos casos que temos). Esse 1% é que me arrebenta...
Vejam como o xml da NF vem quando há mais de um item:
Eis então minha questão:
Como fazer a leitura desses dois itens, considerando que as tags que utilizo são as mesmas nos dois itens?
cleveranjos, afurtado, stalwar1
Abs e Sucesso!
Bom dia Anderson,
Obrigado pela resposta. Mas por falha minha eu não expliquei bem o meu caso:
Busco na base de dados do nosso ERP todos os xml's que ficam contidos dentro de uma única coluna...ou seja,uma string imensa num só campo. Hoje vou tentar conectar via REST direto com o WebService que fornece ao ERP os xml's, daí sim, usaria poder do Qlik no que tange a carga de xml.
Estou por ora, e contando que talvez eu não consigo conectar via REST, buscando alternativas performáticas para resolver a questão.
Vou tentar agora tratar com outras funções esse campo XML (descrito acima). Tendo novidades compartilho aqui.
Mas esteja à vontade para sugerir outra solução.
Toda ajuda é bem vinda!
Thiago, desculpe o vocabulário, vamos ao tecniquez
Criar um QVW para ler todos os xmls e seus tamanhos;
Categorize-os por normal/anormal
Cria um loop para LOAD com todos os arquivos normais;
Depois um outro loop com LOAD dos demais anormal;
Agora, meu medo é se tiveres outra variações como mais de 2 <det nitem> por arquivo.
A função subfield seria mais prático/ortodoxo.
Ao invés de vc se adpatar ao processo, talvez seja simples a alteração do processo de criação dos XML´s.
Tudo são ideias e formas de atuação, cada uma com um custo diferente.
Abraço
Amigo, tenho uma ideia...
Espero que os parceiros da comunidade não briguem comigo por isso... Rsrs
Qualquer coisa, excluo este post...
Gostaria de tentar outra situação...
Consegue anexar em arquivo QVD, dados de exemplo do XML, contendo um registro com 1 item e o segundo registro com 2 itens?
Claro que sim meu amigo Mario: tá na mão.
As informações contidas nos arquivos não são confidenciais por isso as anexo sem maiores problemas.
Thiago,
Achei sua dúvida desafiadora e resolvi testar algo. Bom cheguei neste load que talvez resolva seu problema:
Para exemplificar gravei o conteudo dos 2 xmls enviados dentro de uma planilha excel para simular o banco de dados.
Ela tem duas linhas e dentro da celula eu colei os XML. (a planilha exemplo está anexada a resposta)
Para resolver o problema combinei a função TextBetween com a dupla (while & iterno) para criar um laço que se repete a cada linha tantas vezes for encontrada a tag </det> , isso determina o numero de itens de uma nf.
O comando while cria uma linha para cada ocorrência da tag </det> desde que seja menor que o total de ocorrências encontradas (resultado do substringcount).
Essa dica vale uns 10.000 pontos aqui na comunidade. Hahahahahaha..
Tai o script.
LOAD
Registro,
//cabeçalho NF
TextBetween(XML,'KM:','.') as [NFe Abast - KM],
TextBetween(XML,'PLACA:','KM:') as [NFe Abast - Placa],
TextBetween(XML,'<chNFe>','</chNFe>') as [NFe Abast - Chave de Acesso],
TextBetween(XML,'<vUnCom>','</vUnCom>') as [NFe Abast - Valor Unitario],
len(TextBetween(XML,'<vUnCom>','</vUnCom>')) as [Nfe Abast - Un. Medida],
date(SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1)) as [NFe Abast - Data Emissao],
Year((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Ano Emissao],
Month((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Mes Emissao],
Day((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Dia Emissao],
Time(SubField(SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',2),'-',1),'hh:mm') as [NFe Abast - Hora Emissao],
TextBetween(XML,'<xMotivo>','</xMotivo>') as [NFe Abast - Status],
TextBetween(XML,'<nNF>','</nNF>') as [NFe Abast - Numero],
TextBetween(XML,'<xNome>','</xNome>') as [NFe Abast - Emitente Razao Social],
TextBetween(XML,'<xFant>','</xFant>') as [NFe Abast - Emitente Nome Fantasia],
//itens NF
TextBetween(det_XML,'<vProd>','</vProd>') as [NFe Abast - Valor Total],
TextBetween(det_XML,'<uCom>','</uCom>') as [NFe Abast - Un Medida],
TextBetween(det_XML,'<xProd>','</xProd>') as [NFe Abast - Produto],
TextBetween(det_XML,'<qCom>','</qCom>') as [NFe Abast - Quantidade];
LOAD Registro,
XML,
TextBetween(XML,'<det nItem','</det>',iterno()) as det_XML
FROM
[Dados XML.xlsx]
(ooxml, embedded labels, table is Planilha1)
while iterno() <= SubStringCount(XML,'det nItem') ;
Por isso que eu adoro script de Qlik !!!!!
Abraço,
Pablo
Poxa... foi mais rápido do que eu... srsrs
Já ia publicar.
Você teve a mesma ideia de usar o while/iterno() ?
Isso...
Realmente é possível fazer muitas coisas com While/InterNo()...
Tenho uns documentos que publiquei utilizando While/InterNo() na lógica, gosto muito:
Somar intervalo de tempo/produção dos recursos | Período útil
Adicionando/Preenchendo intervalo de datas nos eventos
Hehehehehehehe
Inicio a resposta assim pra expressar minha alegria ao rodar o seu script.
Simplesmente fantástico! Leve todos os meus poucos pontos na comunidade, são seus
Pablo,
Fora a brincadeira, eu quero te agradecer imensamente pelo tempo que você gastou elaborando algo tão bom (queria usar outro termo, mas seria falta de educação).
Essa resposta vale 1 milhão de pontos e o dobro em curtidas.
Aprecio sua generosidade em compartilhar conhecimento com simples mortais como eu hehe.
E viva o QLIK!