Share Button

[primeira parte]

2. Preparando o Sensor

Escolha o seu sensor entre os vários disponíveis em MySensors – baixe o código e siga as recomendações – pode acreditar… vai funcionar.

Os programas escritos para Arduino seguem o padrão C/C++ (ver mais) e utilizam uma IDE básica com suporte a uma variedade impressionante de processadores da linha ATMEL.

Uma vez instalado a IDE e feito escolha do sensor que irá utilizar o próximo passo será montar a parte eletrônica do sensor ( Arduino + Rádio + Sensor ).sensors

Agora que já tem o código do sensor e a eletrônica montada – é hora de transferir o programa para o arduino – vai encontrar farto material de como fazer isto tanto em MySersors como em  arduino.cc.

Se tudo deu certo… você já tem um sensor funcionando…

 

Até aqui não temos Delphi… na próxima fase vamos trabalhar o Gateway.

 

[continua]

 

Share Button

Uma solução popular para integração de IoT é fazer uso da plataforma Arduino como base de aquisição de dados de campo.

Para alguém que nasceu enfiado no código, como eu, a eletrônica parece se uma barreira – esquece… isto era antes de Arduino.

“Arduino, palavra por vezes traduzida ao português como Arduíno, é uma plataforma de prototipagem eletrônica de hardware livre e de placa única, projetada com um microcontrolador Atmel AVR com suporte de entrada/saída embutido, uma linguagem de programação padrão, a qual tem origem em Wiring, e é essencialmente C/C++. O objetivo do projeto é criar ferramentas que são acessíveis, com baixo custo, flexíveis e fáceis de se usar por artistas e amadores. Principalmente para aqueles que não teriam alcance aos controladores mais sofisticados e de ferramentas mais complicadas.” (Wikipédia)

Como plataforma de prototipagem permite infinitas possibilidades de soluções e conexões com sensores e interação com objetos nas mais diversas área da tecnologia. Arduino como precursora dos processadores que cabem na palma da mão – praticamente se tornou um padrão de mercado para a indústria, onde já encontramos importantes players se dedicando em lançar produtos/placas com a filosofia disseminada pelo Arduino.

Quando se olha do lado do hardware, encontramos em MySensors uma base de integração bem servida de sensores e atuadores para soluções comuns do dia-a-dia.

Como protocolo MySensors estabelece regras simples de troca de informações por porta SERIAL ou TCP/IP (Ethernet) no PC e Rádio (sem fio) no lado do hardware, que permite receber dados coletados de campos e/ou enviar dados para os sensores de campo utilizando comunicação sem fio (rádio).

Quando um ponto MySensors se comunicam sem si ( entre sensores ), ele utiliza uma estrutura de rede MESH em que estabelece uma relação de recepção dos dados endereçados ao próprio ponto (sensor) e retransmissão do sinal quando
forem informações destinados a outro sensor seu vizinho. De forma colaborativa em uma rede MESH o dado viaja entre os sensores até chegar ao seu mestre principal (gateway-gw) – o que torna cada ponto (sensor) em um repetidor (R) de sinal;

Um sensor envia um dado para o Gateway em formato texto (ex: 12;6;0;0;3;My Light\n) – se o destino/Gateway estiver fora do alcance, o dado é retransmitido pelos vizinhos até chegar ao seu destino final.

Uma variedade de sensores podem ser conectados ao seu Arduino que se comunica com o Gateway usando protocolo MySensors e chega ao PC para gerência, armazenamento e/ou reação comandando novas ordens aos sensores.

[continua…]

Share Button

Quando se trata de eventos o mais comum é encontrar uma propriedade que recebe um ponteiro para um procedimento.

Um tipo de evento comum é

property OnClick:TNotifyEvent ….

Para atribuir o evento ao objeto é preciso construir um procedimento para a classe e associá-lo ao evento do objeto, se você já tentou atribuir um procedimento que não esta ligado a uma classe, já notou que há limitações.

Porque criar um novo procedimento em uma classe que será utilizado em um objeto específico… Com eventos anônimos não precisa. (fontes)

   TMinhaClasse = class(TObjectExt)
   end;
.....

var FObjMinhaClasse:TMinhaClass;
begin
     // definindo o evento anônimo
     FObjMinhaClasse:= TMinhaClasse.create;
     FObjMinhaClasse.onFireEvent := procedure (sender:TObject)
                                      begin
                                               ......
                                      end;
end;
...

// usando o evento anônimo
   FObjMinhaClasse.FireEvent(sender);


 

Recriando TObject


  TObject = class(System.TObject)
  private
    FOnFireEvent: TProc<TObject>;
    procedure SetOnFireEvent(const Value: TProc<TObject>);
    public
      procedure FireEvent;overload;
      procedure FireEvent(Sender:TObject);overload;
      property OnFireEvent:TProc<TObject> read FOnFireEvent write SetOnFireEvent;
   end;

.....
{ TObject }

procedure TObject.FireEvent;
begin
 FireEvent(self);
end;

procedure TObject.FireEvent(Sender: TObject);
begin
 if assigned(FOnFireEvent) then
 FonFireEvent(Sender);
end;

procedure TObject.SetOnFireEvent(const Value: TProc<TObject>);
begin
 FOnFireEvent := Value;
end;

 

Exemplos

Este post foi inspirado no livro do Nick Hodges “Coding in Delphi”

 

Share Button

Estava trabalhando para simplificar o TRESTClient do DataSnap  e implementar alguns recursos que gostaria de ter e não encontrei no componente distribuido com o delphi ( Package para TRESTSocialClient ). Mapear as respostas Array para um TFDDataset primordial para facilitar o desenvolvimento (ex: TRESTSocialClientDataset). E quando não é possível mapear para um Dataset… código+código+bug+complexo…

Quando trabalho com um Servidor REST Datasnap escrito para delphi – a integração é simples utilizando o “Wizard” para criar um projeto REST Client disponível. Quando o servidor REST responde para múltiplas plataformas é imperativo que o servidor envie respostas “padronizadas” que sejam compatíveis com a plataforma que o cliente utiliza. O caminho mais rápido é responder JSON padrão evitando respostas específicas de uma plataforma ou outra.

Exemplo: um método não pode responder com um TDataset.Data como é o indicado pelo Delphi… isto obrigaria que o cliente seja igualmente um Delphi.. Então para manter padrão o método deve responder com um TJSONValue ou TJSONObject.

Tomando por base o Servidor Datasnap do post “FireDAC – Datasnap” onde publica o método  GetCliente/{cnpj} (http://localhost:8080/datasnap/rest/TServerMethods1/GetCliente/123456) que retorna:

{"result":[{"cliente":[{"RowId":1,"codigo":1,"nome":"Embarcadero SA","cidade":"Sao Paulo","estado":"SP","endereco":"Rua…xxxx…,10","debitos":100000.12},{"RowId":2,"codigo":2,"nome":"Embarcadero SA2","cidade":"Sao Paulo","estado":"SP","endereco":"Rua…xxxx…,10","debitos":100000.12}],"adicional":[{"codigo":1,"nome":"Exemplo 2"}]}]}

Nas andanças pelos BLOGs de MVPs encontrei um projeto “Introducing JsonToDelphiClass” que aponta para o repositório com o código do projeto.

O projeto JsonToDelphiClass permite que a representação JSON de retorno do servidor DataSnap seja colado no espaço para texto indicada e usar o botão de geração da Unit contendo a classe Delphi para a representação JSON.

As classes geradas pelo projeto possuem um método que fornecendo o código de retorno do servidor – popula o objeto delphi – facilitando a conversão da estrutura JSON para Classe.

class function FromJsonString(AJsonString: string): T... (criar a classe e popula)

.

Passando aquele retorno do Servidor, veja como ele construiu as classes para a representação JSON:

unit JsonRestServer;

//  *************************************************
//    Generated By: JsonToDelphiClass - 0.65
//    Project link: https://github.com/PKGeorgiev/Delphi-JsonToDelphiClass
//    Generated On: 2016-04-10 15:41:06
//  *************************************************
//    Created By  : Petar Georgiev - 2014
//    WebSite     : http://pgeorgiev.com
//  *************************************************

interface

uses Generics.Collections, Rest.Json;

type

TAdicionalClass = class
private
  FCodigo: Extended;
  FNome: String;
public
  property codigo: Extended read FCodigo write FCodigo;
  property nome: String read FNome write FNome;
  function ToJsonString: string;
  class function FromJsonString(AJsonString: string): TAdicionalClass;
end;

TClienteClass = class
private
  FRowId: Extended;
  FCidade: String;
  FCodigo: Extended;
  FDebitos: Extended;
  FEndereco: String;
  FEstado: String;
  FNome: String;
public
  property RowId: Extended read FRowId write FRowId;
  property cidade: String read FCidade write FCidade;
  property codigo: Extended read FCodigo write FCodigo;
  property debitos: Extended read FDebitos write FDebitos;
  property endereco: String read FEndereco write FEndereco;
  property estado: String read FEstado write FEstado;
  property nome: String read FNome write FNome;
  function ToJsonString: string;
  class function FromJsonString(AJsonString: string): TClienteClass;
end;

TResultClass = class
private
  FAdicional: TArray<TAdicionalClass>;
  FCliente: TArray<TClienteClass>;
public
  property adicional: TArray<TAdicionalClass> read FAdicional write FAdicional;
  property cliente: TArray<TClienteClass> read FCliente write FCliente;
  destructor Destroy; override;
  function ToJsonString: string;
  class function FromJsonString(AJsonString: string): TResultClass;
end;

TRootClass = class
private
  FResult: TArray<TResultClass>;
public
  property result: TArray<TResultClass> read FResult write FResult;
  destructor Destroy; override;
  function ToJsonString: string;
  class function FromJsonString(AJsonString: string): TRootClass;
end;

implementation

{TAdicionalClass}


function TAdicionalClass.ToJsonString: string;
begin
  result := TJson.ObjectToJsonString(self);
end;

class function TAdicionalClass.FromJsonString(AJsonString: string): TAdicionalClass;
begin
  result := TJson.JsonToObject<TAdicionalClass>(AJsonString)
end;

{TClienteClass}


function TClienteClass.ToJsonString: string;
begin
  result := TJson.ObjectToJsonString(self);
end;

class function TClienteClass.FromJsonString(AJsonString: string): TClienteClass;
begin
  result := TJson.JsonToObject<TClienteClass>(AJsonString)
end;

{TResultClass}

destructor TResultClass.Destroy;
var
  LclienteItem: TClienteClass;
  LadicionalItem: TAdicionalClass;
begin

 for LclienteItem in FCliente do
   LclienteItem.free;
 for LadicionalItem in FAdicional do
   LadicionalItem.free;

  inherited;
end;

function TResultClass.ToJsonString: string;
begin
  result := TJson.ObjectToJsonString(self);
end;

class function TResultClass.FromJsonString(AJsonString: string): TResultClass;
begin
  result := TJson.JsonToObject<TResultClass>(AJsonString)
end;

{TRootClass}

destructor TRootClass.Destroy;
var
  LresultItem: TResultClass;
begin

 for LresultItem in FResult do
   LresultItem.free;

  inherited;
end;

function TRootClass.ToJsonString: string;
begin
  result := TJson.ObjectToJsonString(self);
end;

class function TRootClass.FromJsonString(AJsonString: string): TRootClass;
begin
  result := TJson.JsonToObject<TRootClass>(AJsonString)
end;

end.

 

 

 

Share Button

Construindo o Servidor RESTServer com exemplos… retornar um TDataset em um JSONObject X “Reflection”.

Para iniciar utilizei o modelo criado pelo delphi: new -> Datasnap REST Application. Criado o projeto alterei a unit abaixo:

GIT com fontes para as dependências


unit ServerMethodsUnit1;

interface

uses System.SysUtils, System.Classes, System.Json,
  Data.FireDACJSONReflect,
  Datasnap.DSServer, Datasnap.DSAuth, Datasnap.DSProviderDataModuleAdapter,
  FireDAC.Stan.StorageJSON, FireDAC.Stan.StorageBin;

type
{$METHODINFO ON}
  TServerMethods1 = class(TDataModule)
    FDStanStorageJSONLink1: TFDStanStorageJSONLink;
    FDStanStorageBinLink1: TFDStanStorageBinLink;
  private
    { Private declarations }
  public
    { Public declarations }
    // original criado pelo DELPHI
    function EchoString(Value: string): string;
    function ReverseString(Value: string): string;

    // passa o codigo do cliente e retorna os dados do cliente
    function GetCliente(codigo: int64): TJSONValue;  // exemplo retornando um JSONObject
    function GetCliente2(codigo: int64): TFDJSONDataSets;  // usando Reflection

    // retorna na mesma resposta CLIENTE + ITENS
    function GetNotaFiscal(ANumero: integer): TFDJSONDataSets;

  end;
{$METHODINFO OFF}

implementation

{$R *.dfm}

uses System.StrUtils, FireDAC.ObjectDataSet, Data.db.helper;

function TServerMethods1.EchoString(Value: string): string;
begin
  Result := Value;
end;

function TServerMethods1.ReverseString(Value: string): string;
begin
  Result := System.StrUtils.ReverseString(Value);
end;

Criando as classes a serem carregadas no TDataset usando RTTI:

type
  TClientes = class
  private
    FCodigo: int64;
    FNome: string;
    FCidade: string;
    FDebitos: double;
    FEndereco: string;
    FEstado: String;
    procedure SetCidade(const Value: string);
    procedure SetCodigo(const Value: int64);
    procedure SetDebitos(const Value: double);
    procedure SetEndereco(const Value: string);
    procedure SetEstado(const Value: String);
    procedure SetNome(const Value: string);
  public
    property codigo: int64 read FCodigo write SetCodigo;
    property Nome: string read FNome write SetNome;
    property Cidade: string read FCidade write SetCidade;
    property Estado: String read FEstado write SetEstado;
    property Endereco: string read FEndereco write SetEndereco;
    property Debitos: double read FDebitos write SetDebitos;
  end;

  TNotaFiscalItens = class
  private
    FPreco: double;
    FCodigo: string;
    FQtde: double;
    FNome: string;
    procedure SetCodigo(const Value: string);
    procedure SetNome(const Value: string);
    procedure SetPreco(const Value: double);
    procedure SetQtde(const Value: double);
  public
    property codigo: string read FCodigo write SetCodigo;
    property Nome: string read FNome write SetNome;
    property Qtde: double read FQtde write SetQtde;
    property Preco: double read FPreco write SetPreco;
  end;

Quando o cliente fizer chamada para GetCliente irá passar o código do cliente, internamente o servidor irá procurar no banco de dados e retornar um JSONObject com os dados do cliente. Este processo permite retornar uma informação mais genérica, importante quando os clientes que irão consumir tenham múltiplas linguagens ou múltiplos desenvolvedores que nem sempre serão Delphianos.


function TServerMethods1.GetCliente(codigo: int64): TJSONValue;
// TFDJSONDataSets;
var
  ds: TObjectDataSet;
  cli: TClientes;
begin
  // buscar os dados no banco de dados com codigo passado pelo cliente...

  // resposta para o cliente;

  // meus dados no firedac
  // usei um ObjectDataset somento para não precisar criar uma conexão e um query
  ds := TObjectDataSet.Create(self, TClientes);  // usa RTTI para mapear coluna do TDataset
  try
    ds.Open;
    ds.append;
    with ds do
    begin
      FieldByName('codigo').Value := 1;
      FieldByName('nome').Value := 'Embarcadero SA';
      FieldByName('Endereco').Value := 'Rua...xxxx...,10';
      FieldByName('Cidade').Value := 'Sao Paulo';
      FieldByName('Estado').Value := 'SP';
      FieldByName('Debitos').Value := 100000.12;
    end;
    ds.Post;

    // retorna um JsonObject
    Result := TJSONObject.ParseJSONValue(ds.ToJson);
  finally
    ds.Free;
  end;
end;

Se os clientes que irão consumir o serviço forem sempre RestClient de Delphi, então retornar um objeto mais preparado para a estrutura do RestClient pode ser um opção. Retornando um objetos TFDJSONDataSets aumenta os dados a serem retornados ao cliente mas pode facilitar a implementação para os cliente Delphi.

// retorna um objeto FireDAC JSON  Reflection
// isto estabelece uma boa integração entre aplicativos que usam FireDAC nos clientes.
// se o cliente não for FireDAC... talves seja interessante pensar em retornar um
//   formato mais generico

function TServerMethods1.GetCliente2(codigo: int64): TFDJSONDataSets;
var
  ds: TObjectDataSet;
  cli: TClientes;
begin
  // buscar os dados no banco de dados com codigo passado pelo cliente...

  // resposta para o cliente;
  Result := TFDJSONDataSets.Create;
  // meus dados no firedac
  // usei um ObjectDataset somento para não precisar criar uma conexão e um query
  ds := TObjectDataSet.Create(nil, TClientes);
  try
    ds.Open;
    ds.append;
    with ds do
    begin
      FieldByName('codigo').Value := 1;
      FieldByName('nome').Value := 'Embarcadero SA';
      FieldByName('Endereco').Value := 'Rua...xxxx...,10';
      FieldByName('Cidade').Value := 'Sao Paulo';
      FieldByName('Estado').Value := 'SP';
      FieldByName('Debitos').Value := 100000.12;
    end;
    ds.Post;

    TFDJSONDataSetsWriter.ListAdd(Result, 'CLIENTE', ds);
  finally
    // ds.Free;   -- eh destruido pelo Writer
  end;
end;

Para retornar mais de uma estrutura de informações no mesma chamada, pode-se utilizar TFDJSONDataSets que permite como no exemplo retornar os dados do Cliente e também os dados dos itens da nota fiscal (no exemplo) no retorno da mesma chamada.


// retornando mais de uma tabala na mesma consulta
// retorna  CLIENTE  e ITENS da nota fiscal
function TServerMethods1.GetNotaFiscal(ANumero: integer): TFDJSONDataSets;
var
  ds: TObjectDataSet;
  cli: TClientes;
  dsItens: TObjectDataSet;
  itens: TNotaFiscalItens;
begin
  // buscar os dados no banco de dados com codigo passado pelo cliente...

  // resposta para o cliente;
  Result := TFDJSONDataSets.Create;
  // meus dados no firedac
  // usei um ObjectDataset somento para não precisar criar uma conexão e um query
  ds := TObjectDataSet.Create(nil, TClientes);
  try
    ds.Open;
    ds.append;
    with ds do
    begin
      FieldByName('codigo').Value := 1;
      FieldByName('nome').Value := 'Embarcadero SA';
      FieldByName('Endereco').Value := 'Rua...xxxx...,10';
      FieldByName('Cidade').Value := 'Sao Paulo';
      FieldByName('Estado').Value := 'SP';
      FieldByName('Debitos').Value := 100000.12;
    end;
    ds.Post;

    TFDJSONDataSetsWriter.ListAdd(Result, 'CLIENTE', ds);

    // usa RTTI para mapear o objeto para TFDMemTable
    dsItens := TObjectDataSet.Create(nil, TNotaFiscalItens);
    dsItens.Open;
    itens := TNotaFiscalItens.Create;
    with itens do
    begin
      codigo := '000001';
      Nome := 'Margarina';
      Qtde := 2;
      Preco := 8.5;
    end;
    dsItens.ObjectList.Add(itens);  // adiciona o objeto ao ObjectDataSet

    with itens do
    begin
      codigo := '000002';
      Nome := 'Pao Frances';
      Qtde := 1;
      Preco := 15;
    end;
    dsItens.ObjectList.Add(itens);

    TFDJSONDataSetsWriter.ListAdd(Result, 'ITENS', dsItens);

  finally
    // ds.Free;   -- eh destruido pelo Writer
  end;
end;

.....
end.

Share Button

Clone de ObjectDataset-JEDI para FireDAC….

Encontra-se no GIT o código para carregar um TObject ou TClass diretamente em um Dataset.
A implementação faz uso de RTTI para ler as propriedades do objeto e mapeia os tipo para as colunas do TFDMemTable do FireDAC.

Exemplo de uso:


// Exemplo de uma classe para mapear no Dataset
  TMinhaClasse = class
  private
    ....
  published
    property Nome: string read FNome write SetNome;
    property id: integer read Fid write Setid;
    property valor: double read Fvalor write Setvalor;
    property Data: TDatetime read Fdata write Setdata;
    property Dinheiro: Currency read FDinheiro write SetDinheiro;
    property Cliente: double read FCliente write SetCliente;
  end;

.....
uses FireDac.ObjectDataSet;
.....
// iniciando o Dataset com o link da Classe...
var ods:TObjectDataset;
begin
  ods := TObjectDataset.Create(self, TMinhaClasse);
  //DataSource1.DataSet := ods; // associa o Dataset a um Datasource
  ods.Open;
end;

Código Fontes no GIT

Lidando com uma lista externa

A classe mantem uma lista interna com os objetos publicando pela propriedade  TObjectDataset.ObjectList,  se você já possui uma lista externa pode utilizar os métodos:

procedure LoadFromList( AList:TList );   // carrega a lista externa para o TDataset
procedure SaveToList( AList:TList );        //  preeche a lista externa com os dados do TDataset;

Emprestando o exemplo do amigo (Marlon)

   TCliente;
   var
     cli : TCliente;
     ods : TObjectDataSet;
   begin
     cli := TCliente.Create;
     cli.ID := 1;
     cli.Nome := ''Marlon;
     cli.Salario := 123.45;
     cli.Dt_Nasc := Date;
     ods := TObjectDataSet.Create(Self, TCliente);
     ods.Open;
     DataSource1.DataSet := ods;

     // pode acrescentar o registro no Dataset;
     ods.append;
     ods.ObjectToField(cli);   // não precisa fazer free... a lista interna faz a liberação de memoria.
     ods.post;

     // outra opção seria:
     ods.append;
     ods.FieldByname('id').asInteger := 1;
     ods.FieldByName('nome').asString := 'Marlon';
     ...
     ods.post;

 

Contribuição do  Marlon


unit Unit56;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDac.ObjectDataSet,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, Vcl.Mask, Vcl.DBCtrls,
  Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Grids, Vcl.DBGrids;

type

  TCliente = class
  private
    FDt_Nasc: TDate;
    FSalario: Currency;
    FID: Integer;
    FNome: String;
    procedure SetDt_Nasc(const Value: TDate);
    procedure SetID(const Value: Integer);
    procedure SetNome(const Value: String);
    procedure SetSalario(const Value: Currency);
  public
    property ID : Integer read FID write SetID;
    property Nome : String read FNome write SetNome;
    property Salario : Currency read FSalario write SetSalario;
    property Dt_Nasc : TDate read FDt_Nasc write SetDt_Nasc;
  end;


  TForm56 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Button1: TButton;
    DBEdit1: TDBEdit;
    DBEdit2: TDBEdit;
    DBEdit3: TDBEdit;
    DBEdit4: TDBEdit;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    ods : TObjectDataSet;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form56: TForm56;

implementation

{$R *.dfm}

{ TCliente }

procedure TCliente.SetDt_Nasc(const Value: TDate);
begin
  FDt_Nasc := Value;
end;

procedure TCliente.SetID(const Value: Integer);
begin
  FID := Value;
end;

procedure TCliente.SetNome(const Value: String);
begin
  FNome := Value;
end;

procedure TCliente.SetSalario(const Value: Currency);
begin
  FSalario := Value;
end;

procedure TForm56.Button1Click(Sender: TObject);
var
  cli : TCliente;
begin
  cli := TCliente.Create;

  ods.FieldToObject(cli);

  Edit1.Text := IntToStr(cli.ID);
  Edit2.Text := cli.Nome;
  Edit3.Text := CurrToStr(cli.Salario);
  Edit4.Text := DateToStr(cli.Dt_Nasc);

end;

procedure TForm56.Button2Click(Sender: TObject);
var
  cli : TCliente;
begin
  cli := TCliente.Create;

  cli.ID := StrToIntDef(Edit1.Text, 0);
  cli.Nome := Edit2.Text;
  cli.Salario := StrToCurrDef(Edit3.Text,0);
  cli.Dt_Nasc := StrToDateDef(Edit4.Text, Date);

  ods.Insert;
  ods.ObjectToField(cli);
  ods.Post;

end;

procedure TForm56.FormCreate(Sender: TObject);
begin
  ods := TObjectDataSet.Create(Self, TCliente);
  ods.Open;
  DataSource1.DataSet := ods;
end;

end.

 

Share Button

As voltas com código legado…

Encontra-se no GIT o código para carregar um TObject ou TClass diretamente em um Dataset.
A implementação faz uso de RTTI para ler as propriedades do objeto e mapeia os tipo para as colunas do TJvMemoryData do JEDI (depende de ter instalado o JEDI-JvMemoryDataSet).

Clone para FireDAC

Exemplo de uso:


// Exemplo de uma classe para mapear no Dataset
  TMinhaClasse = class
  private
    ....
  published
    property Nome: string read FNome write SetNome;
    property id: integer read Fid write Setid;
    property valor: double read Fvalor write Setvalor;
    property Data: TDatetime read Fdata write Setdata;
    property Dinheiro: Currency read FDinheiro write SetDinheiro;
    property Cliente: double read FCliente write SetCliente;
  end;

.....
uses Data.ObjectDataSet;
.....
// iniciando o Dataset com o link da Classe...
var ods:TObjectDataset;
begin
  ods := TObjectDataset.Create(self, TMinhaClasse);
  //DataSource1.DataSet := ods; // associa o Dataset a um Datasource
  ods.Open;
end;



Código Fontes no GIT