0
votes

When calling this code more than once (It's called on the change of a combobox), I'm getting the error "Operation not allowed when the object is open" on the second change and on the third onwards i'm getting "invalid pointer operation".

if loadfile.Database <> nil then  
    loadfile.Database.destroy;  
Loadfile.Database := Tdatabase.create(CardSets.Text, false);  
LoadFile.Database.create(CardSets.Text, false);         
refreshlist;

The create code is just

DataSource :=   
    'Provider=Microsoft.Jet.OLEDB.4.0' +   
    ';Data Source=' + Path +  
    ';Jet OLEDB:Engine Type=5';   
with MainWindow do  
begin   
    ADOConnection.ConnectionString := Datasource;   
    ADOConnection.LoginPrompt := False;   
end; 

And refreshlist just updates a visual list of the data in the database.

I've looked at some similar stackoverflow questions but i am unable to see how the answers could help my problem.

Side question, When to use .Destroy or .Free? .Free in this case just gives a different error.

Thanks.

1
Why are you calling create twice? - Blorgbeard
Anyway, use FreeAndNil - neither destroy nor free set the value to nil. - Blorgbeard
Is that not how you create an object? NVM: I'm an idiot , thanks! - Precastwig
Any time you see two dots in the same expression, that suggests your design is weak. You should not be assigning to LoadFile.Database. A method in the class of LoadFile should be assigning to Database. It would seem that Database is read/write. Step 1 is to make it read only, or even private. More broadly it looks like your model is mixed in with your GUI. That's a mess. - David Heffernan

1 Answers

2
votes

First, you're calling Create twice; the second is unnecessary:

if loadfile.Database <> nil then  
    loadfile.Database.destroy;  
Loadfile.Database := Tdatabase.create(CardSets.Text, false);  // First call
LoadFile.Database.create(CardSets.Text, false);               // Second call

Change your code to simply:

LoadFile.Database.Free;
LoadFile.Database := TDatabase.Create(CardSets.Text, False);

Second, never directly call Destroy. Use Free instead, as it checks first for an unassigned pointer and then calls Destroy if it's safe to do so. TObject.Free is basically this code:

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;