- This topic has 5 replies, 2 voices, and was last updated 6 years, 8 months ago by HeDiBo.
-
AuthorPosts
-
March 12, 2018 at 11:07 pm #37774HeDiBoParticipant
In a form with data fields there are also a couple of TsDBDateEdit fields.
Editing the data fields will put the dataset in edit mode automatically (the default behavior for data fields).
However if I pull down the calendar in the date field and do not choose a date, but click outside the calendar and subsequently try to edit another record (not the same record, that works), I get an exception: Dataset is not in Edit mode.
The problem occurs in this little procedure:
Code:procedure TsDBDateEdit.UpdateData(Sender: TObject);
var
D: TDateTime;
begin
ValidateEdit;
D := Self.Date;
if D <> 0 then
FDataLink.Field.AsDateTime := D {<<<< Raises not in edit mode exception}
else
FDataLink.Field.Clear;
end;The function should not have been called, I think.
To recap:
- Show a record with data fields, with a TsDBDateEdit field.[*]Pull down the calendar in that field.[*]Click outside the calendar to close it.[*]Try to position to the next record.[*]A DataSet is not in edit mode exception occurs.
March 15, 2018 at 2:26 pm #57700SupportKeymasterHello!
Try this demo, please: http://www.alphaskins.com/sfiles/demos/adbdemo.zip
Can the issue be repeated there?
Maybe type of database have influence?
March 15, 2018 at 4:50 pm #57704HeDiBoParticipant'Support' wrote:Hello!
Try this demo, please: http://www.alphaskin…mos/adbdemo.zip
Can the issue be repeated there?
Maybe type of database have influence?
It can not be repeated with your example. You are right in assuming it depends on the database type. The problem is as indicated below.
Code:procedure TsDBDateEdit.CMExit(var Message: TCMExit);
begin
try
if not (csDesigning in ComponentState) and CheckOnExit then begin
CheckValidDate;
if (MaxDate 0) and (Date > MaxDate) then
Date := MaxDate
else
if (MinDate 0) and (Date < MinDate) then
Date := MinDate;
end;
FDataLink.UpdateRecord; // <<< Not always possible, if the dataset is not in Edit or Insert mode.
except
SelectAll;
if CanFocus then
SetFocus;raise;
end;
CheckCursor;
DoExit;
end;Not all databases will accept an UpdateRecord call, if the dataset is not in Edit or Insert mode.
Upon the UpdateRecord, the TsDBDateEdit does this:
Code:procedure TsDBDateEdit.UpdateData(Sender: TObject);
var
D: TDateTime;
begin
ValidateEdit;
D := Self.Date;
if D 0 then
FDataLink.Field.AsDateTime := D // <<< Produces the database error
else
FDataLink.Field.Clear;
end;I think the problem is the CMExit procedure, which should not assume a change in the field's data.
March 16, 2018 at 12:31 pm #57708HeDiBoParticipant'HeDiBo' wrote:I think the problem is the CMExit procedure, which should not assume a change in the field's data.
I made this obvious change in the TsDBDateEdit.CMExit procure:
Code:procedure TsDBDateEdit.CMExit(var Message: TCMExit);
begin
try
if not (csDesigning in ComponentState) and CheckOnExit then begin
CheckValidDate;
if (MaxDate 0) and (Date > MaxDate) then
Date := MaxDate
else
if (MinDate 0) and (Date < MinDate) then
Date := MinDate;
end;
if FDataLink.Field.DataSet.State in [dsEdit, dsInsert] then FDataLink.UpdateRecord;
except
SelectAll;
if CanFocus then
SetFocus;raise;
end;
CheckCursor;
DoExit;
end;That solved the problem. But introduced another one: when selecting a field in the same record, the date field always showed the MinDate: 16-03-1928. When posting the record, that date was made permanent.
Then I changed the obvious place:
Code:procedure TsDBDateEdit.UpdateData(Sender: TObject);
var
D: TDateTime;
begin
if not ( FDataLink.Field.DataSet.State in [dsEdit, dsInsert] ) then Exit;
ValidateEdit;
D := Self.Date;
if D 0 then
FDataLink.Field.AsDateTime := D
else
FDataLink.Field.Clear;
end;That was a bit better. The MinDate showed, but was cleared as soon as I edited another field in that record. But I was still able to store the MinDate when posting the dataset.
So, in the end, it's a mess 😢
March 16, 2018 at 2:03 pm #57709HeDiBoParticipantI didn't think enough about the right solution.
This works:
Code:procedure TsDBDateEdit.CMExit(var Message: TCMExit);
begin
if CanEdit and
( FDataLink.DataSource.State in [dsEdit, dsInsert] ) then
try
if not (csDesigning in ComponentState) and CheckOnExit then begin
CheckValidDate;
if (MaxDate 0) and (Date > MaxDate) then
Date := MaxDate
else
if (MinDate 0) and (Date < MinDate) then
Date := MinDate;
end;
FDataLink.UpdateRecord;
except
SelectAll;
if CanFocus then
SetFocus;raise;
end;
CheckCursor;
DoExit;
end;In other words, don't mingle with the Date if the dataset is not in Edit/Insert mode mode.
This fixed my problem completely ��
The problem occurs in your project too, if you specify a MinDate property.
March 21, 2018 at 12:26 pm #57718HeDiBoParticipantProblem fixed in 13.03
-
AuthorPosts
- You must be logged in to reply to this topic.