AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Excelexport

Ein Thema von Borschti · begonnen am 18. Jul 2008 · letzter Beitrag vom 24. Jul 2008
Antwort Antwort
Seite 1 von 2  1 2      
Borschti

Registriert seit: 1. Nov 2007
Ort: Marburg Lahn
235 Beiträge
 
Delphi 2007 Professional
 
#1

Problem mit Excelexport

  Alt 18. Jul 2008, 13:49
Hallo,

ich habe ein Problem mit dem Exportieren einer Datenmenge nach Excel, also meine procedure läuft wunderbar auf Rechnern auf denen Excel installiert ist, aber wen Excel nicht installiert ist kommt eine Fehlermeldung das die classID (oder so ähnlich) nicht registriert ist.

Also meine Frage jetzt: Wie kann ich meine procedure möglichst einfach verändern das sie auch auf Rechnern angewandt werden kann auf denen kein Excel installiert ist

Hier mal mein derzeitiger Code:

Delphi-Quellcode:
procedure ExcelExport(SaveDialog : TSaveDialog; ExcelAppli : TExcelApplication;
                      ExcelWb : TExcelWorkbook; ExcelWsht : TExcelWorksheet;
                      Query : TVddQuery);

var Filename, CoordCounter: String;
    oleArray1, oleArray2:OleVariant;
    i, z, flcid : Integer;
    sl, sl2 : TStringlist;
begin

  Screen.Cursor := crHourglass;

  SaveDialog.Execute;

    case SaveDialog.FilterIndex of
      1: Filename := ChangeFileExt(SaveDialog.FileName,'.xls');
      2: Filename := ChangeFileExt(SaveDialog.FileName,'.xls');
    end;

    if Filename <> 'then
      begin
        flcid:=GetUserDefaultLCID;
        ExcelAppli.Connect;
        ExcelAppli.Visible[flcid]:=true;
        ExcelAppli.UserControl:=true;

        CreateFile(@Filename[1], 0, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

        ExcelWb.ConnectTo(ExcelAppli.Workbooks.Open(filename, False,
        False, EmptyParam, '', False, False, EmptyParam, EmptyParam, false, false,
        EmptyParam, EmptyParam, EmptyParam, false, 0));
        ExcelWsht.ConnectTo(ExcelWb.Sheets.Item[1] as ExcelWorkSheet);

        sl := TStringList.Create;
        sl2 := TStringList.Create;
        Query.GetFieldNames(sl);

        OleArray1 := VarArrayCreate([0, Query.RecordCount], varVariant);
        OleArray2 := VarArrayCreate([0, sl.Count], varVariant);

        for z := 0 to sl.Count - 1 do
          begin
            OleArray2[z] := sl.Strings[z];
          end;

        sl2.Add('A');
        sl2.Add('B');
        sl2.Add('C');
        sl2.Add('D');
        sl2.Add('E');
        sl2.Add('F');
        sl2.Add('G');
        sl2.Add('H');
        sl2.Add('I');
        sl2.Add('J');
        sl2.Add('K');
        sl2.Add('L');
        sl2.Add('M');
        sl2.Add('N');
        sl2.Add('O');
        sl2.Add('P');
        sl2.Add('Q');
        sl2.Add('R');
        sl2.Add('S');
        sl2.Add('T');
        sl2.Add('U');
        sl2.Add('V');
        sl2.Add('W');
        sl2.Add('X');
        sl2.Add('Y');
        sl2.Add('Z');
        sl2.Add('AA');
        sl2.Add('AB');
        sl2.Add('AC');
        sl2.Add('AD');
        sl2.Add('AE');
        sl2.Add('AF');
        sl2.Add('AG');
        sl2.Add('AH');
        sl2.Add('AI');
        sl2.Add('AJ');
        sl2.Add('AK');
        sl2.Add('AL');
        sl2.Add('AM');
        sl2.Add('AN');
        sl2.Add('AO');
        sl2.Add('AP');
        sl2.Add('AQ');
        sl2.Add('AR');
        sl2.Add('AS');
        sl2.Add('AT');
        sl2.Add('AU');
        sl2.Add('AV');
        sl2.Add('AW');
        sl2.Add('AX');
        sl2.Add('AY');
        sl2.Add('AZ');

        ExcelWsht.Range[sl2[0]+'1', sl2[sl.Count-1]+'1'].Value[EmptyParam] := OleArray2;

        if sl.count > sl2.Count then
          begin
            ExcelWsht.Range[sl2[0]+'1', sl2[sl.Count-1]+'1'].Value[EmptyParam] := OleArray2;
          end;

        Query.First;

        for i := 0 to Query.RecordCount - 1 do
          begin
            for z := 0 to sl.Count - 1 do
              begin
                OleArray1[z] := Query.FieldByName(sl[z]).AsString;
              end;

            CoordCounter := IntToStr(i+2);
            ExcelWsht.Range[sl2[0]+CoordCounter, sl2[sl.Count-1]+CoordCounter].Value[EmptyParam]:=OleArray1;
            Query.Next;

          end;

        ExcelWsht.Cells.EntireRow.AutoFit;
        ExcelWsht.Cells.EntireColumn.AutoFit;

      end;

    Screen.Cursor := crDefault;
    sl.Free;
    sl2.Free;

end;
Ich weiß, die Sache mit der Stringlist und dem hinzufügen der Felder ist nicht gerade die eleganteste Methode aber es musste einfach schnell gehn und mit ist nichts besseres eingefallen, falls hier jemand etwas besseres kennt würde ich mich über Tipps freun.

Also dann ich hoffe ihr könnt mir weiterhelfen.

mfg
Alex
  Mit Zitat antworten Zitat
Benutzerbild von ralfschwalbe
ralfschwalbe

Registriert seit: 19. Jul 2007
Ort: Lichtenstein/Sachsen
133 Beiträge
 
Delphi XE3 Professional
 
#2

Re: Problem mit Excelexport

  Alt 18. Jul 2008, 14:25
Hi,

wenn's hilft: Jet kann von naturaus EXCEL Dateien schreiben:

Delphi-Quellcode:
adoconn := TADOConnection.Create(Application);
try
  adoconn.ConnectionString := ('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + temp);
  adoconn.CursorLocation := clUseClient;
  adoconn.LoginPrompt := false;
  adoconn.Connected := true;
  adoconn.Execute('SELECT * INTO TestTabelle IN "' + FileName + '" "Excel 8.0; HDR=Yes;" FROM ' + TableName, 1);
  adoconn.Connected := false;
finally
  adoconn.Free;
end;
Ralf Schwalbe
viele Grüße...
  Mit Zitat antworten Zitat
Borschti

Registriert seit: 1. Nov 2007
Ort: Marburg Lahn
235 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Problem mit Excelexport

  Alt 18. Jul 2008, 14:33
Hmm eher weniger habe gehofft man könnte vielleicht was bei den Parametern für FileCreate ändern.

Aber komplett neue Komponenten zu benutzen wäre der allerletzte Ausweg.
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.487 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Problem mit Excelexport

  Alt 18. Jul 2008, 15:11
Zum Verständnis: Mit Deinem Beispielcode aus dem Originalposting machst Du nichts anderes, als Excel "fernzusteuern". Deshalb muß Excel auf dem jeweiligen PC logischerweise installiert sein.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Benutzerbild von roga
roga

Registriert seit: 15. Jun 2008
Ort: Sachsen-Anhalt
109 Beiträge
 
Delphi XE8 Professional
 
#5

Re: Problem mit Excelexport

  Alt 18. Jul 2008, 22:32
Hallo Borschti,

suche bitte mal nach Hier im Forum suchenTXLSExport, da gehts auch ohne installiertes Excel.

Gruß RoGa
Ronald
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Problem mit Excelexport

  Alt 18. Jul 2008, 22:41
Nebenbei bemerkt: CreateFile gibt ein Handle zurück, das man schließen sollte.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Borschti

Registriert seit: 1. Nov 2007
Ort: Marburg Lahn
235 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Problem mit Excelexport

  Alt 21. Jul 2008, 09:18
Schonmal danke für die hilfreichen Antworten.

Ich habe mal nach TXLsExport gesucht, wie Roga gesagt hatte, nun bin ich da auf einen recht interessanten Thread gestoßen.

Hier habe ich mir diese Unit kopiert:

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; //Der linken Seite kann nichts zugewiesen werden.
  CXlsLabel[2] := Row; //"
  CXlsLabel[3] := Col; //"
  CXlsLabel[5] := L; //"
  fs.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel));
  fs.WriteBuffer(Pointer(Value)^, L);
end;

end.
Also ich habe mir den Aufruf den Marabu gepostet hat schon so umgebaut das ich meine Query benutzen kann. Ein kleines Problem bleibt allerdings noch, und zwar das der linken Seite nichts zugwiesen werden kann. Die betroffenen Stellen habe ich kommentiert.

Ich denke es liegt an der Konstantendeklaration, wie kann ich das ändern damit die Unit auch das weiterhin tut wofür sie geschrieben worden ist?

Ich hoffe das war halbwegs verständlich.

mfg
Alex
  Mit Zitat antworten Zitat
Benutzerbild von roga
roga

Registriert seit: 15. Jun 2008
Ort: Sachsen-Anhalt
109 Beiträge
 
Delphi XE8 Professional
 
#8

Re: Problem mit Excelexport

  Alt 21. Jul 2008, 09:39
Hallo Borschti,

also bei mir läufts mit der Unit "u_ExportEXCEL" ohne Probleme. Das folgende Beispiel speichert eine ListView in eine Excel-Datei:

Delphi-Quellcode:
procedure ExportDataToExcel(ExportFileName: string;
  ExportListView: TListView);
var XLSFile: TXLSExport;
    XLSFileName: string;
    ColumnsCount, ItemsCount, i, x, y: Integer;
begin
  // Excel-Tabelle erstellen
  XLSFileName := ExportFileName;
  XLSFile := TXLSExport.Create(XLSFileName);
  if FileExists(XLSFileName) then DeleteFile(XLSFileName);
  try
    ColumnsCount := ExportListView.Columns.Count;
    ItemsCount := ExportListView.Items.Count;
    // Kopfzeilen
    for i := 0 to ColumnsCount -1 do
      XLSFile.Write(i, 0, ExportListView.Columns[i].Caption);
    // Daten
    y := 1;
    for i := 0 to ItemsCount -1 do
    begin
      XLSFile.Write(0, y, ExportListView.Items[i].Caption);
      for x := 0 to ColumnsCount -2 do
        XLSFile.Write(x + 1, y, ExportListView.Items[i].SubItems.Strings[x]);
      inc(y);
    end;
  finally

  end;
  XLSFile.Free;
  // Excel starten und Tabelle anzeigen
  if MessageDlg('Soll die Excel-Tabelle jetzt angezeigt werden?',
                mtConfirmation, [mbYes,mbNo], 0) = mrYes then
  try
    ShellExecute(0, nil, PChar(ExportFileName), nil, nil, SW_NORMAL);
  except
    MessageDlg('Excel-Programm konnte nicht gestartet werden!',
               mtError, [mbOk], 0);
  end;
end;
Leider kann man die Spaltenbreite nicht ändern.

Gruß RoGa
Ronald
  Mit Zitat antworten Zitat
Borschti

Registriert seit: 1. Nov 2007
Ort: Marburg Lahn
235 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Problem mit Excelexport

  Alt 21. Jul 2008, 10:18
Hmm also ich habe auch nochmal ein bisschen rumprobiert und habe das jetzt so:

Delphi-Quellcode:
unit u_ExportEXCEL;

interface
uses classes;

type TXLSExport = class(TObject)
                  private
                     fs : TFilestream;
                     CXlsBof : array[0..5] of Word;
                     CXlsEof : array[0..1] of Word;
                     CXlsLabel : array[0..5] of Word;
                     CXlsNumber : array[0..4] of Word;
                     CXlsRk : array[0..4] of Word;
                  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

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.
Mein Aufruf sieht so aus:

Delphi-Quellcode:
procedure TForm1.ExportierenExcel1Click(Sender: TObject);
var
  xf: TXLSExport;
  iCol, iRow: integer;
  Fields : TstringList;
  TempVal : String;
begin
  VddQuery1.First;

  if not SaveDialog1.Execute then Exit;

  if FileExists(Savedialog1.Filename) then
    DeleteFile(SaveDialog1.Filename);

  xf := TXLSExport.Create(savedialog1.filename);

  Fields := TStringList.Create;
  VddQuery1.GetFieldNames(Fields);

  for iRow := 0 to VddQuery1.RecordCount - 1 do
    begin
      for iCol := 0 to Fields.Count - 1 do
        begin
          TempVal := VddQuery1.FieldByName(Fields[iCol]).AsString;
          xf.Write(iCol, iRow, TempVal);
        end;
      VddQuery1.Next;
    end;

  xf.Free;
  Fields.Free;
end;
Also es werden auch schon sachen in die Exceldatei geschrieben aber leider vollkommen unleserlicher kram wie z.B. 500 etc.

Mir wird beim öffnen der .xls auch angezeigt das das Format der Datei nicht erkannt werden konnte

Woran liegt das denn?

mfg
Alex
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#10

Re: Problem mit Excelexport

  Alt 21. Jul 2008, 11:00
Hallo Borschti,

zu Deiner Eingangsfrage:

Delphi-Quellcode:
  excel : variant;
   
begin
  try
    excel:=createoleobject('EXCEL.APPLICATION');
  except
    showmessage('Excel kann nicht gestartet werden!');
    exit;
  end;
Wenn Auf dem Rechner kein excel installiert ist, dann bekommst Du eine Fehlermeldung.
Wenn Du unbedingt eine Ausgabe erstellen willst oder mußt, dann nimm doch CSV .

Deine letzte Frage von hinten aufgedröselt:
Wenn Das excel auf Deinem Rechner das Dateiformat nicht richtig erkennen kann, dann ist es entweder zickig oder aber es kennt das Format nicht. In beiden Fällen sollte die Datenanzeige nicht sehr zuverlässig sein.

Da ich nicht die vollständige Unit gesehen habe mit der Du arbeitest, kann ich wenig konkretes hierzu sagen, aber die excel-Dateien, die auf meinem Rechner liegen, können damit nicht erstellt werden.

Ansonsten kann ich Dir nur den Tip geben die Erstellungsroutine mit bekannten Daten zu testen. Bekannt heißt "im Programm generiert" und nicht über irgendeine obskure Query irgendwoher geholt.


Gruß
K-H
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 15:06 Uhr.
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