Pakowanie tabeli poraz kolejny

0

Dysponuję takim oto kodem. W założeniu miał on "pakować" tabelę typu Paradox z poziomu programu w Delphi, niestety nie działa. Żeby uprzedzić uwagi na temat skutecznego szukania informuję że 2 kody jakie można znaleźć na forum 4programmers nie dają się nawet skompilować, ich autorzy chyba celowo umieścili w nich błędy. Kod poniżej daje się kompilować a zmiany są niewielkie.

treść funkcji:

function PackParadoxTable(Table: TTable): DBIResult;
var
  td: CRTblDesc;
  Database: TDatabase;
begin
  Result := DBIERR_NA;
  try
    begin
    Database := Table.Database;
    if Table.Active then Table.Close;
    if not Database.Connected then Database.Connected := True;
    Result := DBIERR_NA;
    FillChar(td, SizeOf(td), 0);
    StrPCopy(td.szTblName, Table.TableName);
    td.bPack := True;
    if DbiDoRestructure(Database.Handle, 1, @td, nil, nil, nil, False) <> DBIERR_NONE then
      Result := DBIERR_NONE;
    end;
  except
    Result := DBIERR_NONE;
  end;
end;

no i oczywiście jej wywołanie

PackParadoxTable(Table1);

Jakieś pomysły co jest nie tak jak być powinno?
Z góry dziękuję za zaangażowanie i pomoc.

0

Kolejny raz zwracam sie o pomoc do forumowiczów 4programmers, bo brak mi już cierpliwości i sam nie wiem już gdzie robię błąd.

Poniższy kod odpowiada za dopasowanie ilości wierszy tabeli do liczby wybranej przez użytkownika w kontrolce ComboBox. Jednak po takiej operacji indeksy nie mają charakteru porządkowego, należy tabelę "spakować". I tu pojawia się zasadniczy problem. Ciągle wywala błędy.

procedure TForm3.ComboBox3Change(Sender: TObject);
var i,j,k :Integer;
begin
  i:=0;
  Table1.First;
  while not Table1.Eof do
    begin
      Inc(i);
      Table1.Next
    end;
  edit2.Text:=inttostr(i);
  j:=StrToInt(ComboBox3.Text);
  if j>i then
    begin
      Table1.Last;
      for k:=1 to j-i do
        begin
          Table1.Insert;
          Table1.Post
        end;
    end;
  if j<i then
    begin
      for k:=j to i-1 do
        begin
          Table1.Last;
          Table1.Delete;
        end;
    end;
      Table1.Active:=false;
      Table1.Exclusive:=true;
      PackTable(Table1);

    Table1.Active:=True;
end;

Procedura pakowania tabeli pobrana ze strony Borland'a http://info.borland.com/devsupport/bde/bdeapiex/dbidorestructure.html

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;

"Table must be opened to pack." to błąd jaki wyskakuje przy obecnej konfiguracji, jeśli zmienię na

      
      Table1.Active:=True;
      Table1.Exclusive:=true;
      PackTable(Table1);

"Cannot perform this operation on an open dataset"

natomiast jeśli nie wywołam Table1.Exclusive to wyskakuje błąd

"Table must be opened Exclusively to pack"

Proszę o pomoc bo brak mi już pomysłów.
</delphi></i>

0

Jednak po takiej operacji indeksy nie mają charakteru porządkowego, należy tabelę "spakować"

ech chyba za bardzo nie wiesz co to są indexy, to zdanie na pewno nie jest prawdziwe

BTW
Table1.Exclusive:=true;
Table1.Active:=True;

0

Otóż mój drogi kolego może i niewłaściwie napisałem to zdanie. To fakt że indeks to co innego, a pole Index (autonumerowane) stworzone przeze mnie to coś innego, ale widzę że i tak uchwyciłeś o co mi chodzi. Niestety, z kodem zaproponowanym przez Ciebie również nie działa, znów "wyrzuca" błąd:
"Cannot perform this operation on an open dataset".

0

ale przed Table1.Exclusive:=true; musisz mieć zamkniętą tabelę

0

OK już działa, dzięki.
A masz jakiś pomysł żeby pole typu autoincrement nie miało przeskoków w postaci (1,2,3,44,45,46) po usunięciu pewnych rekordów. Miałem nadzieje że pakowanie załatwi sprawę ale niestety nie dało rady.

0

pole autoinc nie służy do numerowania rekordów tylko do nadawania im unikalnych id

0

Wiem ale miałem cichą nadzieję ze da sie je wykorzystać do ponumerowania wierszy w tabeli, iże będzie mieć to charakter porządkowy po usunięciu kilku rekordów i jakiejś (sam nie wiem jakiej) modyfikacji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1