AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein virtualstringtree in excel exportieren
Thema durchsuchen
Ansicht
Themen-Optionen

virtualstringtree in excel exportieren

Ein Thema von youuu · begonnen am 13. Jul 2010 · letzter Beitrag vom 20. Jul 2010
 
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#8

AW: virtualstringtree in excel exportieren

  Alt 15. Jul 2010, 13:40
Da muß ich ein wenig wiedersprechen.

Fakt ist man muß eine Konvertierung machen, ob StringGrid, VST oder sonstwas.

Da unser Export mit unterschiedlichen "Grids" arbeiten können soll, habe ich eine "Wrapper"-Klasse geschrieben, damit die eingentliche Exportklasse übersichtlich bleibt.

Hier ein paar Ansätze:
Delphi-Quellcode:
procedure TExcelServer.WriteRange(Row, Col, RowCount, ColCount: integer; Values: OleVariant);
begin
  ExcelWorksheet.Range[
    TranslateCell(Row + 1, Col + 1),
    TranslateCell(Row + RowCount, Col + ColCount)].Value := Values;
end;
Das ist die schnellste Variante GROSSE Datenmengen an Excel zu senden. (TranslateCell macht aus Integer die Excel Spalten/Zeilen-bezeichnungen)

Der OleVariant wird in der "Wrapper"-Klasse erzeugt:
Delphi-Quellcode:
function TDataWrapper.GetDataOle : OleVariant;
var
  i, iRow, iCol : Longint;
  bm : TBookmark;
  FNodeData : PGridTreeData;
  FNode : PVirtualNode;
begin
  Result := VarArrayCreate([0, RowCount - 1,
                            0, ColCount - 1], varVariant);

  {$REGION 'FAdvStringGridLink'}
  if Assigned(FAdvStringGridLink) then
  begin
    for iCol := 0 to ColCount - 1 do
    begin
      for iRow := 0 to RowCount - 1 do
      begin
        Result[iRow, iCol] := FAdvStringGridLink.Cells[iRow, iCol];
      end;
    end;
  end;
  {$ENDREGION}

  {$REGION 'FVirtualStringTreeLink'}
  if Assigned(FVirtualStringTreeLink) then
  begin
    with FVirtualStringTreeLink do
    begin
      FNode := GetFirst;

      for iRow := 0 to RowCount - 1 do
      begin
        FNodeData := GetNodeData(FNode);
        for iCol := 0 to ColCount - 1 do
        begin
          Result[iRow, iCol] := FNodeData^.Columns[iCol];
        end;

        FNode := GetNext(FNode);
      end;
    end;
  end;
  {$ENDREGION}

  {$REGION 'FDataSourceLink'}
  if Assigned(FDataSourceLink) then
  begin
    with FDataSourceLink.DataSet do
    begin
      DisableControls;
      bm := GetBookmark;
      First;
      iRow := 0;

      while (not Eof) do
      begin
        i := 0;
        for iCol := 0 to FieldCount - 1 do
        begin
          if Fields[iCol].Visible then
          begin
            Result[iRow, i] := Fields.Fields[iCol].AsString;
            inc(i);
          end;
        end;

        Next;
        inc(iRow);
      end;

      GotoBookmark(bm);
      FreeBookmark(bm);
      EnableControls;
    end;
  end;
  {$ENDREGION}
end;
RowCount und ColCount wird auch so ermittelt.
Der OleVariant aus GetDataOle kann wie ein Stringgrid benutzt werden, was ich für zusätzliche Formatierungen ausnutze. z.B.:
Delphi-Quellcode:
...
          {$REGION 'Werte ggf. formatieren und dann einfügen —————————————————————————————'}
          if iMonat > -1 then
          begin
            for iRow := 0 to AData.RowCount - 1 do
              OleGrid[iRow, iMonat] := '01.' + OleGrid[iRow, iMonat];
          end;

          if (FExcelServer.Version.Major >= 11) then
          begin
            if iDatum > -1 then
            begin
              OleGrid[iRow, iDatum] := StrToDateTime(OleGrid[iRow, iDatum]);
            end;
          end;
...
          {$REGION 'Daten schreiben ——————————————————————————————————————————————————————'}
          FExcelServer.WriteRange(FStartRow,
                                  FStartCol,
                                  AData.RowCount,
                                  AData.ColCount,
                                  OleGrid);
          {$ENDREGION}
...
Ich benutzt übrigens Early-binding um wenigstens ein bisschen Kontrolle zu behalten. (Sollte man bei solchen Problemen immer dazu sagen, erleichter das Verständnis ungemein)

Um jetzt auf das Wiedersprechen zu kommen:
man kann natürlich die Werte einzeln nach Excel schreibe:
Delphi-Quellcode:
  {$REGION 'FVirtualStringTreeLink'}
  if Assigned(FVirtualStringTreeLink) then
  begin
    with FVirtualStringTreeLink do
    begin
      FNode := GetFirst;

      for iRow := 0 to RowCount - 1 do
      begin
        FNodeData := GetNodeData(FNode);
        for iCol := 0 to ColCount - 1 do
        begin
          Result[iRow, iCol] := FNodeData^.Columns[iCol]; // Hier kann man statt den Variant zu füllen auch gleich Excel füttern
        end;

        FNode := GetNext(FNode);
      end;
    end;
  end;
  {$ENDREGION}
Diese Variante ist aber um mehrere Größenordnungen langsamer!

Gruß David

Geändert von David Martens (15. Jul 2010 um 13:46 Uhr)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz