Montando Arquivo XML x NF-e

Para quem deseja começar a preparar o sistema da NF-e (Nota Fiscal Eletrônica), aqui vai uma dica muito interessante: como montar parte da estrutura XML
.

É importante lembrar que, a NF-e utiliza muito mais que isso. Não é só a estruturação do arquivo XML que é necessário, mas sim todo processo de validação dos dados, assinatura do arquivo, certificado etc.

Mas aqui falaremos apenas sobre a estrutura inicial do XML.
Neste exemplo a seguir será mostrado como: adicionar um nó; e como adicionar um nó como filho de outro nó.

Breve explicação do que será feito:
>> Vamos declarar uma variável do tipo IXmlNode, ela será chamada de "Root", e será usada por vários procedimentos.

>> Criaremos três procedimentos: CabecalhoXML; Informacao1 e Informacao2.
No CabecalhoXML é onde será criado todo o cabeçalho do arquivo XML.
Em Informacao1 e Informacao2, é onde irá conter os dados que irá compor o arquivo.

>> Criaremos uma função: CriaDirCaminho(const NomeSubDir: string): boolean;
Essa função é para criar uma pasta (no nosso exemplo, será a pasta "TESTE") em um diretório qualquer informado (no nosso exemplo, será no diretório "H", mude para um de sua preferência).

>>E adicionaremos um botão no formulário: nele será colocado informações de entrada e saída do arquivo XML.

Eis o significado de alguns termos que será utilizado na codificação:
XMLDocument1 -> é o componente do XML.
IXmlNode -> é como se fosse o raiz, nele contém os nós filhos do XML.
AddChild -> Adiciona um elemento filho à um nó XML
NodeValue -> Retorna o valor do nó do objeto XML.
Resumindo: na verdade são árvores de nó em qual cada nó é um elemento.

Iniciando o projeto:
Abra o Delphi.
Na aba INTERNET, adicione ao formulário um TXMLDocument.


Adicione um botão, onde será armazenado o código.

Vamos a codificação:
Crie os três procedimentos: procedure CabecalhoXML; procedure Informacao1; procedure Informacao2;
E uma função: CriaDirCaminho(const NomeSubDir: string): boolean;
Declare a variável como global ---> Root : IXmlNode;

Atenção aos códigos:

Esse é o código da função para criar uma Pasta no diretório:
function TForm1.CriaDirCaminho(const NomeSubDir: string): boolean;
var Dir : string;
begin
Dir := 'H:'+'\'+NomeSubDir;

if not DirectoryExists(Dir) then
ForceDirectories(Dir);
end;

Código do procedimento de CabecalhoXML:
procedure TForm1.CabecalhoXML;
var versao : real;
id : integer;
begin
//Transformando "," em "." (vírgula em ponto)
DecimalSeparator := '.';

//Preenchendo variáveis:
id := 12345;
versao:= 1.00;

XMLDocument1.Options := [doNodeAutoIndent];

//Ativa XML
XMLDocument1.Active := True;

//Cabeçalho
XMLDocument1.Encoding := 'utf-8';
XMLDocument1.Version := '1.0';

//Declara o Namespace (se houver)
Root := XMLDocument1.addChild('Delphizinho','http://www.delphizinho.blogspot.com');

//Identificação (se houver)
Root := Root.AddChild('atributos');
Root.Attributes['Id'] := id;
Root.Attributes['versao'] := FormatFloat('0.00', versao);

//Retornando "." para "," (ponto para vírgula)
DecimalSeparator := ',';
end;


Código do procedimento de Informacao1:
procedure TForm1.Informacao1;
begin
//ROOT raiz de informacao1
//AddChild -> Início do nó em informacao1
with Root.AddChild('informacao1') do begin
AddChild('nome').NodeValue := 'Carlos Felizberto Assis';
AddChild('idade').NodeValue := '30';
AddChild('sexo').NodeValue := 'Masculino'
end; //fim de informacao1
end;

Código do procedimento de Informacao2:
procedure TForm1.Informacao2;
begin
//ROOT raiz de informacao2
//AddChild -> Início do nó em informacao2
with Root.AddChild('informacao2') do begin
AddChild('telefone').NodeValue := '(021)5555-5555';
AddChild('celular').NodeValue := '(021)8888-8888';

//AddChild -> Adiciona um nó como filho de outro nó
with AddChild('endereco') do begin
AddChild('rua').NodeValue := 'Rua da Felicidade';
AddChild('numero').NodeValue := 's/n';
AddChild('complemento').NodeValue := 'quadra 5000'
end; //fim de endereco

AddChild('observacao').NodeValue := 'sem observacao';
end; //fim de informacao2
end;

Código do procedimento do Botão:
procedure TForm1.BitBtn1Click(Sender: TObject);
var Nome_Arquivo, Caminho : string;
begin
XMLDocument1.Active := False;
XMLDocument1.XML.Clear;

//Cria pasta Teste1 no diretório H (caso não exista)
CriaDirCaminho('Teste'); //função para criar a pasta Teste

//Preenchendo variáveis:
Nome_Arquivo := ''; //limpa
Nome_Arquivo := 'Teste1'; //Indica nome do arquivo XML
Caminho := ''; //limpa
Caminho := 'H:\Teste'; //Indica caminho a ser gravado o XML

//Chamada do Cabeçalho:
CabecalhoXML;

//Chamada de dados de Informacao1:
Informacao1;

//Chamada de dados de Informacao2:
Informacao2;

//Salva o arquivo XML
XMLDocument1.SaveToFile(Caminho+'\'+Nome_Arquivo+'.xml');

ShowMessage('XML '+Nome_Arquivo+' gerada com sucesso na pasta '+Caminho);
btSair.SetFocus;
end;


Depois de executado o código, o arquivo teste1.xml foi criado (conforme nosso exemplo) no caminho: "H:\Teste".
Dê um duplo clique no arquivo, para visualizá-lo no navegador.

Se for pelo navegador Firefox, basta clicar direto.
Pronto, já está sendo exibido corretamente. Clique nas abas "-" para ocultar e na aba "+" para exibir as informações contidas em cada nó:



Se for visualizar pelo navegador IE, faça:

Serão necessários alguns ajustes, para ele exibir corretamente o XML. Clique na barra amarela:


2- Controle ActiveX, é necessário executar, clique em "Permitir Conteúdo Bloqueado...":


3- Nessa pergunta, responda "SIM":


4- Pronto, já está sendo exibido corretamente. Clique nas abas "-" para ocultar e na aba "+" para exibir as informações contidas em cada nó:


5- Exemplo de algumas informações ocultadas pelas abas:


Fiz testes em alguns navegadores (Safari, Firefox, Chrome, IE), e constatei que o IE e o Firefox são os que o exibem corretamente (em forma identada (com as abas "-" e "+" de controle) e exibe conteúdo do código chamado em xml). Pois os outros mostram a informação direta (somente o resultado final).
----------------------------------------------------------------------------------

Na NF-e este exemplo (da parte do Cabeçalho) ficaria do seguinte modo:
o Root:
Root:= XMLDocument1.addChild('NFe','http://www.portalfiscal.inf.br/nfe');

Definição de Relações. Identificação da NF-e e Versão do Leiaute:
Id:= 'NFe'+chaveNFe; //variável recebe palavra "NFe" + a chave.

Root := Root.AddChild('infNFe');
Root.Attributes['Id'] := id;
Root.Attributes['versao'] := FormatFloat('0.00', versao);

id -> é a chave da NF-e;
versao-> é a versão do aplicativo (conforme o layout estabelece).

Observe, que nesse exemplo, o nó "Delphizinho" é o geral, nele contém: nó "atributos";
O nó "atributos" contém: nó "informacao1" e nó "informacao2";
O nó "informacao2", contém: nó "endereco".

Nos exemplos dos procedimentos Informacao1 e Informacao2, para aplicar à NF-e, é só substituir conforme o layout pede.

Onde obter mais informação sobre XML:
-> Site da W3C http://www.w3c.org/XML/

************************************************
Faça o download do arquivo: XML.rar
************************************************

"Uma viagem de mil léguas começou
com o primeiro passo." Lao Tsé.

Movimentando Objetos Livremente

Hoje, vamos aprender como movimentar (arrastar) qualquer objeto na tela do formulário, utilizando apenas o mouse. Para o objeto ser arrastado em qualquer direção, são necessários alguns ajustes.

Neste exemplo, vamos utilizar uma Label
(TLabel da Paleta Standart) e um Botão (TBitBtn da Paleta Additional).
Nome do formulário será: FMovObj.

>> Vamos precisar de três procedimentos: ControlMouseDown, ControlMouseUp, ControlMouseMove;
>> De uma classe TMoveControle do tipo TControl;
Observação: A classe TMoveControle será declarado em Type.
>> E de três variáveis: moveX, moveY do tipo Inteiro (integer) e mover do tipo (boolean). Essas variáveis são globais.

Definições:
>> Type -> com esta clausula podemos declarar Novos Tipos e/ou Classes.
>> Variáveis Globais -> declaradas da Interface da Unit. Podem ser acessadas por qualquer Unit usuária.

Como o entendimento desse código é um pouco mais complicado, colocarei aqui toda a Unit.

unit uMovObj;

interfaceuses
Classes, Controls, StdCtrls, Forms, Buttons;

type
TFMovObj = class(TForm)

Label1: TLabel;
BitBtn1: TBitBtn;

Label2: TLabel;

{Procedimentos para o objeto se mover}
procedure ControlMouseMove(Sender: TObject; Shift
: TShiftState; X, Y: Integer);
procedure ControlMouseD
own(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

private
{ Private declarations }
public

{ Public declarations }
end;


var
FMovObj: TFMovObj;

{variáveis necessárias}
moveX, moveY: Integer;

mover: boolean;


implementation
{$R *.dfm}

{-----------------------------------------------------
{ Iniciando codificação de Movimen
tação de Objetos.
{-----------------------------
------------------------}
{Mover Componentes RunTime}

type
TMoveControle = class(TControl);


procedure TFMovObj.ControlMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin

moveX := X;
moveY := Y;
mover := True;

TMoveControle(Sender).MouseCapture := True;
end;

procedure TFMovObj.ControlMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);

begin
if mover then begin
with Sender As TControl Do
Begin
Left := X-moveX+Left;

Top := Y-moveY+Top;
End;
end;
end;


procedure TFMovObj.ControlMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin

if mover then begin
mover := False;

TMoveControle(Sender).
MouseCapture := False;
end;

end;

{-----------------------------------------------------
{ Finalizando codificação de Movimentação de Objetos.
{-----------------------------------------------------}

Para que cada objeto que colocamos na tela (Label, Botão) funcione, é preciso linka-los com os procedimentos codificados.

-----------------------
Linkando a Label -> Selecione a Label, e em Eventos faça:

-> No Evento OnMouseDown, selecione a procedure ControlMouseDown.

-> No Evento OnMouseMove, selecione a procedure ControlMouveMove.

-> No Evento OnMouseUp, selecione a procedure ControlMouseUp.

-----------------------
Linkando o Botão -> Selecione o Botão, e em Eventos faça:

-> No Evento OnMouseDown, selecione a procedure ControlMouseDown.

-> No Evento OnMouseMove, selecione a procedure ControlMouveMove.

-> No Evento OnMouseUp, selecione a procedure ControlMouseUp.

Dica Importante: Ao selecionar a procedure no Evento do objeto, dê um duplo-clique na procedure selecionada até que seja exibido o código da procedure na janela da Unit, para que o Delphi reconheça o código a ser linkado.

Exemplo, ao selecionar no Evento OnMouseDown -> a procedure ControlMouseDown, dando um duplo-clique, aparece o código, na janela da Unit:

(selecionando na Janela de Eventos):

(visualizando código):

*********************************************************************
Faça o download do arquivo: Movimentando Objetos.rar
*********************************************************************

"Só fazemos melhor aquilo que repetidamente insistimos em melhorar.
A busca da excelência não deve ser um objetivo e sim um hábito." Aristóteles.