0
votes

Right now I'm struggling to solve a bug that caused by the dataset mode at Delphi (using ADODataset),

details as below for the add button mechanism :

IDMain: =self.DBTextIDUser.Caption+'-'+self.DBEditWorkingDate.Text;
datamodule1.ADODataSetWorkingDetails.Append;

with datamodule1.ADODataSetWorkingDetails do

begin

  dbgridworkinghours.Fields[0].AsString := IDMain;
  dbgridworkinghours.Fields[7].AsString := self.DBTextIDUser.Caption;
  dbgridworkinghours.Fields[8].AsString := self.DBTextName.Caption;
  dbgridworkinghours.Fields[9].AsString := self.DBEditWorkingDate.Text;
  dbgridworkinghours.Fields[11].AsString := self.DBTextPeriod.caption;
  dbgridworkinghours.Fields[10].AsString := self.DBTextToday.Caption;

end;

I already set the adodataset to append mode at the save button :

datamodule1.ADODataSetWorkingDetails.post;

when I click the save button, an error appears that:

The adodataset not in edit/insert mode

I already used this mechanism at the other form and it works

note: I already tried setting the adodataset mode to insert, but still faced the same error

1
Is the grid connected to the dataset? More important Why do you asaign the values to the grid instead of the dataset? - kobik
check other events of the adodataset. - sddk
Hi, the Post is at the save button : datamodule1.ADODataSetWorkingDetails.post. What I meant in before, the append mode already set at the add button. for the Post, I already put it at the save button (datamodule1.ADODataSetWorkingDetails.post) - TimmyBudiman

1 Answers

2
votes

What @kobik said.

Your problem is most likely being caused by something you haven't told us in your q. I think the important thing is for you to find out how to debug this sort of thing yourself, so that even if you don't understand the cause, you can at least isolate it and provide better information when you ask for help here. So I'm going to outline how to do that.

  • In your Project Options, check the box "Use Debug DCUs"

  • Set up two event handlers, for your ADODataSetWorkingDetails's AfterPost and AfterScroll events, put a some "do nothing" code in both of them (to stop the IDE removing them). Put a debugger breakpoint on the first line inside the AfterScroll handler, but not (yet) the AfterScroll one.

  • Compile and run your program.

  • You should find that somewhere after you call Append but before you click your Save button, the debugger stops on your AfterPost breakpoint.

  • When it does, go to View | Debug windows | Call stack. This will show you a list of program lines, the one at the top being the one closest to where the breakpoint tripped. This will likely be deep inside the VCL's run-time code (which is why I said to check "Use Debug DCUs". Scroll down the list towards the bottom, and eventually you should come to a line which is the cause of why Post was called.

  • If it isn't obvious to you why the AfterPost event was called, put a breakpoint on your Append line and run the program again. When this breakpoint trips, put another breakpoint inside your AfterScroll event, resume the program by pressing F9 and see if the AfterScroll breakpoint is hit. If it is, again view the Call stack and that should show you why it was called - if it isn't obvious, then add the contents of tthe Call stack window to your q. If the cause is obvious, then change your code to avoid it.

The reason I've gone on about the AfterScroll event is that what isn't obvious is that when your code causes a dataset to scroll, any pending change (because the dtaset is in dsInsert or dsEdit state will cause the change to be posted and you will then got the error you've quoted if you try to call Post on the dataset again. Calling Append initially sets a dataset into dsInsert state, btw.

See if you can at least identify what is causing your dataset to post before it is supposed to, and let us know in a comment to your q or this answer.

Btw, I strongly recommend that you get out of the habit of using the with construct in your code. Although it may save you a bit of typing, in the long term it will likely make bugs far more likely to happen and far harder to find.

Update TDataSet and its descendants have a State property which is of type TDataSetState (see DB.Pas). Normally, for browsing data and navigating around the dataset, the dataset is in dsBrowse state. If you call Edit or Append (or Insert), the dataset is temporarily put in dsEdit or dsInsert state, respectively. Various routines in DB.Pas check the dataset state before certain operations are performed and raise an exception if the DataSet in not in the correct state for the operation to go ahead. It is very, very likely that it is one of these checks that is giving you the exception.

My original hunch was that your error was occurring because something was happening which was causing Post to be called, because if Post succeeds, it puts the dataset back into dsBrowse state, so when clicking your Save button calls Post, the dataset is already in dsBrowse state. You can, of course, put a breakpoint in TDataSet.Post in DB.Pas check which state the dataset is actually in when it is called.

There are two other main possibilities for the cause of your exception, namely that either TDataSet.Cancel or the general Abort method is being called. To investigate these, put breakpoints on the first lines inside TDataSet.Cancel (in DB.Pas) and Abort (in SysUtils.Pas). If either of these breakpoints trips between you calling Append and Post, then you can use the Call Stack view to try and figure out why execution has reached there.