Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 10 total
Thread How to open detail form with the select row in grid?
Wed, Oct 22 2014 3:23 PMPermanent Link

TD

Advanced Data Systems, Inc.

I would like for a user to select a row in a grid then click an Edit button, on the same form, which would launch another form (detail form) that would show the fields for that particular row.  I have looked at the Master-Detail example but I need help in understanding the code used there.:

procedure TMasterDetailForm.EditOrderButtonClick(Sender: TObject);
begin
  Database.StartTransaction;
  with OrderEntryDlg do
     begin
     OnClose:=OrderEntryClose;
     CustomerOrders.Update;
     SetupOrder(CustomerOrders);
     end;
end;

If someone has the time to quickly explain the code I would greatly appreciate it.
TD
Thu, Oct 23 2014 2:53 AMPermanent Link

Uli Becker

You just have to bind the edit controls on the "Detail" form to the
grid's dataset. Unfortunately you can't do so at design time with the
current version.

To avoid too much writing Smile: Use a loop in the OnCreate event of the
form, e.g.:

for i := 0 to Controlcount -1 do
      begin
         if (controls[i] is TEdit) or (controls[i] is TMemo)  or
(controls[i] is TImage) then
            controls[i].Dataset := MainForm.MyDataset;
      end;

After editing your data you should use code like this:

Database.StartTransaction;
      try
         with MainForm.MyDataset do
         begin
            Update;
            Save;
         end;
         Database.Commit;
      except
         Database.Rollback;
         raise;
      end;

to save your changes.

Uli
Thu, Oct 23 2014 4:17 AMPermanent Link

Matthew Jones

TD wrote:

>    with OrderEntryDlg do
>       begin
>       OnClose:=OrderEntryClose;
>       CustomerOrders.Update;
>       SetupOrder(CustomerOrders);
>       end;

I'll explain these parts. First, the with, is wicked and should be
avoided. 8-)

The OnClose:=OrderEntryClose; sets the FormClose event of the child
form to the OrderEntryClose function in the parent. This allows the
parent to know the form got closed. Not actually part of the
grid/database at all.

CustomerOrders.Update; will be refreshing the database, presumably on
the child form (hard to tell with the with).

SetupOrder(CustomerOrders); will be making the data selections etc,
again probably on the child form. Details in the source.

--

Matthew Jones
Thu, Oct 23 2014 1:59 PMPermanent Link

TD

Advanced Data Systems, Inc.

Uli Becker wrote:

You just have to bind the edit controls on the "Detail" form to the
grid's dataset. Unfortunately you can't do so at design time with the
current version.

To avoid too much writing Smile: Use a loop in the OnCreate event of the
form, e.g.:

for i := 0 to Controlcount -1 do
      begin
         if (controls[i] is TEdit) or (controls[i] is TMemo)  or
(controls[i] is TImage) then
            controls[i].Dataset := MainForm.MyDataset;
      end;

After editing your data you should use code like this:

Database.StartTransaction;
      try
         with MainForm.MyDataset do
         begin
            Update;
            Save;
         end;
         Database.Commit;
      except
         Database.Rollback;
         raise;
      end;

to save your changes.

Uli

Thank you Uli, that is a great help!
Thu, Oct 23 2014 2:02 PMPermanent Link

TD

Advanced Data Systems, Inc.

"Matthew Jones" wrote:

TD wrote:

>    with OrderEntryDlg do
>       begin
>       OnClose:=OrderEntryClose;
>       CustomerOrders.Update;
>       SetupOrder(CustomerOrders);
>       end;

I'll explain these parts. First, the with, is wicked and should be
avoided. 8-)

The OnClose:=OrderEntryClose; sets the FormClose event of the child
form to the OrderEntryClose function in the parent. This allows the
parent to know the form got closed. Not actually part of the
grid/database at all.

CustomerOrders.Update; will be refreshing the database, presumably on
the child form (hard to tell with the with).

SetupOrder(CustomerOrders); will be making the data selections etc,
again probably on the child form. Details in the source.

--

Matthew Jones

Thanks Matthew!  In regards to part of the code above is this code below which is from the master/detail example.  I hate to ask this but ... is all of this really necessary?  If it is, then so be it, just wanting to better understand the code.

Thanks for your help!
TD
Thu, Oct 23 2014 2:47 PMPermanent Link

TD

Advanced Data Systems, Inc.

Sorry, forgot to post the "code below" in my last post to this thread

Thanks Matthew!  In regards to part of the code above is this code below which is from the master/detail example.  I hate to ask this but ... is all of this really necessary?  If it is, then so be it, just wanting to better understand the code.

Thanks for your help!
TD

code -

procedure TOrderEntryDlg.SetupOrder(OrdersDataSet: TDataSet;
                                   IsInserting: Boolean=False);
begin
  Inserting:=IsInserting;
  CancelChecked:=False;
  CommitStarted:=False;
  RollbackStarted:=False;
  Database.BeforeCommit:=BeforeCommit;
  Database.OnCommitError:=CommitError;
  Database.AfterCommit:=AfterCommit;
  Database.BeforeRollback:=BeforeRollback;
  Database.OnRollbackError:=RollbackError;
  Database.AfterRollback:=AfterRollback;
  Orders:=OrdersDataSet;
  OrderIDLabel.DataSet:=Orders;
  OrderDateLabel.DataSet:=Orders;
  PONumberEdit.DataSet:=Orders;
  TermsComboBox.DataSet:=Orders;
  OrderTotalLabel.DataSet:=Orders;
  AmountPaidEdit.DataSet:=Orders;
  BalanceDueLabel.DataSet:=Orders;
  SpecialInstructionsMemo.DataSet:=Orders;
  PurchaseTotalLabel.DataSet:=Orders;
  ShippingTotalLabel.DataSet:=Orders;
  CustomerItems.Params.Clear;
  CustomerItems.Params.Add('OrderID='''+Orders.Columns['OrderID'].AsString+'''');
  Database.Load(CustomerItems);
end;

procedure TOrderEntryDlg.CloseOrder;
begin
  Database.BeforeCommit:=nil;
  Database.OnCommitError:=nil;
  Database.AfterCommit:=nil;
  Database.BeforeRollback:=nil;
  Database.OnRollbackError:=nil;
  Database.AfterRollback:=nil;
  OrderIDLabel.DataSet:=nil;
  OrderDateLabel.DataSet:=nil;
  PONumberEdit.DataSet:=nil;
  TermsComboBox.DataSet:=nil;
  OrderTotalLabel.DataSet:=nil;
  AmountPaidEdit.DataSet:=nil;
  BalanceDueLabel.DataSet:=nil;
  SpecialInstructionsMemo.DataSet:=nil;
  PurchaseTotalLabel.DataSet:=nil;
  ShippingTotalLabel.DataSet:=nil;
end;
Fri, Oct 24 2014 6:25 AMPermanent Link

Matthew Jones

TD wrote:

>  is all of this really necessary?

An interesting question. The answer is of course yes, and no. But for
the no, yes too, but not quite. That should clarify it I think. 8-)

Okay, the reason for that code is that the demo is using a child form
(I presume from the description). Because of that the connections
between the child and parent grids and databases need to be "plumbed
in" so that it works. For many purposes this isn't needed because you'd
simply set the properties and events of the components on the same form
and it would all be connected "automatically" when the form is created.
Thus for a single form solution the connections are there, but you
don't need the code. The demo though is showing the power of the system
available, whether you choose to use it or not is up to you.

--

Matthew Jones
Fri, Oct 24 2014 12:59 PMPermanent Link

TD

Advanced Data Systems, Inc.

"Matthew Jones" wrote:

TD wrote:

>  is all of this really necessary?

An interesting question. The answer is of course yes, and no. But for
the no, yes too, but not quite. That should clarify it I think. 8-)

Okay, the reason for that code is that the demo is using a child form
(I presume from the description). Because of that the connections
between the child and parent grids and databases need to be "plumbed
in" so that it works. For many purposes this isn't needed because you'd
simply set the properties and events of the components on the same form
and it would all be connected "automatically" when the form is created.
Thus for a single form solution the connections are there, but you
don't need the code. The demo though is showing the power of the system
available, whether you choose to use it or not is up to you.

--

Matthew Jones

Thanks Matthew.  I have another question regarding using a second form to edit a row in a grid on a first form.  If this question should be moved to a new thread in the forum please let me know.

Could I not create a form bound to a dataset (fsms_filtered1) that is based on a query that returns only the single record that is shown selected in the grid on the first form?.. I have tried this using a public variable (intPID) on the first form set to the primary key field of the record selected.  I added the first form to the uses clause of the second form.  I used the code below to try this out but it I get the error shown in the attached screen capture.  Shouldn't this work?    

procedure TForm3.Form3Create(Sender: TObject);
begin
  fsms_filtered1.Params.Clear;
  fsms_filtered1.Params.Add('PID=intPID');
  Database.Load(fsms_filtered1);
  Database.Load(location_type1);
end;



Attachments: public variable error.PNG
Fri, Oct 24 2014 7:54 PMPermanent Link

Walter Matte

Tactical Business Corporation

I think this should be changed from

  fsms_filtered1.Params.Add('PID=intPID');

to this

  fsms_filtered1.Params.Add('PID=' inttostr(intPID));

Walter
Sun, Oct 26 2014 5:59 PMPermanent Link

TD

Advanced Data Systems, Inc.

Uli Becker wrote:

"You just have to bind the edit controls on the "Detail" form to the
grid's dataset."

Thanks everyone for helping.  At this point Uli's suggestion is what is working for me.  It is also the way I normally accomplish the same thing in a Delphi desktop app.

TD
Image