title: Compact An Access Database
body: <p>I am attempting to compact a Microsoft Access database but the code shown below does not work.</p>
  
  <pre><code>procedure TForm1.Disconnect1Click(Sender: TObject);
  begin
    ADODataSet1.Active := False;
    ADOTable1.Active := False;
    ADODataSet1.Connection := nil;
    DataSource1.Enabled := False;
    ADOConnection1.Connected := False;
    JetEngine1.Disconnect;
  end;
  
  function DatabaseCompact(const sdbName: WideString): boolean;
  { Compact ADO mdb disconnected database. }
  var
    iJetEngine: TJetEngine; { Jet Engine }
    iTempDatabase: WideString; { TEMP database }
    iTempConn: WideString; { Connection string }
  const
    iProvider = 'Provider=Microsoft.Jet.OLEDB.4.0; Data Source=';
  begin
    Result := False;
    iTempDatabase := ExtractFileDir(sdbName) + 'TEMP' + ExtractFileName(sdbName);
    iTempConn := iProvider + iTempDatabase;
    if FileExists(iTempDatabase) then
      DeleteFile(iTempDatabase);
    iJetEngine := TJetEngine.Create(Application);
    try
      try
        iJetEngine.CompactDatabase(iProvider + sdbName, iTempConn);
        DeleteFile(sdbName);
        RenameFile(iTempDatabase, sdbName);
      except
        on E: Exception do
          ShowMessage(E.Message);
      end;
    finally
      iJetEngine.FreeOnRelease;
      Result := True;
    end;
  end;
  
  procedure TForm1.Compact1Click(Sender: TObject);
  var
    iResult: Integer;
  begin
    AdvTaskDialog1.Clear;
    AdvTaskDialog1.Title := 'Compact Database';
    AdvTaskDialog1.Instruction := 'Compact Database';
    AdvTaskDialog1.Content := 'Compact the database?';
    AdvTaskDialog1.Icon := tiQuestion;
    AdvTaskDialog1.CommonButtons := [cbYes, cbNo];
    iResult := AdvTaskDialog1.Execute;
    if iResult = mrYes then
    begin
      Screen.Cursor := crHourglass;
      try
        DatabaseCompact('D:\RadProjects10\EBook Database\EBook Database.mdb');
        ADODataSet1.Connection := ADOConnection1;
        ADOConnection1.Connected := True;
      finally
        Screen.Cursor := crDefault;
      end;
    end;
  end;
  
  procedure TForm1.Connect1Click(Sender: TObject);
  begin
    ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;' +
      'User ID=Admin;' +
      'Data Source=D:\RadProjects10\EBook Database\EBook Database.mdb;' +
      'Mode=Share Deny None;' + 'Jet OLEDB:System database="";' +
      'Jet OLEDB:Registry Path="";' + 'Jet OLEDB:Database Password="";' +
      'Jet OLEDB:Engine Type=5;' + 'Jet OLEDB:Database Locking Mode=1;' +
      'Jet OLEDB:Global Partial Bulk Ops=2;' +
      'Jet OLEDB:Global Bulk Transactions=1;' +
      'Jet OLEDB:New Database Password="";' +
      'Jet OLEDB:Create System Database=False;' +
      'Jet OLEDB:Encrypt Database=False;' +
      'Jet OLEDB:Don''t Copy Locale on Compact=False;' +
      'Jet OLEDB:Compact Without Replica Repair=False;' + 'Jet OLEDB:SFP=False;';
    ADODataSet1.Connection := ADOConnection1;
    ADOConnection1.Connected := True;
    ADODataSet1.Active := True;
    ADOTable1.Active := True;
    DataSource1.Enabled := True;
  end;
  </code></pre>
  
  <p>Even though I disconnect the database before compacting I get an error message:</p>
  
  <blockquote>
    <p>You attempted to open a database that is already opened exclusively by the user 'Admin' on the machine 'xxxx'.  Try again when the database is available.</p>
  </blockquote>
  
  <p>I disconnect and then compact but something is going wrong.  I understand that it is good to compact an Access database, so I am attempting to do this with a small application I wrote to store contact information.</p>
  
  <p>Apparently the code I used to disconnect from the database is not working.  Where did I fail?</p>