1
votes

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;
1
No, as my post said, I tried that and it doesn't fire when you click a title in another columnuser2834566

1 Answers

1
votes

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.