好象不能
paradox和access不一样
没有多余的空间

解决方案 »

  1.   

    pack paradox and DBase codeunit DDGTbls;interfaceuses DB, DBTables, BDE;type
      TdBaseTable = class(TTable)
      private
        FViewDeleted: Boolean;
        function GetIsDeleted: Boolean;
        function GetRecNum: Longint;
        procedure SetViewDeleted(Value: Boolean);
      protected
        function CreateHandle: HDBICur; override;
      public
        procedure Pack(RegenIndexes: Boolean);
        procedure UndeleteRecord;
        property IsDeleted: Boolean read GetIsDeleted;
        property RecNum: Longint read GetRecNum;
        property ViewDeleted: Boolean read FViewDeleted write SetViewDeleted;
      end;  TParadoxTable = class(TTable)
      private
      protected
        function CreateHandle: HDBICur; override;
        function GetRecNum: Longint;
      public
        procedure Pack;
        property RecNum: Longint read GetRecNum;
      end;implementationuses SysUtils;{ TdBaseTable }function TdBaseTable.GetIsDeleted: Boolean;
    { Returns a boolean indicating whether or not the current record }
    { has been soft deleted. }
    var
      RP: RECProps;
    begin
      if not FViewDeleted then     // don't bother if they aren't viewing
        Result := False            // deleted records
      else begin
        UpdateCursorPos;           // update BDE from Delphi
        { Get current record properties }
        Check(dbiGetRecord(Handle, dbiNOLOCK, Nil, @RP));
        Result := RP.bDeleteFlag;  // return flag from properties
      end;
    end;function TdBaseTable.GetRecNum: Longint;
    { Returns the physical record number of the current record. }
    var
      RP: RECProps;
    begin
      UpdateCursorPos;             // update BDE from Delphi
      { Get current record properties }
      Check(dbiGetRecord(Handle, dbiNOLOCK, Nil, @RP));
      Result := RP.iPhyRecNum;     // return value from properties
    end;function TdBaseTable.CreateHandle: HDBICur;
    { Overridden from ancestor in order to perform a check to }
    { ensure that this is a dBASE table. }
    var
      CP: CURProps;
    begin
      Result := inherited CreateHandle;         // do inherited
      if Result <> Nil then begin
        { Get cursor properties, and raise exception if the }
        { table isn't using the dBASE driver. }
        Check(dbiGetCursorProps(Result, CP));
        if not (CP.szTableType = szdBASE) then
          raise EDatabaseError.Create('Not a dBASE table');
      end;
    end;procedure TdBaseTable.Pack(RegenIndexes: Boolean);
    { Packs the table in order to removed soft deleted records }
    { from the file. }
    const
      SPackError = 'Table must be active and opened exclusively';
    begin
      { Table must be active and opened exclusively }
      if not (Active and Exclusive) then
        raise EDatabaseError.Create(SPackError);
      try
        { Pack the table }
        Check(dbiPackTable(DBHandle, Handle, Nil, Nil, RegenIndexes));
      finally
        { update Delphi from BDE }
        CursorPosChanged;
        Refresh;
      end;
    end;procedure TdBaseTable.SetViewDeleted(Value: Boolean);
    { Allows the user to toggle between viewing and not viewing }
    { deleted records. }
    begin
      { Table must be active }
      if Active and (FViewDeleted <> Value) then begin
        DisableControls;     // avoid flicker
        try
          { Magic BDE call to toggle view of soft deleted records }
          Check(dbiSetProp(hdbiObj(Handle), curSOFTDELETEON, Longint(Value)));
        finally
          Refresh;           // update Delphi
          EnableControls;    // flicker avoidance complete
        end;
        FViewDeleted := Value
      end;
    end;procedure TdBaseTable.UndeleteRecord;
    begin
      if not IsDeleted then
        raise EDatabaseError.Create('Record is not deleted');
      Check(dbiUndeleteRecord(Handle));
      Refresh;
    end;function TParadoxTable.CreateHandle: HDBICur;
    { Overridden from ancestor in order to perform a check to }
    { ensure that this is a Paradox table. }
    var
      CP: CURProps;
    begin
      Result := inherited CreateHandle;         // do inherited
      if Result <> Nil then begin
        { Get cursor properties, and raise exception if the }
        { table isn't using the Paradox driver. }
        Check(dbiGetCursorProps(Result, CP));
        if not (CP.szTableType = szPARADOX) then
          raise EDatabaseError.Create('Not a Paradox table');
      end;
    end;function TParadoxTable.GetRecNum: Longint;
    { Returns the sequence number of the current record. }
    begin
      UpdateCursorPos;             // update BDE from Delphi
      { Get sequence number of current record into Result }
      Check(dbiGetSeqNo(Handle, Result));
    end;procedure TParadoxTable.Pack;
    var
      TblDesc: CRTblDesc;
      TempDBHandle: HDBIDb;
      WasActive: Boolean;
    begin
      { Initialize TblDesc record }
      FillChar(TblDesc, SizeOf(TblDesc), 0); // fill with 0s
      with TblDesc do begin
        StrPCopy(szTblName, TableName);      // set table name
        szTblType := szPARADOX;              // set table type
        bPack := True;                       // set pack flag
      end;
      { Store table active state.  Must close table to pack. }
      WasActive := Active;
      if WasActive then Close;
      try
        { Create a temporary database.  Must be read-write/exclusive }
        Check(dbiOpenDatabase(PChar(DatabaseName), Nil, dbiREADWRITE,
              dbiOpenExcl, Nil, 0, Nil, Nil, TempDBHandle));
        try
          { Pack the table }
          Check(dbiDoRestructure(TempDBHandle, 1, @TblDesc, Nil, Nil, Nil,
                False));
        finally
          { Close the temporary database }
          dbiCloseDatabase(TempDBHandle);
        end;
      finally
        { Reset table active state }
        Active := WasActive;
      end;
    end;end.
      

  2.   

    TO: wk_knife(世界看美国) 
    这个方法能实现吗?我试了一下,好象不行。
    我的思想与你的不同。
      

  3.   

    DBF和Paradox都可以pack,
    dbTable.pas中有描述。
      

  4.   

    用函数packtable就行啦procedure PackTable(Table: TTable);
    var
      Props: CURProps;
      hDb: hDBIDb;
      TableDesc: CRTblDesc;begin
      // Make sure the table is open exclusively so we can get the db handle...
      if Table.Active = False then
        raise EDatabaseError.Create('Table must be opened to pack');
      if Table.Exclusive = False then
        raise EDatabaseError.Create('Table must be opened exclusively to pack');  // Get the table properties to determine table type...
      Check(DbiGetCursorProps(Table.Handle, Props));  // If the table is a Paradox table, you must call DbiDoRestructure...
      if Props.szTableType = szPARADOX then
      begin
        // Blank out the structure...
        FillChar(TableDesc, sizeof(TableDesc), 0);
        //  Get the database handle from the table's cursor handle...
        Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
        // Put the table name in the table descriptor...
        StrPCopy(TableDesc.szTblName, Table.TableName);
        // Put the table type in the table descriptor...
        StrPCopy(TableDesc.szTblType, Props.szTableType);
        // Set the Pack option in the table descriptor to TRUE...
        TableDesc.bPack := True;
        // Close the table so the restructure can complete...
        Table.Close;
        // Call DbiDoRestructure...
        Check(DbiDoRestructure(hDb, 1, @TableDesc, nil, nil, nil, FALSE));
      end
      else
        // If the table is a dBASE table, simply call DbiPackTable...
        if Props.szTableType = szDBASE then
          Check(DbiPackTable(Table.DBHandle, Table.Handle, nil, szDBASE, TRUE))
        else
          // Pack only works on PAradox or dBASE; nothing else...
          raise EDatabaseError.Create('Table must be either of Paradox or dBASE ' +
                   'type to pack');  Table.Open;
    end;
      

  5.   

    二楼上的东西实质上与我的是一样的。
    DbiPackTable(用于DBase),DbiDoRestructure(用于Paradox)另Pack并不是真正意义上的压缩,它的作用只是清除被删除的记录,是“紧缩”而非“压缩”。
    题目说的并不是很清楚,我只是照文字来回答一下。更确切的说是从tip中挖了一段。
    不知Tense(何必)大侠的想法是什么?愿闻其详。我因为专业的原因,对数据库方面了解不多。