Entwickler-Ecke

Sonstiges (Delphi) - Frage zu einer "SaveAsExcelFile" Prozedur......


pesi - Mo 17.05.10 12:17
Titel: Frage zu einer "SaveAsExcelFile" Prozedur......
Hallo,
ich benutze die unten angegebene Function um ein Stringgrid im XLS-Format abzuspeichern (stammt irgendwoher aus dem Internet - ich tippe auf swiss-delphi-center). Hat in der Vergangenheit in unterschiedlichsten kleinen Programmen auch immer gut funktioniert, aber leider habe ich jetzt wohl erstmals in einer Grid-Zelle einen Text drin der länger als 256 Zeichen ist und dann erscheint im XLS leider einfach nur eine leere Zelle :-(
Ich ich mich in der Vergangenheit noch so gar nicht mit Streams beschäftigt habe, ist die Funktion für mich ein großes schwarzes Loch! Ja ja jaaaa... ich könnte mich jetzt vielleicht 2 Wochen lang mit der Logik von Buffern, Streams etc. beschäftigen, aber ich versuche es einfach erst mal hier. Vielleicht hat ja jemand eine Idee ob und wie ich diese Funktion dazu bringen kann längere Texte zu übergeben. (Und JA, ihr dürft mich auch anschließend wüst beschimpfen, dass ich es doch lieber selber lösen soll etc. etc.....)
1000000 Dank & Gruß
Peter

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
function TForm1.SaveAsExcelFile(AGrid: TStringGrid; AFileName: string): Boolean;
const
  {$J+} CXlsBof: array[0..5of Word = ($809800$1000); {$J-}
  CXlsEof: array[0..1of Word = ($0A00);
var
  FStream: TFileStream;
  I, J: Integer;
begin
  Result := False;
  FStream := TFileStream.Create(PChar(AFileName), fmCreate or fmOpenWrite);
  try
    CXlsBof[4] := 0;
    FStream.WriteBuffer(CXlsBof, SizeOf(CXlsBof));
    for i := 0 to AGrid.ColCount - 1 do
      for j := 0 to AGrid.RowCount - 1 do
        XlsWriteCellLabel(FStream, I, J, AGrid.cells[i, j]);
    FStream.WriteBuffer(CXlsEof, SizeOf(CXlsEof));
    Result := True;
  finally
    FStream.Free;
  end;
end;


Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Tryer - Mo 17.05.10 12:25


Delphi-Quelltext
1:
XlsWriteCellLabel(FStream, I, J, AGrid.cells[i, j])                    

ist die interessante Funktion.

Grüsse, Dirk


pesi - Mo 17.05.10 14:31

Oh man... heute ist nicht mein Tag....
Hier die andere Prozedur, die ich auch leider nur eingeschränkt verstehe....

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.XlsWriteCellLabel(XlsStream: TStream; const ACol, ARow: Word;
  const AValue: string);
var
  L: Word;
const
  {$J+}
  CXlsLabel: array[0..5of Word = ($20400000);
  {$J-}
begin
  L := Length(AValue);
  CXlsLabel[1] := 8 + L;
  CXlsLabel[2] := ARow;
  CXlsLabel[3] := ACol;
  CXlsLabel[5] := L;
  XlsStream.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel));
  XlsStream.WriteBuffer(Pointer(AnsiString(AValue))^, L);
end;


Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Chemiker - Mo 17.05.10 14:41

Hallo pesi,

pesi hat folgendes geschrieben:
aber leider habe ich jetzt wohl erstmals in einer Grid-Zelle einen Text drin der länger als 256 Zeichen

ist die Zeichenanzahl in Excel nicht auf 255 Zeichen begrenzt?

Bis bald Chemiker


JoelH - Mo 17.05.10 15:03

Nein ist sie nicht ;)

Empirisch überprüft, Einfach mal 300 Zeichen eingegeben ;)


pesi - Mo 17.05.10 15:16

Hmmm.... die Anzahl ist vermutlich nur in den aktuellen Versionen nicht mehr begrenzt (oder zumindest liegt die Grenze deutlich höher), aber diese Funktion erstellt noch eine XLS-Datei in einem "uralt" Excel Format.
Ich hab mir gerade mal eine solche XLS-Datei in einem Editor angeschaut (JAaaaa.... hätte ich vielleicht mal früher machen sollen - ich weiss....) und dabei festgestellt, dass der Inhalt aus dem Stringgrid sogar korrekt abgelegt ist, nur nach dem Öffnen in Excel wird der Inhalt nicht angezeigt.
....was mich zu der Überlegung kommen lässt, diese Prozedure vielleicht besser gar nicht mehr zu verwenden - wer weiss wie lange dieses alte XLS-Format von modernen Excel-Versionen überhaupt noch unterstützt wird - oder aber direkt auf 255 Zeichen abzuschneiden. Dann fehlt mir zwar etwas an Information, aber besser etwas Information als ein ganz leeres Feld :-((
Blöd blöd blöd........ Jemand bessere Ideen auf Lager?


Tryer - Mo 17.05.10 20:54

Andersherum kann man es auch verifizieren, einfach eine Zelle mit >255 Zeichen füllen und unter altem Format (Save as..) abspeichern, dann fehlt ein ganzer Teil.
Bleibt nur eine aktuellere Implementierung, der Weg über OLE, oder selber machen mit Infos von hier [http://www.wotsit.org/list.asp?search=xls&button=GO!].

Grüsse, Dirk


DonManfred - Di 18.05.10 11:05

user profile iconTryer hat folgendes geschrieben Zum zitierten Posting springen:
Bleibt nur eine aktuellere Implementierung, der Weg über OLE, oder selber machen


oder mit der Komponente TMS FlexCel Studio for VCL/LCL [http://www.tmssoftware.com/site/flexcel.asp]


Tryer - Di 18.05.10 12:43

Sowas meinte ichmit Aktuele Implementierung, halt eine Kompo/Unit die das kann.

Grüsse, Dirk


pesi - Di 18.05.10 16:13

Hallo DonM.
diese Kompo sieht gar nicht schlecht aus. Okay, sie kostet etwas, aber der Preis ist jetzt wahrlich nicht extrem hoch. Mal schauen.....
Danke für Eure Hilfe!


DonManfred - Di 18.05.10 23:46

Ich kann die Kompo empfehlen... Ich stand letztens vor dem Problem, das mein Chef mir eine Excel-Datei gegeben hat, die ein Bestellformular von einem Lieferanten enthielt. Ich sollte eine Routine schreiben, die bestimmte Artikel eines Auftrages dort automatisch eintrug (samt Bild)...

Nachdem ich das System erstmal verstanden hatte war das ganze schnell erledigt.

Exceldatei geladen, Daten an die ensprechenden Felder eingetragen, Bilder eingefügt, das ganze als neues Excel-Sheet gespeichert und fertig.

Echt klasse Routinen. Ok, ich hatte den Vorteil, das ich eine TMS Subscription habe und die Kompo war eh in meinem Paket mit drin... Aber so kam sie schnell zum erfolgreichen Einsatz;vorher keine echte Verwendung dafür gehabt.