Charl van Staden
Charl van Staden

Reputation: 47

Having weird ADO database issues with Delphi

I'd really appreciate some help with an issue for a school project that I've been having. What do you guys think could be wrong?
I spoke to a friend who said I must make sure that I only have 1 table's active property set to true at any given time. I tried this but it didn't seem to make a difference. Perhaps I didn't do it properly?

This is the code of my procedure:

procedure TForm1.btnChangePassUserClick(Sender: TObject);
var
  sNewPass,sOldPass:string;
begin
  sOldPass:= InputBox('Password verification','Please enter your current password','');

  if sOldPass = sPassword then
  begin
      sNewPass := inputBox('Password change','Please enter a new Password with at least 1 number and letter','');
      if isPasswordValid(sNewPass) then
        begin
           tblUsers.Active := True;
            tblUsers.Edit;
            tblUsers.Filtered := True;

            tblUsers.Filter := 'UserID = ' +QuotedStr(sPassword);
            tblUsers.First;
            tblUsers['Password'] := sNewPass;

            tblUsers.Post;
            tblUsers.Filtered := False;
            tblUsers.Filter := '';


          if bRememberMe then
            begin
              ShowMessage('Password changed, please log in again for security purposes');
              imgLogoutClick(Sender);
            end;

          sPassword := sNewPass;
        end
      else ShowMessage('Please ensure your password contains at least 1 letter and 1 number');
  end
  else ShowMessage('Incorrect Password');
end;

The error I get:

tblUsers: Dataset not in edit or insert mode

Upvotes: 1

Views: 150

Answers (2)

Ken White
Ken White

Reputation: 125748

Your use of Edit, Filter, and Filtered are all incorrect. You need to Edit only when actually editing the row; any change in the cursor (record pointer) position will cancel or post changes, taking the table out of edit mode (and thus your error).

You also shouldn't use Filter to search for data for editing. Use Locate instead. Something like this should work for you (although it's probably not what I would use in my own code):

procedure TForm1.btnChangePassUserClick(Sender: TObject);
var
  sNewPass,sOldPass:string;
begin
  sOldPass:= InputBox('Password verification','Please enter your current password','');

  if sOldPass = sPassword then
  begin
    sNewPass := inputBox('Password change','Please enter a new Password with at least 1 number and letter','');
    if isPasswordValid(sNewPass) then
    begin
      tblUsers.Active := True;

      // I'd think the search should be on the UserID rather than
      // the password. Are you certain this is what you want to do?
      if tblUsers.Locate('UserID', sPassword, []) then
      begin
        tblUsers.Edit;
        tblUsers['Password'] := sNewPass;
        tblUsers.Post;
      end;
      tblUsers.Active := False;

      if bRememberMe then
      begin
        ShowMessage('Password changed, please log in again for security purposes');
        imgLogoutClick(Sender);
      end;

      sPassword := sNewPass;
    end
    else ShowMessage('Please ensure your password contains at least 1 letter and 1 number');
  end
  else 
    ShowMessage('Incorrect Password');
end;

Upvotes: 5

René Hoffmann
René Hoffmann

Reputation: 2815

tblUsers.First might cause a scroll. I guess the dataset is posted on that scroll.

Try calling tblUsers.Edit just before assigning the new password via tblUsers['Password'] := sNewPass;.

As MartynA suggests, there is another problem that will prevent your code from working correctly, even when the above is fixed. tblUsers.Filter := 'UserID = ' +QuotedStr(sPassword); is most likely not what you want to do. Probably a variable containing UserID should be passed rather than sPassword.

If I remember correctly, there should be a function called Locate. It should be faster than a filter, as well.

Upvotes: 0

Related Questions