Logo

  DELPHI - FAQ

  Delphi-FAQ | Allgemeine Tipps | Grafik | Datenbanken | VCL | DLL-Programmierung |
 
  Delphi-FAQ | Datenbanken | dBase |
  Keine Darstellung von numerischen Feldern

In dBASE - Dateien, die von anderen Programmen erstellt wurden, sind in Delphi die numerische Felder scheinbar leer. In dBASE III o.ä. Programmen werden sie aber angezeigt. Hintergrund: In dBASE - Dateien werden Zahlen als Zeichenkette mit den entsprechenden Dezimalstellen abgelegt. Dabei werden nicht benötigte Stellen linksbündig mit Leerzeichen aufgefüllt. (z.B. 2.54 --> xxx2.54 {x = Leerzeichen}). Speichert das Fremdprogramm die Zahl aber als xx2.54x, kann Delphi damit nichts anfangen, die Felder sind scheinbar leer. Hilfe Solche Dateien müssen konvertiert werden. Folgende Prozedur korrigiert die Datei. Dabei wird zur Sicherheit erst abgespeichert, wenn die Routine fehlerfrei durchlaufen wurde.
type
  TDBFKopf = packed record
    Version: Byte;
    Zugriff: array[0..2] of char;
    RecCount: LongInt;
    HaederSize: SmallInt;
    RecordSize: SmallInt;
    Dummy: array[0..19] of Char;
  end;

  TDBFFeld = packed record
    Name: array[0..10] of Char;
    Typ: Char;
    Adress: LongInt;
    Size: byte;
    Decimal: byte;
    Dummy: array[0..13] of Char;
  end;
  TDbfFelder = array[0..255] of TDBFFeld;

procedure DBF_Reparieren(TableName: TFileName);
var
  Ziel, Quelle      : TFileStream;
  FieldCount        : integer;
  Kopf              : TDBFKopf;
  Felder            : ^TDBFFelder;
  z, i              : Integer;
  c                 : Char;
  Daten             : PChar;
  isKorr            : boolean;
  procedure Korr_Datensatz;
  var
    s               : ShortString;
    z, l            : integer;
    falsch          : boolean;
  begin
    for z := 0 to FieldCount - 1 do begin
      s := '';
      for l := 0 to Felder^[z].Size - 1 do
        s := s + Daten[Felder^[z].Adress + l];
      Falsch := false;
      case Felder^[z].Typ of
        'N': if (trim(s) <> '') and (s <> TrimRight(s)) then begin
            s := LFill(TrimRight(s), Felder^[z].Size);
            Falsch := true;
          end;
      end;
      if Falsch then begin
        isKorr := true;
        for l := 0 to Felder^[z].Size - 1 do
          Daten[Felder^[z].Adress + l] := s[l + 1];
      end;
    end;
  end;
begin
  isKorr := false;
  Quelle := TFileStream.Create(ChangeFileExt(TableName, '.DBF'),
        fmOpenRead);
  Ziel := TFileStream.Create(ChangeFileExt(TableName, '.$$$'),
        fmCreate);
  try
    Quelle.ReadBuffer(Kopf, SizeOf(Kopf));
    FieldCount := (Kopf.HaederSize - 1) div 32 - 1;
    GetMem(Felder, FieldCount * SizeOf(TDbfFeld));
    GetMem(Daten, Kopf.RecordSize);
    try
      Quelle.ReadBuffer(Felder^, FieldCount * SizeOf(TDbfFeld));
      Quelle.ReadBuffer(c, SizeOf(c));
      if c <> #$0D then
// Kopf richtig eingelesen ?
        raise Exception.Create('Kopf ist Falsch');
// Dateikopf ist o.k --> zurückspeichern
      Ziel.WriteBuffer(Kopf, SizeOf(Kopf));
      Ziel.WriteBuffer(Felder^, FieldCount * SizeOf(TDbfFeld));
      Ziel.WriteBuffer(c, SizeOf(c));
      i := 1;
// Löschflag übergehen
      for z := 0 to FieldCount - 1 do begin
        Felder^[z].Adress := i;
        i := i + Felder^[z].Size;
      end;
      if i <> Kopf.RecordSize then
// Felddefinitionen richtig ?
        raise Exception.Create('Feldgröße ist falsch');
      for z := 0 to Kopf.RecCount - 1 do begin
        Quelle.ReadBuffer(Daten^, Kopf.RecordSize);
        Korr_Datensatz;
        Ziel.WriteBuffer(Daten^, Kopf.RecordSize);
      end;
      Quelle.Read(c, SizeOf(c));
      if c <> #$1A then
// Endekennzeichen ?
        raise Exception.Create('Länge der Datei ist falsch');
      Ziel.WriteBuffer(c, SizeOf(c));
    finally
      FreeMem(Daten);
      FreeMem(Felder);
    end;
  finally
    Quelle.Free;
    Ziel.Free;
  end;
  if isKorr then begin
    if Sysutils.DeleteFile(ChangeFileExt(TableName, '.dbf')) then
      RenameFile(ChangeFileExt(TableName, '.$$$'),
           ChangeFileExt(TableName, '.DBF'));
  end;
  SysUtils.DeleteFile(ChangeFileExt(TableName, '.$$$'));
end;




 26.01.2006 © wlsoft www.wlsoft.de