This is the code that I have been trying to do this with. DSMaster is a
TClientDataSet containing two fields: "ID" (integer) and "Data" (dataset).
DSChild is the nested data set and contains a single field "Number"
(integer). Also there is an index on ID in DSMaster, and I set it to the
selected index in the designer.
======
// adds ID to DSMaster if it's not already there. adds nothing if it is
// already there. in either case sets current record.
void TForm1::_AddMasterID (int id) {
if (!DSMaster->FindKey(ARRAYOFCONST((id)))) {
DSMaster->Insert();
DSMaster->FieldByName("ID")->AsInteger = id;
DSMaster->Post();
}
}
void __fastcall TForm1::Button2Click(TObject *Sender) {
int i, j, val;
//...
DSMaster->DisableControls();
DSChild->DisableControls();
for (i = 0; i < 5; ++ i) {
_AddMasterID(i);
// this is the part i'm having trouble with:
DSMaster->Edit();
DSChild->EmptyDataSet();
for (j = 0; j < 10; ++ j) {
val = rand();
DSChild->InsertRecord(ARRAYOFCONST((val)));
}
DSMaster->Post();
// -----------------------------------------
}
//...
}
======
That code attempts to add IDs 0-4 to DSMaster if they don't already exist,
clear's each child data, then adds 10 random numbers to each child. What
actually happens is that every single child data set ends up empty except
for the last one. If I comment out the EmptyDataSet() call then it does what
I'd expect: add 10 additional numbers to each child data set on top of
what's already there. It's like EmptyDataSet() is happening -after- the
InsertRecord() calls for some reason -- but not for the last one.
A test project showing this is here:
http://www.sendspace.com/file/z6xatx
The "Reset" button clears the content. The "Populate" button tries to do
what I just described. The DBGrid on the left is the master, the right is
the child. Note that even if you add ID numbers > 4 to the master table
before pressing "Populate", ID 4 is still the one that contains data, and 0,
1, 2, and 3, are all erased
What am I doing wrong here?
It works when I replace the EmptyDataSet() call with:
for (DSChild->First(); !DSChild->Eof; DSChild->First())
DSChild->Delete();
But this seems like an inefficient way of clearing the data set, and I
thought this is the effect EmptyDataSet() was supposed to have, anyway. Am I
misunderstanding what EmptyDataSet() is supposed to do?
Thanks,
Jason
PS:
I found something that confused me even more. You can try this out in the
test project but if I add other IDs to DSMaster that that loop doesn't touch
(like 5, 6, 7) and put some data in their child data sets, then run that
code, it erases the contents of the child data sets for -all- the IDs
(except 4), even though that loop should never have touched the ones I
added.
So if you have IDs 0, 1, 2, 3, 4, 5, 6, 7 in DSMaster with data in their
child data sets, then run that code which only loops on IDs 0, 1, 2, 3, 4,
you are left with no data in any of the child data sets except number 4. I
can't figure it out at all.