Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Mein Programm gibt erzeugtes xls - File nicht frei (https://www.delphipraxis.net/55042-mein-programm-gibt-erzeugtes-xls-file-nicht-frei.html)

padavan 15. Okt 2005 15:58


Mein Programm gibt erzeugtes xls - File nicht frei
 
Hallo Leute,

mit diesen Code (und einer externen Unit)

Delphi-Quellcode:
if Savedialog2.Execute then begin
  if extractfileext(savedialog2.FileName) = '.xls' then XLSFile := TXLSExport.Create(Savedialog2.FileName)
  else XLSFile := TXLSExport.Create(Savedialog2.FileName + '.xls');
    try
      for iRow := 0 to StringGrid1.RowCount - 1 do
      for iCol := 0 to StringGrid1.ColCount - 1 do
      if iRow = 0 then // Ausgabe Spaltenköpfe als string
        xlsfile.Write(iCol, iRow, StringGrid1.Cells[iCol, iRow])
      else // der Rest sind integer Werte
        xlsfile.Write(iCol, iRow, (*StrToInt*)(StringGrid1.Cells[iCol,iRow]));
    finally
      xlsfile.Free;
    end;
  Showmessage(Savedialog2.FileName + '.xls was created');
erzeuge ich ein Excel-File.

mit dieser Zeile

Delphi-Quellcode:
  xlsfile.Free;
dachte ich, gebe ich die Datei frei.
Leider kann ich das Excel-File erst öffnen, wenn ich mein Programm geschlossen hab.
Warum?

Eichhoernchen 15. Okt 2005 16:06

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
hmm vielleicht gibt es noch was anderes als free, free löscht ja lediglich das Objekt aus dem Speicher, vielleicht gibt es irgendwie sowas wie .close was die Datei wieder freigibt!

Ich weiß ja nicht was deine KLasse: TXLSExport alles da kann, ich kenn die nicht

LoRd-MuldeR 15. Okt 2005 16:14

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
Ich denke mal der Handle zu der Datei wurde noch nich geschlossen. Den Handel aus dem Speicher zu löschen (was ja mit .Free geschieht) schließt ihn ja nich! Das schließen des Handles muss unbedingt vor dem Löschen aus dem Speicher geschehen. Eigentlich sollte das spätestens im Destructor passieren, was aber hier offenbar nicht der Fall ist. Entweder wurde das vergessen, oder es gibt eine spezielle Methode dafür. In letzterem Fall musst du den Handle zuerst über die entsprechende Methode schließen, bevor du .Free aufrufst.

Würde helfen, wenn du mal deine "TXLSExport" Object vollständig posten würdest...

padavan 15. Okt 2005 16:22

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
Hm,
close läuft schon auf einen Fehler bei der Syntaxprüfung,
da ich nichts mit "open" aufmache, kann ich´s mit "close" auch nicht schließen nehme ich an...
:|

Hier kommt die externe Unit....

Delphi-Quellcode:
unit u_ExportEXCEL;

interface
uses classes;

type TXLSExport = class(TObject)
                  private
                     fs : TFilestream;
                  public
                     constructor Create(filename : string);
                     destructor Destroy; override;
                     procedure Write(const Col, Row: Word; const Value: Integer); overload;
                     procedure Write(const Col, Row: Word; const Value: Double); overload;
                     procedure Write(const Col, Row: Word; const Value: string); overload;
                  end;


implementation

const
  CXlsBof   : array[0..5] of Word = ($809, 8, 00, $10, 1, 0);
  CXlsEof   : array[0..1] of Word = ($0A, 00);
  CXlsLabel : array[0..5] of Word = ($204, 0, 0, 0, 0, 0);
  CXlsNumber : array[0..4] of Word = ($203, 14, 0, 0, 0);
  CXlsRk    : array[0..4] of Word = ($27E, 10, 0, 0, 0);


constructor TXLSExport.Create(filename : string);
begin
  inherited Create;
  fs := TFileStream.Create(filename,fmCreate);
  fs.WriteBuffer(CXlsBof, SizeOf(CXlsBof));
end;

destructor TXLSExport.Destroy;
begin
  fs.WriteBuffer(CXlsEof, SizeOf(CXlsEof));
  inherited Destroy;
end;

procedure TXLSExport.Write(const Col, Row: Word; const Value: Integer);
var
  V: Integer;
begin
  CXlsRk[2] := Row;
  CXlsRk[3] := Col;
  fs.WriteBuffer(CXlsRk, SizeOf(CXlsRk));
  V := (Value shl 2) or 2;
  fs.WriteBuffer(V, 4);
end;

procedure TXLSExport.Write(const Col, Row: Word; const Value: Double);
begin
  CXlsNumber[2] := Row;
  CXlsNumber[3] := Col;
  fs.WriteBuffer(CXlsNumber, SizeOf(CXlsNumber));
  fs.WriteBuffer(Value, 8);
end;

procedure TXLSExport.Write(const Col, Row: Word; const Value: string);
var L: Word;
begin
  L := Length(Value);
  CXlsLabel[1] := 8 + L;
  CXlsLabel[2] := Row;
  CXlsLabel[3] := Col;
  CXlsLabel[5] := L;
  fs.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel));
  fs.WriteBuffer(Pointer(Value)^, L);
end;

end.

Bernhard Geyer 15. Okt 2005 16:23

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
Im Destruktor fehlt eine
Delphi-Quellcode:
  fs.Free;

padavan 15. Okt 2005 16:34

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
Jetzt wird´s wieder komisch.
Den Fall hatte ich neulich schonmal.

Habe fs.free im Destructor einfügen wollen,
danach läuft´s auf eine Fehlermeldung:
"der linken Seite kann nichts zugewiesen werden"
bei
Delphi-Quellcode:
  CXlsRk[2] := Row;
Wollte es wieder entfernen, trotzdem geht´s nicht mehr.

Hat aber nichts mit Bernard´s Vorschlag zu tun, sondern das Phänomen hatte ich neulich schonmal.
Seltsamerweise regt sich der D2005PE-Compiler nicht darüber auf, nur der D7Enterprise-Compiler.
Sehr sehr eigenartig.

zumal es bis eben ging, dann öffnet man die Unit, macht alle Änderungen rückgängig...und trotzdem, jetzt kommt der Fehler.
:wiejetzt:

Eichhoernchen 15. Okt 2005 16:49

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
Zitat:

Zitat von F1
Der Destruktor gibt eine Instanz von TFileStream frei.

Delphi-Syntax:

destructor Destroy; override;

Beschreibung

Rufen Sie Destroy in einer Anwendung nicht direkt auf. Verwenden Sie stattdessen Free. Die Methode Free überprüft zuerst, ob die TFileStream-Referenz nicht bereits nil ist und ruft Destroy nur bei Bedarf aufd.

Destroy schließt das Handle für den Datei-Stream, bevor das Objekt aufgelöst wird.

Hmm also musst du im destructor der Klasse aufjedenfall den TFilestream freigeben.
Also wie schon jemand gesagt hat FS.free; muss darein!
oder sowas wie FreeAndNil(fs);


Wo hast du denn das Fs.free stehen? Nach oder vor inherited Destroy; ??

padavan 15. Okt 2005 22:48

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
danach!,
aber hab dann nicht weiter ausprobieren können, da ich dann auf diese seltsame Problem stieß.
Irgenwas stimmt mit der Unit nicht, es ist schon komisch, dass sie zumindest auf das Problem mit den Freigeben einmal funktioniert und nachdem ich sie öffne und ohne zu speichern schließe sie auf einmal nicht funzt. Mit der Fehlermeldung:

Zitat:

"der linken Seite kann nichts zugewiesen werden"
bei
Delphi-Quellcode:
CXlsRk[2] := Row;


Eichhoernchen 15. Okt 2005 22:56

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
Aber müsste es nicht davor??
Ich meine sonst ist die Instanz der Klasse ja schon weg und vielleicht kannste ja dann nicht mehr die Eigenschaft der klasse destroyen..

Und irgendwie verstehe ich den Compiler^^:

Delphi-Quellcode:
const
  CXlsBof   : array[0..5] of Word = ($809, 8, 00, $10, 1, 0);
  CXlsEof   : array[0..1] of Word = ($0A, 00);
  CXlsLabel : array[0..5] of Word = ($204, 0, 0, 0, 0, 0);
  CXlsNumber : array[0..4] of Word = ($203, 14, 0, 0, 0);
  CXlsRk    : array[0..4] of Word = ($27E, 10, 0, 0, 0);

...
CXlsRk[2] := Row;
du hast da ne Konstante deklariert aber willst den Wert ändern, ersetz mal const durch var!

Bernhard Geyer 16. Okt 2005 09:18

Re: Mein Programm gibt erzeugtes xls - File nicht frei
 
Zitat:

Zitat von Eichhoernchen
...

Und irgendwie verstehe ich den Compiler^^:

Delphi-Quellcode:
const
  CXlsBof   : array[0..5] of Word = ($809, 8, 00, $10, 1, 0);
  CXlsEof   : array[0..1] of Word = ($0A, 00);
  CXlsLabel : array[0..5] of Word = ($204, 0, 0, 0, 0, 0);
  CXlsNumber : array[0..4] of Word = ($203, 14, 0, 0, 0);
  CXlsRk    : array[0..4] of Word = ($27E, 10, 0, 0, 0);

...
CXlsRk[2] := Row;
du hast da ne Konstante deklariert aber willst den Wert ändern, ersetz mal const durch var!

Das obige Konstrukt geht auch wenn die Compiler-Option "Zuweisbare typisierte Konstanten" gesetzt wurde.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:13 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz