Reputation: 805
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
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
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