Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   ExcelExport löst einen Fehler aus (https://www.delphipraxis.net/178548-excelexport-loest-einen-fehler-aus.html)

Ykcim 14. Jan 2014 09:45

ExcelExport löst einen Fehler aus
 
Hallo Zusammen,

ich habe unter Delphi xe2 mit diesem Objekt einen Excel-Export realisiert. Jetzt muss ich ein Programm unter Delphi 2009 Prof. schreiben und bekomme den ExcelExport nicht ans Laufen...

Delphi-Quellcode:
 FExcelApp := CreateOleObject('Excel.Application');
Hier wird ein Fehler ausgelöst mit der Nachricht, dass es eine Zugriffsverletzung gegeben hat. Sieht einer, was ich falsch mache?

Vielen Dank

Patrick



Delphi-Quellcode:
unit TExcelExportUnit;

interface

uses SysUtils, Variants, Dialogs, Grids, BaseGrid, AdvGrid, ShlObj, ComObj, Math;

type
   TExcelExport = class
      strict protected
         FExcelApp: OleVariant;
         FWorkbook: OleVariant;
         FWorksheet: OleVariant;
         FRange: OleVariant;
         FData: OleVariant;
         FValue: OleVariant;
         FMaxCol, FMaxRow: integer;
      public
         constructor OpenTemp(Pfad:string);
         procedure exportieren(StringGrid : TStringGrid; Pfad:string; Space:integer);
         function RefToCell(Col, Row, Space : Integer) : string;
         function GetExcelApp: OleVariant;
         function GetWorkbook: OleVariant;
         function GetWorksheet: OleVariant;
         function GetRange: OleVariant;
         function GetData: OleVariant;
         function GetValue: OleVariant;
         function GetMaxCol: integer;
         function GetMaxRow: integer;
         procedure SetExcelApp;
         procedure SetWorkbook;
         procedure SetWorksheet;
         procedure SetRange;
         procedure SetData;
         procedure SetValue;
         procedure SetMaxCol(val: integer);
         procedure SetMaxRow(val: integer);
         procedure SaveDokument(Pfad: string);
         property ExcelApp: OleVariant read GetExcelApp;
         property Workbook: OleVariant read GetWorkbook;
         property Worksheet: OleVariant read GetWorksheet;
         property Range: OleVariant read GetRange;
         property Data: OleVariant read GetData;
         property Value: OleVariant read GetValue;
         property MaxCol: integer read GetMaxCol write SetMaxCol;
         property MaxRow: integer read GetMaxRow write SetMaxRow;
   end;

var ExportGrid: TExcelExport;

implementation

function StringToVariant(const SourceString : string) : Variant;
var
  FloatValue : Extended;
begin
  if TryStrToFloat(SourceString, FloatValue) then
    Result := FloatValue
  else
    Result := SourceString;
end;

constructor TExcelExport.OpenTemp(Pfad:string);
var  Row, Col: integer;
begin
   //Verbindung zu Excel herstellen
   FExcelApp := CreateOleObject('Excel.Application');
   try
      if not VarIsNull(FExcelApp) then begin
         //Neues FWorkbook öffnen
         FWorkbook :=FExcelApp.Workbooks.open(pfad);
         if VarIsNull(FWorkbook) then
            showmessage('Datei konnte nicht geöffnet werden.');
      end;
   Finally

   end;
end;

procedure TExcelExport.SaveDokument(Pfad: string);
begin
   FExcelApp.ActiveWorkbook.SaveAs(Pfad);
end;


//Inhalt eines TStringGrid nach Excel exportieren
procedure TExcelExport.exportieren(StringGrid : TStringGrid; Pfad:string; Space:integer);
var  Row, Col: integer;
begin
  //Verbindung zu Excel herstellen
  FExcelApp := CreateOleObject('Excel.Application');
  try
    if not VarIsNull(FExcelApp) then
    begin
      //Neues FWorkbook öffnen
      FWorkbook :=FExcelApp.Workbooks.open(pfad);
      if not VarIsNull(FWorkbook) then
      begin
        //Maximalen Bereich bestimmen
        FMaxCol := Min(StringGrid.ColCount, FExcelApp.Columns.Count);
        FMaxRow := Min(StringGrid.RowCount, FExcelApp.Rows.Count);
        if (FMaxRow > 0) and (FMaxCol > 0) then
        begin
          //FWorksheet auswählen
          FWorksheet := FWorkbook.ActiveSheet;
          //Bereich auswählen
          FRange := FWorksheet.Range[RefToCell(1, 1, Space), RefToCell(FMaxCol, FMaxRow, Space)];
          if not VarIsNull(FRange) then
          begin
            //Daten aus Grid holen
            FData := VarArrayCreate([1, FMaxRow, 1, FMaxCol], varVariant);
            for Row := 0 to Pred(FMaxRow) do
            begin
              for Col := 0 to Pred(FMaxCol) do
              begin
                FValue := StringToVariant(StringGrid.Cells[Col, Row]);
                FData[Succ(Row), Succ(Col)] := FValue
              end;
            end;
            //Daten dem Excelsheet übergeben
            FRange.Value := FData;
            //Excel anzeigen
            {FWorkbook.Activate;
            FExcelApp.Visible := True;}
          end;
        end;
      end;
    end;
  finally
    //FValue   := UnAssigned;
    FData    := UnAssigned;
    //FRange   := UnAssigned;
    //FWorkbook := UnAssigned;
    //FExcelApp := UnAssigned;
  end;
end;

function TExcelExport.RefToCell(Col, Row, Space : Integer) : string;
var
  Pos : Integer;
begin
  //Spalte bestimmen
  Result := '';
  while Col > 0 do
  begin
    Pos := Col mod 26;
    if Pos = 0 then
    begin
      Pos := 26;
      Dec(Col);
    end;
    Result := Chr(Ord('A') + Pos -1) + Result;
    Col := Col div 26;
  end;
  //Spalte und Zeile zusammenführen
  Result := Result + IntToStr(Row+Space);
end;

function TExcelExport.GetExcelApp;
begin
   Result:=FExcelApp;
end;

function TExcelExport.GetWorkbook;
begin
   Result:=FWorkbook;
end;

function TExcelExport.GetWorksheet;
begin
   Result:=FWorksheet;
end;

function TExcelExport.GetRange;
begin
   Result:=FRange;
end;

function TExcelExport.GetData;
begin
   Result:=FData;
end;

function TExcelExport.GetValue;
begin
   Result:=FValue;
end;

function TExcelExport.GetMaxCol;
begin
   Result:=FMaxCol;
end;

function TExcelExport.GetMaxRow;
begin
   Result:=FMaxRow;
end;

procedure TExcelExport.SetExcelApp;
begin
   FExcelApp:=UnAssigned;
end;

procedure TExcelExport.SetWorkbook;
begin
   FWorkBook:=UnAssigned;
end;

procedure TExcelExport.SetWorksheet;
begin
   FWorksheet:=UnAssigned;
end;

procedure TExcelExport.SetRange;
begin
   FRange:=UnAssigned;
end;

procedure TExcelExport.SetData;
begin
   FData:=UnAssigned;
end;

procedure TExcelExport.SetValue;
begin
   FValue:=UnAssigned;
end;

procedure TExcelExport.SetMaxCol(val: integer);
begin
   FMaxCol:= val;
end;

procedure TExcelExport.SetMaxRow(val: integer);
begin
   FMaxRow:= val;
end;


initialization
   ExportGrid := TExcelExport.Create;

finalization
   if ExportGrid <> nil then
      ExportGrid.Free;
end.

GHorn 14. Jan 2014 10:05

AW: ExcelExport löst einen Fehler aus
 
Ich mache das i.d.R. so:

Delphi-Quellcode:
 
     try
        XLApp := GetActiveOleObject('Excel.Application');
      except
        XLApp := CreateOleObject('Excel.Application');
      end;
Gruß
Gerald

Ykcim 14. Jan 2014 10:11

AW: ExcelExport löst einen Fehler aus
 
Habe ich versucht, aber er löst auch bei

Delphi-Quellcode:
FExcelApp := GetActiveOleObject('Excel.Application');
den Fehler aus...

Gruß Patrick

p80286 14. Jan 2014 10:19

AW: ExcelExport löst einen Fehler aus
 
Aber "ExcelExport" gibt es schon?

Gruß
K-H

Ykcim 14. Jan 2014 10:28

AW: ExcelExport löst einen Fehler aus
 
Das Objekt wird erstellt, die Software lässt sich problemlos compilieren, der Fehler tritt nur auf, wenn ich die Export-Funktion auslöse...

sx2008 14. Jan 2014 10:33

AW: ExcelExport löst einen Fehler aus
 
Teste doch mal mit einem von Delphi unabhängigen System:
Folgenden Code in einer *.vbs-Datei speichern und mit Doppelklick starten
Code:
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("C:\test.xls")

Ykcim 14. Jan 2014 10:38

AW: ExcelExport löst einen Fehler aus
 
passiert nichts - Datei wurde erstellt, Exceldatei wurde erstellt und an den angegebenen Ort gelegt. Aber wenn ich die vbs Datei starte, passiert nichts.

GHorn 14. Jan 2014 10:48

AW: ExcelExport löst einen Fehler aus
 
Im Constructor rufst OpenTemp(..) auf und startest CreateOleObject(..).
Das gleiche machst aber in der procedure exportieren(..) ohne FExelApp
frei zu geben. Oder wie ist die Aufrufreihenfolge?

Ykcim 15. Jan 2014 09:33

AW: ExcelExport löst einen Fehler aus
 
Hallo Zusammen,

@GHorn: Du warst genau auf dem richtigen Weg!

Ich habe in der anderen Software das Objekt zu der Klasse erst in der Prozedure erstellt. Jetzt wird das Objekt aber schon erstellt, wenn die Klasse eingebunden wird. Das bedeutete, dass OpenTemp gar nicht mehr ausgeführt wurde...

Ich habe das jetzt das Ganze so umgebuat und es funktioniert...

Delphi-Quellcode:
unit TExcelExportUnit;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComObj, Grids, AdvObj, BaseGrid, Math,
      AdvGrid;

type
   TExcelExport = class
      strict protected
         FExcelApp: OleVariant;
         FWorkbook: OleVariant;
         FWorksheet: OleVariant;
         FRange: OleVariant;
         FData: OleVariant;
         FValue: OleVariant;
         FMaxCol, FMaxRow: integer;
      public
         procedure OpenTemp(Pfad:string);
         procedure exportieren(StringGrid : TStringGrid; Pfad:string; Space:integer);
         function RefToCell(Col, Row, Space : Integer) : string;
         function GetExcelApp: OleVariant;
         function GetWorkbook: OleVariant;
         function GetWorksheet: OleVariant;
         function GetRange: OleVariant;
         function GetData: OleVariant;
         function GetValue: OleVariant;
         function GetMaxCol: integer;
         function GetMaxRow: integer;
         procedure SetExcelApp;
         procedure SetWorkbook;
         procedure SetWorksheet;
         procedure SetRange;
         procedure SetData;
         procedure SetValue;
         procedure SetMaxCol(val: integer);
         procedure SetMaxRow(val: integer);
         procedure SaveDokument(Pfad: string);
         property ExcelApp: OleVariant read GetExcelApp;
         property Workbook: OleVariant read GetWorkbook;
         property Worksheet: OleVariant read GetWorksheet;
         property Range: OleVariant read GetRange;
         property Data: OleVariant read GetData;
         property Value: OleVariant read GetValue;
         property MaxCol: integer read GetMaxCol write SetMaxCol;
         property MaxRow: integer read GetMaxRow write SetMaxRow;
   end;

var ExportGrid: TExcelExport;

implementation

function StringToVariant(const SourceString : string) : Variant;
var
  FloatValue : Extended;
begin
  if TryStrToFloat(SourceString, FloatValue) then
    Result := FloatValue
  else
    Result := SourceString;
end;

procedure TExcelExport.OpenTemp(Pfad:string);
begin
   //Verbindung zu Excel herstellen
   try
      FExcelApp := GetActiveOleObject('Excel.Application');
   except
      FExcelApp := CreateOleObject('Excel.Application');
   end;
end;

procedure TExcelExport.SaveDokument(Pfad: string);
begin
   FExcelApp.ActiveWorkbook.SaveAs(Pfad);
end;


//Inhalt eines TStringGrid nach Excel exportieren
procedure TExcelExport.exportieren(StringGrid : TStringGrid; Pfad:string; Space:integer);
var  Row, Col: integer;
begin
  //Verbindung zu Excel herstellen
   OpenTemp(Pfad);
   try
    if not VarIsNull(FExcelApp) then
    begin
      //Neues FWorkbook öffnen
      FWorkbook :=FExcelApp.Workbooks.open(pfad);
      if not VarIsNull(FWorkbook) then
      begin
        //Maximalen Bereich bestimmen
        FMaxCol := Min(StringGrid.ColCount, FExcelApp.Columns.Count);
        FMaxRow := Min(StringGrid.RowCount, FExcelApp.Rows.Count);
        if (FMaxRow > 0) and (FMaxCol > 0) then
        begin
          //FWorksheet auswählen
          FWorksheet := FWorkbook.ActiveSheet;
          //Bereich auswählen
          FRange := FWorksheet.Range[RefToCell(1, 1, Space), RefToCell(FMaxCol, FMaxRow, Space)];
          if not VarIsNull(FRange) then
          begin
            //Daten aus Grid holen
            FData := VarArrayCreate([1, FMaxRow, 1, FMaxCol], varVariant);
            for Row := 0 to Pred(FMaxRow) do
            begin
              for Col := 0 to Pred(FMaxCol) do
              begin
                FValue := StringToVariant(StringGrid.Cells[Col, Row]);
                FData[Succ(Row), Succ(Col)] := FValue
              end;
            end;
            //Daten dem Excelsheet übergeben
            FRange.Value := FData;
            //Excel anzeigen
            {FWorkbook.Activate;
            FExcelApp.Visible := True;}
          end;
        end;
      end;
    end;
  finally
    //FValue   := UnAssigned;
    FData    := UnAssigned;
    //FRange   := UnAssigned;
    //FWorkbook := UnAssigned;
    //FExcelApp := UnAssigned;
  end;
end;

function TExcelExport.RefToCell(Col, Row, Space : Integer) : string;
var
  Pos : Integer;
begin
  //Spalte bestimmen
  Result := '';
  while Col > 0 do
  begin
    Pos := Col mod 26;
    if Pos = 0 then
    begin
      Pos := 26;
      Dec(Col);
    end;
    Result := Chr(Ord('A') + Pos -1) + Result;
    Col := Col div 26;
  end;
  //Spalte und Zeile zusammenführen
  Result := Result + IntToStr(Row+Space);
end;

function TExcelExport.GetExcelApp;
begin
   Result:=FExcelApp;
end;

function TExcelExport.GetWorkbook;
begin
   Result:=FWorkbook;
end;

function TExcelExport.GetWorksheet;
begin
   Result:=FWorksheet;
end;

function TExcelExport.GetRange;
begin
   Result:=FRange;
end;

function TExcelExport.GetData;
begin
   Result:=FData;
end;

function TExcelExport.GetValue;
begin
   Result:=FValue;
end;

function TExcelExport.GetMaxCol;
begin
   Result:=FMaxCol;
end;

function TExcelExport.GetMaxRow;
begin
   Result:=FMaxRow;
end;

procedure TExcelExport.SetExcelApp;
begin
   FExcelApp:=UnAssigned;
end;

procedure TExcelExport.SetWorkbook;
begin
   FWorkBook:=UnAssigned;
end;

procedure TExcelExport.SetWorksheet;
begin
   FWorksheet:=UnAssigned;
end;

procedure TExcelExport.SetRange;
begin
   FRange:=UnAssigned;
end;

procedure TExcelExport.SetData;
begin
   FData:=UnAssigned;
end;

procedure TExcelExport.SetValue;
begin
   FValue:=UnAssigned;
end;

procedure TExcelExport.SetMaxCol(val: integer);
begin
   FMaxCol:= val;
end;

procedure TExcelExport.SetMaxRow(val: integer);
begin
   FMaxRow:= val;
end;


initialization
   ExportGrid := TExcelExport.Create;

finalization
   if ExportGrid <> nil then
      ExportGrid.Free;
end.
Vielen Dank

Patrick

DeddyH 15. Jan 2014 09:36

AW: ExcelExport löst einen Fehler aus
 
Zitat:

Delphi-Quellcode:
if ExportGrid <> nil then
      ExportGrid.Free;

Das ist zwar nicht falsch, aber auch nicht notwendig. Free prüft intern bereits auf nil, so dass man das nicht selbst machen muss. Und das ist im übrigen auch der Grund, weshalb man zur Freigabe immer Free verwenden soll statt Destroy.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:47 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