Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Datasnap: Howto run through a TDataset on clientside


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Jul 14, 2015 9:26 AM Last Post By: Michael Eriksen
Michael Eriksen

Posts: 27
Registered: 6/12/11
Datasnap: Howto run through a TDataset on clientside  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 29, 2015 12:09 PM
Hey all,
I hope that someone can help me.

I have my servermethods as posted below:
procedure TServerMethods.GetEmployeeList(out ADataSet: TDataset);
var
  vQ: TFDQuery;
begin
  vQ := TFDQuery.Create(nil);
  try
    vQ.Connection := FDConnection;
    vQ.sql.Clear;
    vQ.SQL.Add('select * from employees');
    vQ.Open;
    ADataSet := vQ;
  finally
  end;
end;


The servermethods on my datasnap server seems to work fine and results in a dataset as an out parameter.
But how to manually run through all these records in my clientapplication and presents the data into a TStringGrid?

I have tried the following - but without success :-(

procedure TfmEmployee.FormCreate(Sender: TObject);
begin
  with smGetemployeelist do begin
    ExecuteMethod;
    with smGetemployeelist.ParamByName('ADataSet') do begin
      Open;
      First;
      while not Eof do begin
        Next;
      end;
    end;
  end;
end;

I'm using Delphi XE8

Thanks for any advise,
Michael

Edited by: Michael Eriksen on Jun 29, 2015 12:52 PM

Mathias Burbach

Posts: 42
Registered: 12/8/99
Re: Datasnap: Howto run through a TDataset on clientside  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 2, 2015 12:28 AM   in response to: Michael Eriksen in response to: Michael Eriksen
Hello Eric,

I think you don't need to open the dataset any more once it has been returned by the DataSnap server. Here is how I deal with server methods that may return multiple datasets:

procedure TsvmCalendar.GetRules(const DailyCalendarIDs, WeeklyCalendarIDs, MonthlyCalendarIDs, YearlyCalendarIDs: string;
                                out DailyRules, WeeklyRules, MonthlyRules, YearlyRules: TDataSet);
begin
  OpenRule(qryDailyCalendarRule, DailyCalendarIDs);
  DailyRules := qryDailyCalendarRule;
  OpenRule(qryWeeklyCalendarRule, WeeklyCalendarIDs);
  WeeklyRules := qryWeeklyCalendarRule;
  OpenRule(qryMonthlyCalendarRule, MonthlyCalendarIDs);
  MonthlyRules := qryMonthlyCalendarRule;
  OpenRule(qryYearlyCalendarRule, YearlyCalendarIDs);
  YearlyRules := qryYearlyCalendarRule;
end;


And on the client side I use the proxy class
TsvmCalendarClient.GetRules(DailyCalendarIDs: string; 
   WeeklyCalendarIDs: string; 
   MonthlyCalendarIDs: string; 
   YearlyCalendarIDs: string; 
   out DailyRules: TDataSet; out WeeklyRules: TDataSet; out MonthlyRules: TDataSet; out YearlyRules: TDataSet);


to obtain my data in one server call:

procedure TxxxCalendar.GetRulesRemotely(const DailyCalendarIDs, WeeklyCalendarIDs,
                                               MonthlyCalendarIDs, YearlyCalendarIDs: string);
var
  svmCalendarClient: TsvmCalendarClient;
  dstDailyRule, dstWeeklyRule, dstMonthlyRule, dstYearlyRule: TDataSet;
begin
  svmCalendarClient := TsvmCalendarClient.Create(FConnection);
  try
    svmCalendarClient.GetRules(DailyCalendarIDs, WeeklyCalendarIDs,
                               MonthlyCalendarIDs, YearlyCalendarIDs,
                               dstDailyRule, dstWeeklyRule,
                               dstMonthlyRule, dstYearlyRule);
    PopulateRuleCDS(FDailyRule, dstDailyRule);
    PopulateRuleCDS(FWeeklyRule, dstWeeklyRule);
    PopulateRuleCDS(FMonthlyRule, dstMonthlyRule);
    PopulateRuleCDS(FYearlyRule, dstYearlyRule);
  finally
    svmCalendarClient.Free;
  end;
end;


The crucial bit is hidden in PopulateRuleCDS:
procedure TxxxCalendar.PopulateRuleCDS(const cdsRule: TClientDataSet;
                                         const dstRule: TDataSet);
var
  i: Integer;
begin
  cdsRule.Close;
  cdsRule.CreateDataSet;
  cdsRule.LogChanges := False;
  while not dstRule.Eof do
  begin
    cdsRule.Append;
    for i := 0 to dstRule.FieldCount-1 do
      cdsRule.Fields[i].Value := dstRule.Fields[i].Value;
    cdsRule.Post;
    dstRule.Next;
  end;
  cdsRule.IndexFieldNames := 'CalendarID';
end;


As you can see I am shuffeling may data into a local CDS because the dataset used to transport the data from the server to the client will be closed when client-side proxy class svmCalendarClient.

I hope this will help.

Salut,
Mathias
Michael Eriksen

Posts: 27
Registered: 6/12/11
Re: Datasnap: Howto run through a TDataset on clientside  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 14, 2015 9:26 AM   in response to: Mathias Burbach in response to: Mathias Burbach
Thanks for your help - but do you have a more simplified example? I don't exactly understand what you mean :-(

Mathias Burbach wrote:
Hello Eric,

I think you don't need to open the dataset any more once it has been returned by the DataSnap server. Here is how I deal with server methods that may return multiple datasets:

procedure TsvmCalendar.GetRules(const DailyCalendarIDs, WeeklyCalendarIDs, MonthlyCalendarIDs, YearlyCalendarIDs: string;
                                out DailyRules, WeeklyRules, MonthlyRules, YearlyRules: TDataSet);
begin
  OpenRule(qryDailyCalendarRule, DailyCalendarIDs);
  DailyRules := qryDailyCalendarRule;
  OpenRule(qryWeeklyCalendarRule, WeeklyCalendarIDs);
  WeeklyRules := qryWeeklyCalendarRule;
  OpenRule(qryMonthlyCalendarRule, MonthlyCalendarIDs);
  MonthlyRules := qryMonthlyCalendarRule;
  OpenRule(qryYearlyCalendarRule, YearlyCalendarIDs);
  YearlyRules := qryYearlyCalendarRule;
end;


And on the client side I use the proxy class
TsvmCalendarClient.GetRules(DailyCalendarIDs: string; 
   WeeklyCalendarIDs: string; 
   MonthlyCalendarIDs: string; 
   YearlyCalendarIDs: string; 
   out DailyRules: TDataSet; out WeeklyRules: TDataSet; out MonthlyRules: TDataSet; out YearlyRules: TDataSet);


to obtain my data in one server call:

procedure TxxxCalendar.GetRulesRemotely(const DailyCalendarIDs, WeeklyCalendarIDs,
                                               MonthlyCalendarIDs, YearlyCalendarIDs: string);
var
  svmCalendarClient: TsvmCalendarClient;
  dstDailyRule, dstWeeklyRule, dstMonthlyRule, dstYearlyRule: TDataSet;
begin
  svmCalendarClient := TsvmCalendarClient.Create(FConnection);
  try
    svmCalendarClient.GetRules(DailyCalendarIDs, WeeklyCalendarIDs,
                               MonthlyCalendarIDs, YearlyCalendarIDs,
                               dstDailyRule, dstWeeklyRule,
                               dstMonthlyRule, dstYearlyRule);
    PopulateRuleCDS(FDailyRule, dstDailyRule);
    PopulateRuleCDS(FWeeklyRule, dstWeeklyRule);
    PopulateRuleCDS(FMonthlyRule, dstMonthlyRule);
    PopulateRuleCDS(FYearlyRule, dstYearlyRule);
  finally
    svmCalendarClient.Free;
  end;
end;


The crucial bit is hidden in PopulateRuleCDS:
procedure TxxxCalendar.PopulateRuleCDS(const cdsRule: TClientDataSet;
                                         const dstRule: TDataSet);
var
  i: Integer;
begin
  cdsRule.Close;
  cdsRule.CreateDataSet;
  cdsRule.LogChanges := False;
  while not dstRule.Eof do
  begin
    cdsRule.Append;
    for i := 0 to dstRule.FieldCount-1 do
      cdsRule.Fields[i].Value := dstRule.Fields[i].Value;
    cdsRule.Post;
    dstRule.Next;
  end;
  cdsRule.IndexFieldNames := 'CalendarID';
end;


As you can see I am shuffeling may data into a local CDS because the dataset used to transport the data from the server to the client will be closed when client-side proxy class svmCalendarClient.

I hope this will help.

Salut,
Mathias
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02