Database error if clicking outside TsDBDateEdit

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #37774
    HeDiBo
    Participant

    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.
    #57700
    Support
    Keymaster

    Hello!

    Try this demo, please: http://www.alphaskins.com/sfiles/demos/adbdemo.zip

    Can the issue be repeated there?

    Maybe type of database have influence?

    #57704
    HeDiBo
    Participant
    '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.

    #57708
    HeDiBo
    Participant
    '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 😢

    #57709
    HeDiBo
    Participant

    I 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.

    #57718
    HeDiBo
    Participant

    Problem fixed in 13.03 a3.gif

Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.