Cadastre-se Revistas DevMedia Cursos
 

Space de Cicero Tadeu Pereira Lima França
Busca Autor


Últimas 20 atualizações de Cicero Tadeu Pereira Lima França

Artigo - Usando Banco de Dados Distribuído e Heterogêneos

Esta série de artigos irá mostrar com usar nosseus softwares o middleware LUCAS-GABRIEL, que tem a finalidade deaumentar a escalabilidade do SGBD através da distribuição horizontal dos dados.

 

Apresentação

Sistemas que entram em produção tendem a perderdesempenho após um determinado tempo. Algumas vezes essa perda de desempenho estárelacionada com consultas de dados mal elaboradas, mas na maioria das vezes oproblema está relacionado a sobrecarga que os servidores de dados sofrem com oaumento dos dados armazenados.

Na tentativa de resolver este problema aCASSIC está desenvolvendo o middleware LUCAS-GABRIEL. Este middlewareefetua a distribuição horizontal dos dados entre instâncias distintas deSGBDRs, mas sem interferir diretamente sobre o processamento dos SGBDRs.

 

Artigo_Figura_01.png

Figura 1 – Arquitetura do LUCAS-GABRIEL

 

Esta solução impacta diretamente sobre acomunidade de programadores e softhouses, pois o LUCAS-GABRIEL tem a pretensãode ser independente do banco de dados e da linguagem de programação utilizada,o que diminui significativamente a curva para a interoperabilidade entresistemas feitos em linguagens distintas e banco de dados heterogêneos, cenáriocomum nas empresas da atualidade. Existem outras soluções para este problema,mas diferentemente do LUCAS-GABRIEL, elas são direcionadas para um banco dedados ou linguagem de programação especifica.

Já foram feitos teste iniciais emlaboratório e alguns teste em ambiente de produção controlado, nos dois casosforam obtidos bons rendimentos. Agora estamos colocando ele a disposição dacomunidade para que todos avaliem e dêem feedbacks. A intenção da CASSIC édesenvolver um middleware que seja GRATUITO e CONFIÁVEL.

Com a finalidade de apresentar e divulgar acomunidade, será apresentado uma série de artigos mostrando as funcionalidadesdo LUCAS-GABRIEL em conjunto com o Delphi. Esperamos que apreciem e dêem seusfeedbacks sobre o produto.

 

Preparando os Bancos de Dados

Foi dito anteriormente que o LUCAS-GABRIEL “tema pretensão de ser independente do banco de dados”, mas para efetuar osprimeiros testes e avaliarmos melhor o desempenho do banco de dados, nestaprimeira versão beta só foi implementada a conexão com o Firebird. Colocadaesta explicação, vamos a construção do banco de dados.

Abaixo seguem os comandos DDLs para acriação das tabelas que serão usadas para mostrar as funcionalidades do LUCAS-GABRIEL.

 

create table Cliente(
  ID integer not null primary key,
  Nome varchar(50),
  Limite_Credito numeric(15,2)
);

create table Produto(
  ID integer not null primary key,
  Descricao varchar(50),
  Vr_Venda numeric(15,2)
);

create table PDV(
  ID integer not null primary key,
  Dt_Venda date,
  ID_Cliente integer,
  foreign key(ID_Cliente) references Cliente(ID)
);

create table PDV_Item(
  ID integer not null primary key,
  Quant numeric(15,3),
  Vr_Unit numeric(15,2),
  ID_PDV integer,
  ID_Produto integer,
  foreign key(ID_PDV) references PDV(ID),
  foreign key(ID_Produto) references Produto(ID)
);

 

Devido o LUCAS-GABRIEL efetua a distribuiçãohorizontal, estes mesmos comandos DDLs devem ser repetidos para cadainstância do SGBD. Se desejar, pode efetuar a cópia de todo o banco de dadospara as máquinas onde os SGBDs estão instanciados. É importante ter em menteque na distribuição horizontal, as mesmas tabelas e colunasexistentes numa instância do SGBD devem existir nas outras instâncias.

 

Instalação do LUCAS-GABRIEL

Os arquivos necessários para usar oLUCAS-GABRIEL podem ser baixados de http://www.cassic.com.br/carregar/produtos/lucas_gabriel.

 

Observação:Osistema que vai ser desenvolvido para testar o LUCAS-GABRIEL será citado desteponto por diante como Sistema Cliente.

 

Na máquina onde ficará Sistema Clientenão é instalado nenhum driver de conexão com o SGBD, nela deve-secolocar apenas o arquivo “LUCAS.dll” que está dentro do arquivo baixado.

Numa máquina entre o Sistema Clientee os SGBDs deve ser instalado o aplicativo GABRIEL junto com o arquivo“Midas.dll”. Nesta máquina também devem ser instalados os drivers clientedo SGBDs, pois o aplicativo GABRIEL é visto pelos SGBDs com um sistema clientecomum.

 

Configuração do LUCAS-GABRIEL

O arquivo “LUCAS.dll” será configuradodentro do Sistema Cliente. Mas o aplicativo GABRIEL requer configuraçõesmanuais.

A figura 2 mostra a aparência do aplicativoGABRIEL quando ele for inicializado pela primeira.

 

Artigo_Figura_02.png

Figura 2 – Aplicativo GABRIEL nãoconfigurado

 

Para configura o aplicativo GABRIEL siga ospassos abaixo:

1.  Na“Caixa de edição Porta” informe a porta e na seqüência clique no “BotãoSetPorta”. Nossa configuração usou a porta “1010”, mas a sua porta pode serdiferente.

2.  Na“Caixa de edição Servidor” informe o nome do servidor, na “Caixa deedição Endereço” informe o endereço do banco de dados, em seguida clique nobotão “Botão SetServidor”, repita este processo para todos osservidores. A nossa configuração usou 3 servidores de banco dedados e ficou como mostrado abaixo, ela serve de exemplo para a suaconfiguração:

a.   Servidor: Servidor_01
Endereço: 192.168.56.20:\Documents andSettings\Windows-VB\Desktop\BancoDados_1.FDB

b.   Servidor: Servidor_02
Endereço: 192.168.56.30:\Documents andSettings\Windows-VB\Desktop\BancoDados_2.FDB

c.    Servidor: Servidor_03
Endereço: 192.168.56.40:\Documents andSettings\Windows-VB\Desktop\BancoDados_3.FDB

3.  Na“Caixa de edição Tabela” informe o nome da tabela que será distribuídaentre os bancos de dados, na “Caixa de edição Chave” informe o nome doatributo da tabela que deve ser tratada como chave primária, e na “Caixa deedição Gerador” informe o número que será usado como valor de inicializaçãoda chave primária. Na seqüência clique no “Botão SetTabela”, repitaeste processo para todas as tabelas. Para seguir os exemplos desteartigo, a sua configuração deve ficar igual a nossa:

a.   Tabela: Cliente                 Chave:ID     Gerador: 0

b.   Tabela: Produto      Chave:ID     Gerador: 0

c.    Tabela: PDV           Chave:ID     Gerador: 0

d.   Tabela: PDV_Item  Chave:ID     Gerador: 0

 

Artigo_Figura_03.png

Figura 3 – Aplicativo GABRIEL configurado

 

Criando o Formulário Principal do Projeto SistemaCliente

Crie um novo projeto, modifique apropriedade Name do formulário para FPrincipal. Insirana seção interface da Unit o código que estádestacado com a cor vermelha.

 

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TFPrincipal = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    ArqResposta: string;
  end;

  procedure LUCAS_SetAtivarSoquete(Ativar: Boolean);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetPorta(Porta: Integer);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetMediador(Endereco: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetResposta(Endereco: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetConfiguracao(Porta: Integer; EnderecoMediador,
    EnderecoResposta: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetTabela(Tabela: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetChaveEstrangeira(Tabela, Campo: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetDados(Campo, Valor: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_Clear;
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_ClearChaveEstrangeiraTudo;
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_ClearChaveEstrangeira(Tabela, Campo: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_ClearDadosTudo;
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_ClearDados(Campo: string);
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetSocketAtivo: Boolean;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetSocketAtivar: Boolean;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetPorta: Integer;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetMediador: string;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetResposta: string;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetTabela: string;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetChaveEstrangeira: string;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetDados: string;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetPendente: Integer;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetStatusDescr(var Status: string): Integer;
    stdcall; external 'LUCAS.dll';
  function LUCAS_GetStatus: Integer;
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetIncluir(Requisitar: Boolean);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetAlterar(Condicao: string; Requisitar: Boolean);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetExcluir(Condicao: string; Requisitar: Boolean);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetConsultar(Condicao: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetConsultarSQL(ComandoSelect: string);
    stdcall; external 'LUCAS.dll';
  procedure LUCAS_SetRequisitar;
    stdcall; external 'LUCAS.dll';

var
  FPrincipal: TFPrincipal;

 

 

No evento OnShow do FPrincipalentre com o código abaixo:

 

procedure TFPrincipal.FormShow(Sender: TObject);
begin
  // Desativando conexão com o GABRIEL
  LUCAS_SetAtivarSoquete(False);
  // Configurando endereço do mediador
  // Este endereço foi usado no nosso projeto, mas o seu pode ser diferente
  LUCAS_SetMediador('192.168.56.10');
  // Configurando porta de comunicação
  // Esta porta foi a configura na “Caixa de edição Porta” 
  //   do aplicativo GABRIEL, mas a sua pode ser diferente
  LUCAS_SetPorta(1010);
  // Ativando conexão com o GABRIEL
  LUCAS_SetAtivarSoquete(True);
  // Nome do arquivo de retorno
  // Este nome é padrão e pode ficar numa constante do sistema
  ArqResposta := 'Consulta.xml';  
  // Configurando endereço do arquivo com retorno da consulta
  LUCAS_SetResposta( ExtractFilePath(Application.Exename) );
end;

 

Coloque no formulário um componente TMainMenue configure-o como mostrado na figura 4.

 

Artigo_Figura_04.jpg

Figura 4 – Menu do Sistema Cliente

 

 

Observação:A construção do Sistema Clientefocará o uso do middleware LUCAS-GABRIEL, logo nem sempre serão usadas as boaspráticas da programação por questões didáticas.

 

Salve o formulário com o nome de UPrincipale o projeto com o nome de SistemaCliente.

 

Criando o Formulário FClienteInc

Crie um formulário e configure e coloque oscomponentes solicitados:

 

 

TForm

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
28/11/2011 00:00:00





Artigo - Nota Fiscal Eletrônica – Um caso real – Parte 2g

Nota Fiscal Eletrônica – Um caso real – Parte 2g

 

Continuação da Parte 2f.

Para finalizar a classe de integração TCASSICNFe, os métodos InutilizarNFe e Enviar_eMailNFe são apresentado na listagem abaixo.

 

// Método para gerar o arquivo de solicitação de inutilização de NF-e

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
17/01/2011 16:17:00





Artigo - Nota Fiscal Eletrônica – Um caso real – Parte 2f

Nota Fiscal Eletrônica – Um caso real – Parte 2f

 

Continuação da Parte 2e.

Para finalizar a classe de integração TCASSICNFe, o métodos ImprimirDANFE e CancelarNFe são apresentado na listagem abaixo.

// Método para gerar o arquivo de solicitação de impressão do DANFE

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
17/01/2011 16:13:00





Artigo - Nota Fiscal Eletrônica – Um caso real – Parte 2e

Nota Fiscal Eletrônica – Um caso real – Parte 2e

 

Continuação da Parte 2d.

Na listagem seguinte é mostrado o método responsável por integrar o ERP com o middleware (MercuryMD). Ele cópia para a pasta de solicitação o arquivo gerado pelos métodos GerarNFe (Parte 2b), ImprimirDANFE (Parte 2f), CancelarNFe (Parte 2f), InutilizarNFe (Parte 2g) e Enviar_eMailNFe (Parte 2g). Na seqüência o método fica aguardando o arquivo de retorno gerado pelo middleware para poder processar a resposta.

// Método que integra o ERP ao Mercury-MD

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
17/01/2011 16:06:00





Artigo - Nota Fiscal Eletrônica – Um caso real – Parte 2d

Nota Fiscal Eletrônica – Um caso real – Parte 2d

 

Continuação da Parte 2c.

Continuação do método que gera o arquivo de solicitação para emissão da NF-e (GerarNFe).

Observação:

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
17/01/2011 15:59:00





Artigo - Nota Fiscal Eletrônica – Um caso real – Parte 2c

Nota Fiscal Eletrônica – Um caso real – Parte 2c

 

Continuação da Parte 2b.

Continuação do método que gera o arquivo de solicitação para emissão da NF-e (GerarNFe).

Observação:

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
17/01/2011 15:54:00





Artigo - Nota Fiscal Eletrônica – Um caso real – Parte 2b

Nota Fiscal Eletrônica – Um caso real – Parte 2b

 

Continuação da Parte 2a.

Na listagem seguinte é apresentada a primeira parte do método que gera o arquivo de solicitação para emissão da NF-e (GerarNFe). Embora o método seja grande, ele é simples, pois basicamente ele captura os dados da nota fiscal persistida no ERP e formata o arquivo de solicitação no mesmo local do aplicativo.

Observação1:

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
17/01/2011 15:43:00





Artigo - Nota Fiscal Eletrônica – Um caso real – Parte 2a

Nota Fiscal Eletrônica – Um caso real – Parte 2a

 

Após apresentar o middleware que criamos para integrar ERPs com NF-e (Nota Fiscal Eletrônica – Um caso real) recebi alguns e-mails pedindo ajuda na integração. De uma maneira geral a integração é simples, mas para os que haviam pedido ajuda lhes enviei uma classe de integração criada no Delphi, o que reduz ainda mais a curva de integração entre o nosso middleware e o ERP.

A classe que será apresentada é utilizada pelos nossos ERPs para fazer a emissão de NF-e via middleware. Embora o arquivo da classe seja grande, ela é bem simples e auto-explicativa. Mas caso exista alguma dúvida, por favor, nos comunique.

Na listagem abaixo é apresentado a declaração da classe TCASSICNFe e das constantes PathNFeIn e PathNFeOut. Estas duas constantes informam a classes TCASSICNFe onde colocar o arquivo de solicitação que será consumido pelo middleware (PathNFeIn) e onde o middleware irá colocar a reposta da solicitação feita (PathNFeOut).

Na mesma listagem é apresentado o construtor da classe (Create), o método que buscará o ID do município que será usado na geração da NF-e (MunicID) e o método que retorna a descrição do status da solicitação feita ao middleware (StatusNFe).

Observação:

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
17/01/2011 15:22:00





Artigo - Nota Fiscal Eletrônica – Um caso real

Nota Fiscal Eletrônica – Um caso real

 

Nossa empresa estar inserida numa região que comporta o terceiro pólo calçadista do país. No final de 2009 inicio de 2010 várias indústrias precisaram inserir nos seus ERPs a emissão da NF-e. Entre essas empresas estavam alguns clientes nossos. Além das indústrias de calçado outros clientes atacadistas e varejistas também precisavam emitir NF-e.


Com mais de um sistema para ser integrado com a NF-e passamos por um questionamento:

- Como minimizar o trabalho de manutenção dos ERPs para integrá-los a NF-e?


A resposta que encontramos foi a criação de um middleware que faça todo o processo de integração da NF-e com o mínimo de alteração em sistemas legados.


O middleware foi pensado e construído visando nos nossos sistemas legados em Delphi, e já preparado para, se preciso, integrá-lo com nossos sistemas legados feitos em outras linguagens.


...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
13/12/2010 12:55:00





Artigo - Transferência de dados através de arquivos .txt - Parte VII

Transferência de dados através de arquivos .txt - Parte VII

Projeto para receber os dados (cont.)


Código para receber o arquivo de transferência

Vamos colocar o código necessário para receber e gravar os dados que estão no arquivo de transferência.  No evento OnShow do formulário coloque a Listagem 6, depois dê um clique duplo no BtnRec insira a Listagem 7 no evento OnClick.

 

procedure TFRec.FormShow(Sender: TObject);

begin

  PnlStatus.Caption := 'Status : Sem Processo';

end;

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
05/10/2010 17:33:00





Artigo - Transferência de dados através de arquivos .txt - Parte VI

Transferência de dados através de arquivos .txt - Parte VI

Projeto para receber os dados

 

Agora devemos criar um projeto para receber o arquivo que foi gerado.  Assim como o projeto anterior deixaremos ele simples, para que possa, caso deseje, colocar essa rotina em um projeto seu com poucas alterações.

No novo projeto mude as seguintes propriedades do formulário:

 

Propriedade

Valor

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
05/10/2010 17:23:00





Artigo - Transferência de dados através de arquivos .txt - Parte V

Transferência de dados através de arquivos .txt - Parte V



Iniciando um novo projeto para transmitir os dados (cont.)


Entrando com código para gerar o arquivo de transferência (cont.)


Para formatar a data e a hora de acordo com o layout usamos a função FormatDateTime do próprio Delphi, como vista na Listagem 1 é bem simples, ela requer dois parâmetros, o primeiro parâmetro é formato de saída desejado e o segundo parâmetro é a Data e/ou Hora que será formatado.

Já para remover o separador decimal dos valores numéricos e fixar os tamanhos desejados para alfanuméricos e numéricos criamos duas funções com os respectivos nomes de RemoverChar e PreencherStr.  Essa função tem que ser declaradas no Private declarations do formulário (Listagem 2).

 

Type

  TFTransf = class(TForm)

    BtnGerar: TBitBtn;

    PBarGerar: TProgressBar;

    SQLConnec: TSQLConnection;

    SQLQuery: TSQLQuery;

    DataSetProv: TDataSetProvider;

    ClientDataSet: TClientDataSet;

    procedure BtnGerarClick(Sender: TObject);

  private

    { Private declarations }

    // Declare as duas funções criadas para esse exemplo aqui

    function PreencherStr(StrEntrada: string; CharPreencher: Char;

      TamRetorno: Integer; LeftPreencher: Boolean): string;

    function RemoverChar(StrEntrada: string; CharRemover: Char): string;

  public

    { Public declarations }

  end;

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
01/07/2010 13:37:00





Artigo - Transferência de dados através de arquivos .txt - Parte IV

Transferência de dados através de arquivos .txt - Parte IV



Iniciando um novo projeto para transmitir os dados (cont.)


Entrando com código para gerar o arquivo de transferência

 

Agora para concluir o programa de transferência de dados devemos entrar com o código que irá gerar o arquivo desejado de acordo com o layout proposto.  Dê um clique duplo no BtnGerar para criar o evento OnClick.  Dentro do evento coloque a Listagem 1.

* Todo o código está comentado para melhor compreensão.

 

procedure TFTransf.BtnGerarClick(Sender: TObject);

var

  // Variável do tipo arquivo

  ArqTransf: TextFile;

  Cont, Lin, Reg1, Reg2: Integer;

begin

  /////////////////////////////////////////////////////////////

  //                                                         //

  // Lembrete : Serão adotados os formatos  preestabelecidos //

  //   no layout                                             //

  //                                                         //

  // Obs. : Para identificar que dados estamos informando    //

  //   colocaremos apenas os nomes dos campos informados no  //

  //   layout criado                                         //

  //                                                         //

  /////////////////////////////////////////////////////////////

 

  // Inicializando os contadores

  Lin := 0;

  Reg1 := 0;

  Reg2 := 0;

 

  // Informando a variável ArqTransf o

  // nome do arquivo que será gerado

  AssignFile(ArqTransf, 'Transf.txt');

 

  // Inicializando o arquivo de transferência

  Rewrite(ArqTransf);

 

  // Incrementando o contador de linhas

  Inc(Lin);

 

  // Incluindo uma nova linha no arquivo de transferência

  // Registro Tipo 0

  WriteLn(ArqTransf,

    // Tipo

    '0' +

    // DtGera

    FormatDateTime('yyyyymmdd', Now) +

    // HsGera

    FormatDateTime('hhmmss', Now) +

    // Versão

    '1.0.0' +

    // Brancos

    PreencherStr(' ', ' ', 170, False) +

    // Linha

    PreencherStr(IntToStr(Lin), '0', 5, True ));

 

  // Abrindo a conexão com a base de dados

  SQLConnec.Connected := True;

 

  ///////////////////////////////////////

  //                                   //

  // Inicio da transferência dos dados //

  //                                   //

  ///////////////////////////////////////

 

  // Quando a variável "Cont" for igual a 1 estaremos utilizando a

  // tabela "Cliente".  Quando o seu valor for 2 passaremos a usar

  // a tabela "Produto"

  // Cont = 1 --> Tabela Cliente

  // Cont = 2 --> Tabela Produto

  for Cont := 1 to 2 do

    begin

      // Abrindo tabela de cliente

      SQLQuery.SQL.Clear;

      case Cont of

        // Utilizando a tabela "Cliente"

        1:SQLQuery.SQL.Add('select * from Cliente');

        // Utilizando a tabela "Produto"

        2:SQLQuery.SQL.Add('select * from Produto');

      end;

 

      // Para melhor compreenção não utilizarei o "with ClientDataSet do"

      ClientDataSet.Active := False;

      ClientDataSet.Active := True;

 

      // Preparando o TProgressBar para mostrar o progresso

      // da transferência dos dados

      PBarGerar.Position := 0;

      PBarGerar.Max := ClientDataSet.RecordCount;

 

      // Entra no loop dos registros da tabela atual

      // até chegar no fim do arquivo - Eof (End of file)

      while not(ClientDataSet.Eof) do

        begin

          // Incrementando o contador de linhas

          Inc(Lin);

 

          case Cont of

            // Utilizando a tabela "Cliente"

            1:begin

                // Incrementando o contador do Registro Tipo 1

                Inc(Reg1);

 

                // Incluindo uma nova linha no arquivo de transferência

                // Registro Tipo 1

                WriteLn(ArqTransf,

                  // Tipo

                  '1' +

                  // Codigo

                  PreencherStr(ClientDataSet.FieldByName('Codigo').AsString,

                    '0', 5, True) +

                  // CPF

                  PreencherStr(ClientDataSet.FieldByName('CPF').AsString,

                    ' ', 14, False) +

                  // Nome

                  PreencherStr(ClientDataSet.FieldByName('Nome').AsString,

                    ' ', 50, False) +

                  // Endereço

                  PreencherStr(ClientDataSet.FieldByName('Ender').AsString,

                    ' ', 50, False) +

                  // Bairro

                  PreencherStr(ClientDataSet.FieldByName('Bairro').AsString,

                    ' ', 30, False) +

                  // Cidade

                  PreencherStr(ClientDataSet.FieldByName('Cidade').AsString,

                    ' ', 30, False) +

                  // UF

                  PreencherStr(ClientDataSet.FieldByName('UF').AsString,

                    ' ', 2, False) +

                  // DtNasc

                  FormatDateTime('yyyyymmdd',

                    ClientDataSet.FieldByName('DtNasc').AsDateTime)+

                  // Linha

                  PreencherStr(IntToStr(Lin), '0', 5, True));

              end;

            // Utilizando a tabela "Produto"

            2:begin

                // Incrementando o contador do Registro Tipo 2

                Inc(Reg2);

                // Incluindo uma nova linha no arquivo de transferência

                // Registro Tipo 1

                WriteLn(ArqTransf,

                  // Tipo

                  '2' +

                  // Codigo

                  PreencherStr(ClientDataSet.FieldByName('Codigo').AsString,

                    ' ', 13, False) +

                  // Descr

                  PreencherStr(ClientDataSet.FieldByName('Descr').AsString,

                    ' ', 50, False) +

                  // Valor

                  PreencherStr(RemoverChar(Format('%1.2f', [

                    ClientDataSet.FieldByName('Valor').AsCurrency]),

                    DecimalSeparator), '0', 15, True) +

                  // Brancos

                  PreencherStr(' ', ' ', 111, False) +

                  // Linha

                  PreencherStr(IntToStr(Lin), '0', 5, True));

              end;

          end;

 

          // Pula para o próximo registro da tabela atual

          ClientDataSet.Next;

 

          // Incrementa o TProgressBar

          PBarGerar.Position := PBarGerar.Position + 1;

 

          // Delay apenas para mostrar a evolução do TProgressBar

          // pois os arquivos são muito pequenos e sem ele não veriamos

          // essa evolução.  Sua remoção não causará efeito algum

          // ao resultado final do arquivo de transferência

          Sleep(100);

        end;

    end;

 

  // Incrementando o contador de linhas

  Inc(Lin);

 

  // Incluindo uma nova linha no arquivo de transferência

  // Registro Tipo 9

  WriteLn(ArqTransf,

    // Tipo

    '9' +

    // Reg1

    PreencherStr(IntToStr(Reg1), '0', 5, True) +

    // Reg2

    PreencherStr(IntToStr(Reg2), '0', 5, True) +

    // Brancos

    PreencherStr(' ', ' ', 179, False) +

    // Linha

    PreencherStr(IntToStr(Lin), '0', 5, True));

 

  // Fechando o arquivo de transferência

  CloseFile(ArqTransf);

 

  ShowMessage('Arquivo gerado');

end;

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
01/07/2010 13:34:00





Artigo - Transferência de dados através de arquivos .txt - Parte III

Transferência de dados através de arquivos .txt - Parte III



Iniciando um novo projeto para transmitir os dados

 

Criaremos um novo projeto para a geração do arquivo de transferência, será um programa bem simples, pois ficará mais fácil a colocação da rotina de geração dentro de um projeto, fazendo-se apenas algumas poucas modificações.

Crie um projeto no Delphi, no formulário mude as propriedades:

 

Propriedade

Valor

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
01/07/2010 13:16:00





Artigo - Transferência de dados através de arquivos .txt - Parte II

Transferência de dados através de arquivos .txt - Parte II



Layout

 

Agora que já temos informações a serem transferidas, é necessária a elaboração de algumas regras para gerar o arquivo texto.  Essas regras, que de agora por diante chamaremos apenas de layout, tem que ser compreendida pelos dois aplicativos(o que gerou o arquivo e que irá receber).

Sendo assim vamos criar nosso layout.

 

1.      Regras de formatação de campos

 

1.1.   Campos numéricos (Tipo N) fracionados deverão ser preenchidos por completo, sem nenhum tipo de sinal, sem vírgula e pontos, alinhado a direita e com suas posições a esquerda preenchidas por zeros:

 

Ex1: R$ 1.050,55 com tamanho 15,2(13 caracteres da parte inteira e 2 da decimal) no layout deverá aparecer 000000000105055

Ex2: R$ 78,00 com tamanho 15,2(13 caracteres da parte inteira e 2 da decimal) no layout deverá aparecer 000000000007800

 

1.2.   Campos inteiros (Tipo I) serão similares aos campos numéricos fracionados, apenas não utilizando as casas decimais.

 

1.3.   Campos com datas (Tipo D) tem que estar no formato AAAAMMDD:

 

Ex1: 31/12/2005 tem que ser informado 20051231

Ex2: 01/02/2006 tem que ser informado 20060201

 

1.4.   Campos com tempo (Tipo T) tem que estar no formato HHMMSS:

 

Ex1: 10:30h tem que ser informado 103000

Ex2: 13:25:55h tem que ser informado 132555

 

 

1.5.   Campos alfanuméricos (Tipo A) serão alinhados a esquerda com espaço em branco a direita até ser atingido seu tamanho máximo:

 

Ex1: José da Silva com tamanho 50 deverá “José da Silva                                     ” – sem as aspas

Ex2: Celular XR-60 com tamanho 50 deverá aparecer “Celular XR-60                                     ” – sem as aspas

 

2.      Regras para tipos de registros

 

2.1.   Todos os registros deverão ter obrigatoriamente 195 posições.

 

2.2.   O primeiro dígito indicará o tipo de registro que contém na linha e o cinco últimos a posição do registro no arquivo.

 

Ex1: “100001111.111.111-11Jose da Silva                                     Rua da Flores, 123                                Romeirao                      Juazeiro do Norte             CE1970123100002” – O primeiro dígito é o número 1 o que indica que é um Registro Tipo 1, os cinco últimos números são 00002 informando que o registro está na segunda linha do arquivo

Ex2: “21234567890123Telefone XT-72                                    000000000008399                                                                                                               00006”  - O primeiro dígito é o número 2 indicando que é um Registro Tipo 2, os cinco últimos números são 00006 informando que o registro está na sexta  linha do arquivo

 

2.3.   O registro deverá ser finalizado com carriage return/line feed (CR/LF).

 

2.4.   O arquivo deverá iniciar obrigatoriamente com o Registro Tipo 0 e ser finalizado com o Registro Tipo 9.

 

2.5.   O arquivo só poderá ter apenas um Registro Tipo 0 e um Registro Tipo 9, os Registro Tipo 1 e Registro Tipo 2 pode aparece nenhuma ou varias vezes por arquivo.

 

3.      Descritiva dos registros

 

3.1.   Registro Tipo 0

 

3.1.1. Ocorre uma vez no arquivo, deve ser o primeira registro.   Inicialização do arquivo.  Registro obrigatório.

 

Campo

Descritiva

Tamanho

Tipo

Pos. Inic.

Pos. Final

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
01/07/2010 12:35:00





Artigo - Transferência de dados através de arquivos .txt - Parte I

Transferência de dados através de arquivos .txt - Parte I



Introdução

 

            Um problema encontrado por desenvolvedores é a transferência de dados entre empresas parceiras (Ex.: Pedidos, tabelas de preço, cadastro de cliente, etc) ou entre empresas comerciais e bancos (Ex.: Arquivos de remessa e retorno de valores). 

Embora os arquivos XML sejam utilizados pelos sistemas atuais (Ex.: SNGPC/ANVISA, NF-e) para resolver este problema, existem sistemas legados (Ex.: CNAB/FEBRABAN) que ainda utilizam a geração de arquivos texto seguindo um layout pré-definido por uma ou ambas as partes.

Este artigo não tem a intenção de definir qual a melhor solução, e sim, mostrar como podemos trabalhar com arquivos texto neste contexto.

 


Tabelas utilizadas neste artigo para Transmissão e Recebimentos

 

Crie um banco de dados com o nome ClubeDelphi_Transf.fdb. Neste artigo foi utilizado o Firebrid 2.0, mas fique a vontade para utilizada o SGBD da sua preferência.

 

Tabela Cliente

 

Criando o gerador utilizado pela tabela cliente

create generator Gen_Cliente;

 

Obs1: Criamos esse gerador para acumular o último código usado pelo “Trigger”(Veja mais a frente) no momento de incluir um novo cliente.

 

Criando a tabela cliente

create table Cliente(

  Codigo integer not null,

  CPF char(14) not null,

  Nome varchar(50) not null,

  Ender varchar(50),

  Bairro varchar(30),

  Cidade varchar(30),

  UF char(2),

  DtNasc date

);

 

Obs2: Usamos dois campos para alfanumérico, o varchar e o char. A diferença entre os dois é bem simples.  Um campo varchar(50) está indicando a quantidade máxima de caracteres, mas caso você use apenas um caractere, as outras quarenta e nove posições serão “desprezadas”.  Já um campo char(14) quer dizer que se você incluir apenas um caractere, as outras trezes posições serão preenchidas com espaço.

Obs3: Após a definição do tipo dos três primeiros campos aparece “not null”.  Essa instrução informa ao Firebird que é obrigatório entrar com um valor nos mesmos para cada registro informado, ou seja, não é permitido deixá-los em branco.

 

Criando a chave primaria da tabela cliente

alter table Cliente

add primary key(Codigo);

 

Obs4: Nesse exemplo criamos uma chave primaria simples.  Caso fossemos criar uma chave composta usando, por exemplo, os campo Codigo e CPF bastaríamos, na linha, ter escrito “primary key(Codigo, CPF)”.

Obs5: Embora seja permitido criar a chave primeira junto com a criação da tabela, nesse exemplo criamos a chave primeira depois de termos criado a tabela.  Para criarmos junto com a tabela só seria preciso colocar uma virgula após a definição do campo “DtNasc” e incluir “primary key(Codigo)” como mostrado abaixo:

create table Cliente(

  Codigo integer not null,

  CPF char(14) not null,

  Nome varchar(50) not null,

  Ender varchar(50),

  Bairro varchar(30),

  Cidade varchar(30),

  UF char(2),

  DtNasc date,

  primary key (Codigo)

);

 

Criando o trigger utilizado pela tabela cliente

set term^;

 

create trigger TCliente for Cliente

active before insert position 0

as begin

  new.Codigo = gen_id(Gen_Cliente, 1);

end;

 

Obs6: O Firebird não possui um campo do tipo Autoincremente, mas podemos driblar isso com o uso do “Trigger” como mostrado acima.

Obs7: A linha “create trigger TCliente for Cliente” manda o SGBD criar um “Trigger” com o nome “TCliente” para a tabela “Cliente”.

Obs8: A linha “active before insert” pede que esse “Trigger” seja acionado antes de se inserir um novo registro.  O comando “position 0” informa que caso exista mais de um “active before insert”, esse será o primeiro a ser executado.  Caso existisse um segundo “active before insert” o comando irá aparecer “position 1”.

Obs9: O “begin... end” informa o inicio e o fim de um bloco de código.

Obs10: A linha “new.Codigo = gen_id(Gen_Cliente, 1);” utilize a função “gen_id( )” para incrementar em 1(um) o gerador “Gen_Cliente”(criado anteriormente) e jogar esse valor no campo “Codigo” do novo registro.

 

Tabela Produto

 

Criando a tabela produto

create table Produto(

  Codigo varchar(13) not null,

  Descr varchar(50) not null,

  Valor numeric(15, 2) not null

);

 

Criando a chave primaria da tabela produto

alter table Produto

add primary key(Codigo);

 

            Após ter criado as tabelas, trigger e generators, faça uma cópia da base e renomeia para ClubeDelphi_Rec.fdb, essa base será usada para receber os dados gerados.  Vale ressaltar que embora a base de recebimento seja igual a de transferência(nome das tabelas, campos, tipos e tamanhos), nem sempre isso acontece na vida real.

 


Incluindo Dados na Base de Transmissão

 

            Vamos agora alimentar a base ClubeDelphi_Transf.fdb com alguns registros como mostrado a seguir:

 

Incluindo registros na tabela cliente

 

insert into Cliente(CPF, Nome, Ender, Bairro, Cidade, UF, DtNasc)

values ('111.111.111-11', 'Jose da Silva', 'Rua da Flores, 123', 'Romeirao', 'Juazeiro do Norte', 'CE', '12/31/1970');

commit;

 

insert into Cliente(CPF, Nome, Ender, Bairro, Cidade, UF, DtNasc)

values ('222.222.222-22', 'Maria da Silva', 'Rua Sao Pedro, 234', 'Centro', 'Juazeiro do Norte', 'CE', '02/28/1975');

commit;

 

insert into Cliente(CPF, Nome, Ender, Bairro, Cidade, UF, DtNasc)

values ('333.333.333-33', 'Joao Carvalho', 'Rua Sao Jose, 345', 'Salesianos', 'Juazeiro do Norte', 'CE', '10/01/1980');

commit;

 

insert into Cliente(CPF, Nome, Ender, Bairro, Cidade, UF, DtNasc)

values ('444.444.444-44', 'Joana Alencar', 'Rua Padre Cicero, 456', 'Matriz', 'Juazeiro do Norte', 'CE', '01/10/1985');

commit;

 

Obs11: Não foi informado o campo “Codigo” pois o mesmo será gerado pelo trigger da tabela.

Obs12: Note que a data está no formato MM/DD/AAAA, este é o formato aceito pelo comando insert para data quando se utiliza a barra “/”.

Obs13: Como esses dados são apenas para questões didáticas, os CPF informados são inválidos.

 

Incluindo registros na tabela produto

 

insert into Produto(Codigo, Descr, Valor)

values ('1234567890123', 'Telefone XT-72', 83.99);

commit;

 

insert into Produto(Codigo, Descr, Valor)

values ('2345678901234', 'Celular RM-50', 390.5);

commit;

 

insert into Produto(Codigo, Descr, Valor)

values ('3456789012345', 'Carregador para celular MP-65', 78);

commit;

 

insert into Produto(Codigo, Descr, Valor)

values ('4567890123456', 'Bateria para celular FL-900', 102.05);

commit;

 

insert into Produto(Codigo, Descr, Valor)

values ('5678901234567', 'Celular XR-60', 1050.55);

commit;

 

Obs14: Verifique que usamos o sinal de ponto no lugar da vírgula como símbolo decimal e que o símbolo de agrupamento de dígitos inexiste.

 

Artigo criado por http://www.cassic.com.br/

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
01/07/2010 12:05:00





Artigo - Introdução ao comando SELECT da SQL - Parte III

Introdução ao comando SELECT da SQL - Parte III

Para Programadores

Função avg


 Retorna a média aritmética da coluna informada.

 

Sintaxe :

 

select  avg(Coluna) [as New_Coluna] from  Tabela

 

Tabela                                          Nome da tabela

Coluna                                         Nome de uma coluna

[as New_Coluna]                         Nome da coluna de retorno [Opcional]

 

Exemplo :

 

select avg(Salario) as Media from Funcion

 

Resultado

Media

1071,42

 

Função max

 

Retorna o maior valor da coluna informada.

 

Sintaxe :

 

select  max(Coluna) [as New_Coluna] from  Tabela

 

Tabela                                          Nome da tabela

Coluna                                         Nome de uma coluna

[as New_Coluna]                         Nome da coluna de retorno [Opcional]

 

Exemplo :

 

select max(Codigo) as Maior_Codigo from Funcion

 

Resultado

Maior_Codigo

7

 

Função min

 

Retorna o menor valor da coluna informada.

 

Sintaxe :

 

select  min(Coluna) [as New_Coluna] from  Tabela

 

Tabela                                          Nome da tabela

Coluna                                         Nome de uma coluna

[as New_Coluna]                         Nome da coluna de retorno [Opcional]

 

Exemplo :

 

select min(Codigo) as Menor_Codigo from Funcion

 

Resultado

Menor_Codigo

1

 

Função sum

 

Retorna o somatório da coluna informada.

 

Sintaxe :

 

select  sum(Coluna) [as New_Coluna] from  Tabela

 

Tabela                                          Nome da tabela

Coluna                                         Nome de uma coluna

[as New_Coluna]                         Nome da coluna de retorno [Opcional]

 

Exemplo :

 

select sum(Salario) as Total from Funcion

 

Resultado

Total

7500

 

Função count

 

Retorna a quantidade de registros existentes.

 

Sintaxe :

 

select  count(Coluna) [as New_Coluna] from  Tabela

 

Tabela                                          Nome da tabela

Coluna                                         Nome de uma coluna – Pode ser substituído
pelo “*” (asterisco)

 [as New_Coluna]                        Nome da coluna de retorno [Opcional]

 

Exemplo :

 

select count(Codigo) as QtTotal from Funcion

 

Resultado

QtTotal

7

 

Função distinct

 

Usamos distinct para evitar que um determinado valor seja repetido em uma consulta.

 

Sintaxe :

 

select  distinct(Coluna) from  Tabela

 

Tabela                                          Nome da tabela

Coluna                                         Nome de uma coluna

 

Exemplo :

 

select distinct(Cliente) from Pedido

 

Resultado

Cliente

2

4

5


Cláusula group by

 

Quando queremos agrupar o resultado de uma ou mais funções com os dados de uma ou mais colunas devemos usar o group by.

 

Sintaxe :

 

select  Função, Coluna from Tabela

group by Coluna

 

Tabela                                          Nome da tabela

Função                                        Função a ser unida com a coluna

Coluna                                         Nome de uma coluna

 

Exemplo :

 

select sum(Valor) as Soma, Cliente from Pedido

group by Cliente

 

Resultado

Soma        Cliente

3500        2

2000        4

2500        5

 

Cláusula having

 

Having é utilizada para filtrar o resultado de uma função de agrupamento juntamente com a cláusula group by.

 

Sintaxe :

 

select  Função, Coluna from Tabela

group by Coluna

having Condição

 

Tabela                              Nome da tabela

Função                             Função a ser unida com a coluna

Coluna                             Nome de uma coluna

Condição                         Cria condição para filtrar o resultado da função.

 

Exemplo :

 

select sum(Valor) as Soma, Cliente from Pedido

group by Cliente

having sum(Valor) >= 2500

 


Resultado

Soma        Cliente

3500        2

2500        5

 

Operador de concatenação ( || )

 

Para combinar cadeias de caracteres utilizamos o operador ||.

 

Sintaxe :

 

select  Coluna || [String ||] Coluna [as New_Coluna] from  Tabela

 

Tabela                                          Nome da tabela

Coluna                                         Nome de uma coluna

String                                           String para separar as colunas [Opcional]

[as New_Coluna]                         Nome da coluna de retorno [Opcional]

 

Exemplo :

 

select Nome || ' ' || Sobrenome as Nome_Completo from Cliente

 

Resultado

Nome_Completo

Francisco Silva

José Lima

Maria Silva

Adriana Ferreira

João Oliveira

Eduarda Souza

 

Operadores aritméticos

 

Podemos fazer cálculos com operações aritméticas em qualquer declaração de cláusula SQL, com exceção para a cláusula from.

 

Sintaxe :

 

select  Coluna, Operação_Aritmética [as New_Coluna] from  Tabela

 

Tabela                                          Nome da tabela

Coluna                                         Nome de uma coluna

Operação_Aritmética                  Operação aritmética desejada

[as New_Coluna]                         Nome da coluna de retorno [Opcional]

 

Operadores aritméticos “+” (Adição)

 

Exemplo :

 

select Nome, (Salario + 200) as Salario_Atual from Funcion

 

Resultado

Nome                    Salario_Atual

Tadeu                   1700

Ylane                   1400

Julian                  1200

Ewerton                 1200

João                    1000

Geraldo                 1700

Maria                    700

 

Operadores aritméticos “-” (Subtração)

 

Exemplo :

 

select Nome, (Salario - 200) as Salario_Atual from Funcion

 

Resultado

Nome                    Salario_Atual

Tadeu                   1300

Ylane                   1000

Julian                   800

Ewerton                  800

João                     600

Geraldo                 1300

Maria                    300

 

Operadores aritméticos “*” (Multiplicação)

 

Exemplo :

 

select Nome, (Salario * 1.5) as Salario_Atual from Funcion

 

Resultado

Nome                    Salario_Atual

Tadeu                   2250

Ylane                   1800

Julian                  1500

Ewerton                 1500

João                    1200

Geraldo                 2250

Maria                    750

 

Operadores aritméticos “/” (Divisão)

 

Exemplo :

 

select Nome, (Salario / 2) as Salario_Quinzena from Funcion

 

Resultado

Nome                    Salario_Quinzena

Tadeu                   750

Ylane                   600

Julian                  500

Ewerton                 500

João                    400

Geraldo                 750

Maria                   250

 

Este artigo foi cedido por http://www.cassic.com.br/

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
09/04/2010 16:11:00





Artigo - Recursos do Code Editor

Recursos do Code Editor

 

O Code Editor além das sintaxes coloridas oferece outros recursos tais como:

 

- Class Completion : Após declarar um método, usamos esse recurso para fornecer a definição do mesmo na seção Implementation da Unit, o inverso também pode ser feito, ou seja, após definir o método na seção Implementation o Class Completion cria a declaração.  Outra opção fornecida por esse recurso é o complemento da definição de uma propriedade.

 

Exemplo

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
09/04/2010 11:29:00





Artigo - Conteúdo dos arquivos PAS, DFM e DPR

Conteúdo dos arquivos PAS, DFM e DPR

Conteúdo do arquivo UPrincipal.pas

 

Declaração
da unit

unit UPrincipal;

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
09/04/2010 11:22:00





Artigo - Padrões de Codificação

Padrões de Codificação

Por que usar um padrão de codificação?

 

A organização do código fonte facilita os processos de desenvolvimento, retirada de bugs, atividades de validação e manutenção.  O uso de um padrão de codificação também aumenta a produtividade num projeto, uma vez que a comunicação dentro da equipe de desenvolvimento fica mais fácil, mas vale ressaltar que partes desses padrões são vistas, algumas vezes, como sugestões por empresas que adotam seus próprios padrões.

 

- Comentários : Usamos as chaves - { }- para iniciar e terminar um comentário com mais de uma linha, esse tipo de comentário é comum para se informar dados gerais e específicos de Unit e métodos, vindo no seu inicio.  Dentro dos comentários com chaves não devemos usar asteriscos, símbolos ou caracteres especiais.  Outro tipo de comentário usado é a barra de data digitada duplamente - // - neste caso o comentário se ressume a uma linha, devendo ser dado um espaço após a segunda barra para começar o texto desejado.

 

- Indentação : Ato de separar os níveis de codificação por espaços em branco.  No caso da Linguagem Delphi a indentação deve ter dois espaços, não se podendo usar tabulação.

 

Observação1

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
09/04/2010 11:12:00





 

Mestre em Computação Aplicada; Especialista em Gestão de Projetos de TI; Especialista em Engenharia de Software; Tecnólogo em Automática; Certified ScrumMaster.
Arquivo de atualizações
 2011
 2010

Estatísticas do Autor:
Número de posts: 30
Características dos posts deste autor:
Conteúdo:
Utilidade:
9 1
 
DevMedia Group - Tel: (21) 3382-5038 - www.devmedia.com.br
Todos os Direitos Reservados a DevMedia Group