user2834566
user2834566

Reputation: 805

How to post data in TDBgrid immediately when exiting the cell being edited

I have a TDBGrid --> Tdatasource --> TQuery --> table in MySQL database.

One field in the grid/query is Boolean and is shown as a checkbox.

I have written code to sort the grid by whichever column title I click following standard answers on SO.

I have a 'Save' button that preforms quite a bit of unrelated processing but the first thing it does is

MyQuery1.edit;
MyQuery1.Post;

to ensure that the last edit made is posted, even if the user doesn't move to another row before clicking 'save'.

The problem.

If for example I tick one checkbox to change the field value from FALSE to TRUE and move to a different row then the data is posted back to the table as desired and the row stays ticked as I scroll

If I tick one checkbox and move off to click the 'save' button the code in that button does a post and the checkbox remains checked

However, If I tick one checkbox and move to the column header of a different column to sort the grid the data doesn't get posted and after the sort has completed the checkbox is unchecked

The question

Is there some event I can use to do a post either immediately I tick (or untick) the checkbox or when I exit the column in which the checkbox resides.

What I have tried

I've tried the following events of the DBgrid but none seem to get called when I move off to click a column title

OnEditChange() 
OnEditRecord(()
OnColExit(()

In case someone wants to see the full code of my 'unrelated processing' in the Save button it is this but, as I said, it is unrelated.

procedure TFrmBulkSubdPaymentRecord.btnSaveClick(Sender: TObject);
var
  i : Integer;
  member_id_making_payment : Integer;
  invoice_id : Integer;
  cash_payment_ref : string;
  payment_amount : Currency;
  paid_date : TDateTime;
  user_comment : string;
  sql : string;
  NunRecordSaved : integer;
  SQL_of_changes : string;
begin
    SQL_of_changes := '';
    user_comment := 'Bulk insertion on ' + ReverseDateString(DateToStr(Date));
    paid_date := Date;
    NunRecordSaved := 0;
     SMDBGrid1.DisableScroll;

     MyQuery1.DisableControls;   //to avoid dataset not in edit mode error see https://forums.devart.com/viewtopic.php?t=25580
     MyQuery1.edit;
     MyQuery1.Post;// make sure that even one row gets put in even if we don't move cursor off it
     MyQuery1.EnableControls ;

    MyQuery1.First ;
    while not MyQuery1.eof do   // if this row is ckecked, build up the paramenters and mark this invoice as paid
        begin
        if MyQuery1.FieldByName('payment_made').AsBoolean = true then
          begin
            member_id_making_payment := MyQuery1.FieldByName('member_id').asInteger;
            invoice_id  := MyQuery1.FieldByName('invoice_id').asInteger;
            cash_payment_ref  := MyQuery1.FieldByName('invoice_ref').asString;
            payment_amount  := MyQuery1.FieldByName('invoice_amount').AsCurrency ;
            sql :=  'CALL record_new_payment('
                   + ToSQL.Int(member_id_making_payment) + ','
                   + ToSQL.Int(invoice_id) + ','
                   + ToSQL.MySQLText(cash_payment_ref) + ','
                   + ToSQL.Float(payment_amount) +','
                   + ToSQL.Date(paid_date) +','
                   + ToSQL.MySQLText(user_comment) +');'  ;
            DMod.RunSQLCommand(sql);
            inc(NunRecordSaved);

            SQL_of_changes :=  SQL_of_changes +
              U_SQLcode.SQL_ChangeMade(
                                       member_id_making_payment,   //AffectedMemberID   integer
                                       'New payment',        //ChangeType
                                       'Member: '+ inttostr(member_id_making_payment) + 'Invoice: ' + inttostr(invoice_id),                       //FieldChanged
                                       '',                                //OldData
                                       '£'  + CurrToStr(payment_amount) ,    //Newdata
                                       user_comment,             //Comment
                                       invoice_id   //invoiceID integer
                                       );
            end;
        MyQuery1.Next;
        end;
     SMDBGrid1.EnableScroll;
 if NunRecordSaved > 0  then
    begin
    DMod.RunSQLCommand(SQL_of_changes);
    ShowMessage(IntToStr(NunRecordSaved)+' payments for full subs amount saved' );
    LoadGrid(TheFeeYear);
    end
 else
    ShowMessage('No members ticked as having paid, nothng saved')
end;

Upvotes: 1

Views: 374

Answers (2)

Paul Browne
Paul Browne

Reputation: 1

I got round this by adding an OnKeyPress event to the data grid and forcing the dataset .Post for the return or tab key, which were effectively exiting the cell anyway.

if  (ClientDataSet.State in [dsEdit, dsInsert])
and ( (ord(Key) = VK_RETURN) or (ord(Key) = VK_TAB) ) then
  ClientDataSet.Post;

Also, I have realised I needed to handle the user clicking away from the grid - using the grid's OnExit event - but only after being in an edit/insert state.

if ClientDataSet.State in [dsEdit, dsInsert] then
  ClientDataSet.Post;

Upvotes: 0

user2834566
user2834566

Reputation: 805

I got round this by adding

MyQuery1.edit;
MyQuery1.Post;

at the start of the code that does the sorting.

But I'd still like to know if there is a better way to post when leaving a cell.

Upvotes: 1

Related Questions