Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Excel Sheets (https://www.delphipraxis.net/190397-excel-sheets.html)

Sidi61 29. Sep 2016 20:26

Excel Sheets
 
Hallo zusammen,

eigentlich einfache Aufgabe, mit Delphi eine Excel Arbeitsmappe erstellen, dort 2 Arbeitblätter einfügen und das zweite Arbeitsblatt umbenennen.
Wird in vielen Beiträgen beschrieben, will bei mir aber nicht fehlerfrei funktionieren.

Variablen: Excel : Variant und WBOj : Olevariant

Excel starten:
Delphi-Quellcode:
 try
    Excel := GetActiveOleObject('Excel.Application');
  Except
     try
       Excel := CreateOleObject('Excel.Application');
     except
       Showmessage('Excel konnte nicht gestartet werden!');
       OK := false;
     end;
  end;

Arbeitsmappe anlegen (enthält automatisch ein Tabellenblatt):
Delphi-Quellcode:
WBObj := Excel.Application.Workbooks.Add;

Ein weiteres Tabellenblatt anlegen:
Delphi-Quellcode:
WBObj.Worksheets.add;

Jetzt möchte ich das zweite Tabellenblatt umbenennen. Die folgende Variante funktioniert einwandfrei, kurios ist hierbei jedoch dass Delphi eine
Fehlermeldung anzeigt : Undeklarierter Bezeichner 'Activate' in Zeile ... aber trotzdem Compiliert und fehlerfrei ausführt

Delphi-Quellcode:
WBObj.Sheets[2].Activate;
WBObj.ActiveSheet.Name := 'Neu';
Bei folgender Variante wird kein Fehler angezeigt, bei der Ausführung erhalte ich jedoch eine Fehlermeldung "Mitglied nicht gefunden"

Delphi-Quellcode:
WBObj.ActiveSheet := WBObj.Sheets[Nr];
WBObj.ActiveSheet.Name := 'Neu';
Eine oft beschriebene Variante funktioniert überhaupt nicht und wird auch nicht compiliert:

Delphi-Quellcode:
Excel.WBObj[1].WorkSheets[2].Name := 'Neu';
Wer kann mir hier ein wenig auf die Sprünge helfen:gruebel::gruebel:

Gruß
Sidi61

HolgerX 30. Sep 2016 04:23

AW: Excel Sheets
 
Hallo,

lass mall das "WBOj" weg..

Delphi-Quellcode:
Excel := CreateOLEObject('Excel.Application'); // Excel-Verbindung öffnen
Excel.Application.Workbooks.Add; // Seite erstellen
Excel.WorkSheets[1].Name:=Copy(SheetName,1,30); // Arbeitseitenname setzen = max 30 Zeichen
...

So gehts...

Jumpy 30. Sep 2016 09:20

AW: Excel Sheets
 
Oder nutze eine weitere Variable, diesmal für das worksheet:

WSObj:=WBObj.Worksheets.add;
WSObj.Name:='Neu';

Sidi61 30. Sep 2016 21:24

AW: Excel Sheets
 
Hallo,

es ist zum Mäuse melken, sobald ich die Eckige Klammer verwende zeigt Delphi für nach der Klammer folgende Begriffe einen Fehler mit 'Undeklarierter Bezeichner'

Delphi-Quellcode:
WBObj.Sheets[2].Activate;
WBObj.ActiveSheet.Name := 'Neu';
Obiges Beispiel funktioniert einwandfrei obwohl Activate rot unterstrichen ist und der besagte Fehler im Fenster 'Struktur' angezeigt wird.

Ich habe mal nach Excel Referenzen gesucht und Beispiel für VBA gefunden. Hier werden anstatt eckiger die runden Klammern verwendet.

Ändere ich meinen Code wie folgt

Delphi-Quellcode:
WBObj.Sheets(2).Activate;
WBObj.ActiveSheet.Name := 'Neu';
wird Activate akzeptiert, die Fehlermeldung verschwindet, der Code kann compiliert werden - bei der Ausführung kommt jedoch die Fehlermeldung 'Mitglied nicht gefunden' - ist natürlich wieder mal eine Meldung mit der man überhaupt nichts anfangen kann!

Vielleicht hat jemand mal Lust mein Beispiel nachzubauen ggf. mit einer anderen Delphi Version als XE5 ob dort der gleiche Fehler auftaucht.

Gruß
Sidi61

Chemiker 1. Okt 2016 00:53

AW: Excel Sheets
 
Hallo Sidi61,

es gibt einige Wege um ein WorkSheet mit einem neunen Namen zu versehen. Im Beispiel Code steht eine Möglichkeit.

Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
var
  oExcel: OLEVariant;
  oWB1: OLEVariant;
  oWS1: OLEVariant;
  oWS2: OLEVariant;
begin
  try
    oExcel := CreateOleObject('Excel.Application');
  except
    ShowMessage('Microsoft Excel kann nicht starten.');
    exit;
  end;
  oExcel.Visible:= TRUE;
  // Workbook anlegen
  if (NOT VarIsEmpty(oExcel)) then
  begin
    oWB1:=oExcel.Workbooks.add;
  end;
  if ((NOT VarIsEmpty(oExcel))and(NOT VarIsEmpty(oWB1))) then
  begin
    // Wir legen mal ein neues Sheet an, es soll vor den ersten Sheet eingefügt
    // werden
    oWS1:= oWB1.Worksheets.add(Before:= oWB1.WorkSheets[1]);
    oWS1.Name:= 'Erste Blatt';
    oWS2:= oWB1.Worksheets[2];
    oWS2.Name:= 'Zweites Blatt';
    oWS2.activate;
    ShowMessage('Blatt 2 aktiviert');
    oWS1.activate;
    ShowMessage('Blatt 1 aktiviert');
  end;
  if ((NOT VarIsEmpty(oExcel))and(NOT VarIsEmpty(oWB1))
      and(NOT VarIsEmpty(oWS1))and(NOT VarIsEmpty(oWS2))) then
  begin
    oWS1.Delete;     // Wir löschen das neue Sheet
    oWS1:= Unassigned;
  end;
  //  Workbook schliesssen
  if (NOT VarIsEmpty(oWB1)) then
  begin
    oWB1.Saved := TRUE;  // ohne Nachfragen
    oWB1.Close;
    oWB1:= Unassigned;
  end;
  // Excel schliessen
  if ((NOT VarIsEmpty(oExcel))and VarIsEmpty(olevWB)) then
  begin
    oExcel.Quit;
    oExcel:= Unassigned;
  end;
end;
Bis bald Chemiker

Sidi61 2. Okt 2016 19:44

AW: Excel Sheets
 
Hallo Chemiker,

habe es mit deinem Beispiel versucht, es wird kein Fehler angezeigt, Programm lässt sich compilierren allerdings bei der Ausführung oWS2.Name erhalte ich folgenden Fehler:

Die methode "Name" wird vom Automatisierunsobjekt nicht unterstützt.

Wie soll man das noch verstehen:wall:

Gruß
Sidi61

Chemiker 2. Okt 2016 20:20

AW: Excel Sheets
 
Hallo Sidi61,

ich habe einen Fehler in der Zeile:

Delphi-Quellcode:
if ((NOT VarIsEmpty(oExcel))and VarIsEmpty(olevWB)) then

sie muss geändert werden. Von olevWB nach oWB1.

Delphi-Quellcode:
if ((NOT VarIsEmpty(oExcel))and VarIsEmpty(oWB1)) then

Ich habe das Beispiel unter Delphi Berlin mit Office 2016 und Delphi XE5 mit Office 2007 getestet. Einfach ein Form anlegen einen Button drauf und im onClick-Event den Code kopieren.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.SyncObjs,System.Win.ComObj;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
   oExcel: OLEVariant;
   oWB1: OLEVariant;
   oWS1: OLEVariant;
   oWS2: OLEVariant;
begin
   try
     oExcel := CreateOleObject('Excel.Application');
   except
     ShowMessage('Microsoft Excel kann nicht starten.');
     exit;
   end;
   oExcel.Visible:= TRUE;
   // Workbook anlegen
   if (NOT VarIsEmpty(oExcel)) then
   begin
     oWB1:=oExcel.Workbooks.add;
   end;
   if ((NOT VarIsEmpty(oExcel))and(NOT VarIsEmpty(oWB1))) then
   begin
     // Wir legen mal ein neues Sheet an, es soll vor den ersten Sheet eingefügt
     // werden
     oWS1:= oWB1.Worksheets.add(Before:= oWB1.WorkSheets[1]);
     oWS1.Name:= 'Erste Blatt';
     oWS2:= oWB1.Worksheets[2];
     oWS2.Name:= 'Zweites Blatt';
     oWS2.activate;
     ShowMessage('Blatt 2 aktiviert');
     oWS1.activate;
     ShowMessage('Blatt 1 aktiviert');
   end;
   if ((NOT VarIsEmpty(oExcel))and(NOT VarIsEmpty(oWB1))
       and(NOT VarIsEmpty(oWS1))and(NOT VarIsEmpty(oWS2))) then
   begin
     oWS1.Delete; // Wir löschen das neue Sheet
     oWS1:= Unassigned;
   end;
   // Workbook schliesssen
   if (NOT VarIsEmpty(oWB1)) then
   begin
     oWB1.Saved := TRUE; // ohne Nachfragen
     oWB1.Close;
     oWB1:= Unassigned;
   end;
   // Excel schliessen
   if ((NOT VarIsEmpty(oExcel))and VarIsEmpty(oWB1)) then
   begin
     oExcel.Quit;
     oExcel:= Unassigned;
   end;
end;

end.
Bis bald Chemiker

Sidi61 2. Okt 2016 20:52

AW: Excel Sheets
 
Hallo Chemiker,

habe dein Beispiel 1:1 übernommen, es läuft durch und die Tabellenblätter werden entsprechend umbenannt allerdings erhalte ich auch hier in meinem Struktur Fenster die Fehlermeldung: Undeklarierter Bezeichner 'Before' in Zeile...

Hab so den Verdacht meine Delphi Version ist hier etwas fehlerhaft.

Wollte eigentlich eine Unit schreiben die ich in allen Projekten einsetzen kann, werde mal mit deinem Ansatz weiter experimentieren :|

Gruß
Sidi61

himitsu 2. Okt 2016 23:03

AW: Excel Sheets
 
Zitat:

Undeklarierter Bezeichner
ErrorInsight hatte noch nie 100% richtig funktioiert und zeigt gern mal falsche Fehler an.
Wenn der Compiler sagt es ist OK, dann ignoriere solche Fehlermeldungen einfach.

HolgerX 3. Okt 2016 08:43

AW: Excel Sheets
 
So, mal deinen Quellcode überarbeitet

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   oExcel: OLEVariant;
   oWB1: OLEVariant;
   oWS1: OLEVariant;
   oWS2: OLEVariant;
begin
   try
     oExcel := CreateOleObject('Excel.Application');
   except
     ShowMessage('Microsoft Excel kann nicht starten.');
     exit;
   end;


   if (NOT VarIsEmpty(oExcel)) then // Excel gestartet ?
   begin
     try

       oExcel.Visible:= TRUE;      // Excel anzeigen

       oWB1:=oExcel.Workbooks.add; // Workbook anlegen

       if (NOT VarIsEmpty(oWB1)) then // Workbook angelegt ?
       begin
         // Wir legen mal ein neues Sheet an, es soll vor den ersten Sheet eingefügt
         // werden
         oWS1:= oWB1.Worksheets.add(oWB1.WorkSheets[1]);
         if (NOT VarIsEmpty(oWS1)) then
         begin
           oWS1.Name:= 'Erste Blatt';
           oWS2:= oWB1.Worksheets[2];
           oWS2.Name:= 'Zweites Blatt';
           oWS2.activate;
           ShowMessage('Blatt 2 aktiviert');
           oWS1.activate;
           ShowMessage('Blatt 1 aktiviert');

           oWS1.Delete; // Wir löschen das neue Sheet

           ShowMessage('Blatt 1 gelöscht');
         end;

         oWS1:= Unassigned;
         oWS2:= Unassigned;

         // Workbook schliesssen
         oWB1.Saved := TRUE; // ohne Nachfragen
         oWB1.Close;
         oWB1:= Unassigned;
       end;
     finally
       // Excel schliessen
       oExcel.Quit;
       oExcel:= Unassigned;
     end;
  end;
end;

das Before:= kann auch weggelassen werden, da 'Before' der erste Parameter von Sheet.Add ist...
Somit auch keine Fehlermeldungen...

Durch die vielen (NOT VarIsEmpty( wurde es etwas unübersichtlich.. ;)

Sidi61 3. Okt 2016 19:07

AW: Excel Sheets
 
Hallo zusammen,

nach langem Gefummel habe ich jetzt doch tatsächlich einen Code der läuft :thumb:

Einen Schönheitsfehler bezüglich Fehlermeldung "Undeklarierter Bezeichner" für After und Name bleibt erhalten, wenn ich das jedoch richtig verstanden habe ist das kein Beinbruch.

Es sind einige eurer Tips eingeflossen - Danke dafür - mit folgendem Skript kann ich jetzt eine neue Arbeitsmappe mit 3 Arbeitsblättern anlegen und diese auch benennen.

Delphi-Quellcode:
Var ExcelApp : OleVariant;
Function TFormExcel.Excel_Starten(Q,Namen : String; Anz : integer; V : boolean) : boolean;
var OK : boolean;
    N1, N2 : string;
    I : integer;
begin
  OK := true;
  try
    ExcelApp := GetActiveOleObject('Excel.Application');
  Except
     try
       ExcelApp := CreateOleObject('Excel.Application');
     except
       Showmessage('Excel konnte nicht gestartet werden!');
       OK := false;
     end;
  end;

  if (OK) and (not v) then
  begin
    ExcelApp.visible := false;
    ExcelApp.DisplayAlerts:=False; //unterdrückt die Ausgaben von Hinweisen aus Excel
  end;

  if Q = '' then //neue Arbeitsmappe anlegen
  begin
    ExcelApp.Workbooks.Add(xlWBatWorkSheet);
    //Eine Arbeitsmappe hat automatisch auch eine Tabelle
    N1 := Namen;
    if Pos(';',N1)>0 then
    begin
      N2 := Copy(N1,1,Pos(';',N1)-1);
      Delete(N1,1,Pos(';',N1));
    end else N2 := 'Seite 1';
    ExcelApp.ActiveWorkbook.ActiveSheet.Name := N2;

    //soll die Arbeitsmappe mehr als eine Tabelle enthalten dann weitere anlegen
    if Anz > 1 then
    begin
      for I := 2 to Anz do
      begin
        if Pos(';',N1)>0 then
        begin
          N2 := Copy(N1,1,Pos(';',N1)-1);
          Delete(N1,1,Pos(';',N1));
        end else N2 := 'Seite ' + inttostr(I);
        ExcelApp.ActiveWorkbook.Worksheets.Add(After := ExcelApp.ActiveWorkbook.Worksheets[I-1]);
        ExcelApp.ActiveWorkbook.Worksheets[I].Name := N2;
      end;
    end else
    begin
      //hier Action wenn vorhandene Arbeitsmappe geöffnet werden soll
    end;
  end;
  Result := OK;
end;

Function TFormExcel.Excel_Arbeitsmappe_speichern(Z: string):boolean;
Var OK : boolean;
begin
  OK := true;
  if Z = '' then Ziel := Quelle else Ziel := Z;
  if Ziel <> '' then ExcelApp.ActiveWorkbook.saveas(Ziel) else OK := false;
  Result := OK;
end;

Procedure TFormExcel.Excel_Schliessen;
begin
  ExcelApp.Quit;
  ExcelApp := Unassigned;
end;

procedure TFormExcel.Button1Click(Sender: TObject);
begin
  if Excel_Starten('','Test 1;Test 2;Test 3;',3,false) then
  begin
    Excel_Arbeitsmappe_speichern('D:\Eigene Dateien\temp\Test.xlsx');
    Excel_Schliessen;
  end;
end;
Ein weiteres Problem wo ich noch keinen Ansatz gefunden habe:
Wie im Beispiel zu sehen gebe ich die Datei-Endung mit .xlsx an, was aber wenn der Anwender noch ein älteres Excel hat welches nur xls unterstützt.
Kann ich das irgendwie herausfinden ob xlsx geht oder nicht ??



Gruß
Sidi61

Jumpy 4. Okt 2016 08:20

AW: Excel Sheets
 
Hallo,

die Excel-Version bekommst du über:
Code:
Application.Version bzw. bei dir: ExcelApp.Version
Das ist ein String, den du dann mal analysieren musst.

Zur generellen Vorgehensweise: Ich würde einfach eine Stringlist, oder TStrings mit den Namen übergeben, dann weißt du zum einen die Anzahl der gewünschten Namen über den Listcount und kannst es dir auch sparen, deinen Namens-String mühsam zu zerlegen, wie du das jetzt machst.

Dann kannst du auch folgendes dann machen, um auf einen Schlag ein Workbook mit n leeren Sheets zu erzeugen:
Delphi-Quellcode:
AlteSheetZahl:=ExcelApp.SheetsInNewWorkbook
ExcelApp.SheetsInNewWorkbook:=Namensliste.Count
wb:=ExcelApp.Workbooks.Add
ExcelApp.SheetsInNewWorkbook:=AlteSheetZahl
for i:=0 to Namensliste.Count-1 do
  wb.Worksheets[i+1].Name:=Namensliste[i]
fertig.

Aviator 4. Okt 2016 12:08

AW: Excel Sheets
 
Was passiert wenn du einfach die Endung weglässt? Bei Excel gibt es eine Einstellung wie neue Arbeitsmappen standardmäßig gespeichert werden sollen. Wenn sich der User jetzt explizit einen Datentyp ausgewählt hat und deine Anwendung aber einen anderen verwendet, dann ist das u. U. nicht so gern gesehen.

Vielleicht speichert Excel die Datei dann mit der voreingestellten Endung wenn du sie einfach weglässt. Habe ich bisher aber noch nicht probiert.

Die Fehler werden bei mir auch massig in der Fehlerliste angezeigt. Ich habe meine Export Funktionen in eine eigene Unit ausgelagert damit diese nicht die wirklichen Fehler überdecken. Scheint ein Problem mit den Variants zu sein weil Error Insight das nicht richtig auflösen kann.

p80286 4. Okt 2016 15:58

AW: Excel Sheets
 
Zitat:

Zitat von Sidi61 (Beitrag 1349595)
Ein weiteres Problem wo ich noch keinen Ansatz gefunden habe:
Wie im Beispiel zu sehen gebe ich die Datei-Endung mit .xlsx an, was aber wenn der Anwender noch ein älteres Excel hat welches nur xls unterstützt.
Kann ich das irgendwie herausfinden ob xlsx geht oder nicht ??

Naja Excel weiß natürlich auch hier alles besser und verbindet mit den Qualifiern bestimmte Formate. Und noch besser Je nach Art eine Datei zu öffnen interpretiert Excel (und Word,und..) das Dateiformat oder aber nicht. Wenn Du auf der sicheren Seite sein willst, bleibt Dir nur die Frage "In welchem Format soll gespeichert werden?"

Gruß
K-H

himitsu 4. Okt 2016 16:19

AW: Excel Sheets
 
Zitat:

Zitat von HolgerX (Beitrag 1349550)
Durch die vielen (NOT VarIsEmpty( wurde es etwas unübersichtlich.. ;)

Zitat:

Delphi-Quellcode:
  if ((NOT VarIsEmpty(oExcel))and(NOT VarIsEmpty(oWB1))
      and(NOT VarIsEmpty(oWS1))and(NOT VarIsEmpty(oWS2))) then

Ein bissl Boolesche Algebra und viele NOT sind Geschichte.

Erstmal die obsoleten Klammern weg (außerdem können Leerzeichen ja soooooooowas von entspannend wirken)
Ich werde da immer ganz kirre, wenn ich sinnlos Klammern zählen muß, um zu erkennen was wirklich geklammert ist. (wir schreiben hier doch keine C-Codes, wo immer zuviele Klammern vorkommen und ich die gern mal mit { } verwechsle )
Delphi-Quellcode:
  if NOT VarIsEmpty(oExcel) and NOT VarIsEmpty(oWB1)
      and NOT VarIsEmpty(oWS1) and NOT VarIsEmpty(oWS2) then
und dann nur noch umdrehn
Delphi-Quellcode:
  if NOT (VarIsEmpty(oExcel) or VarIsEmpty(oWB1) or VarIsEmpty(oWS1) or VarIsEmpty(oWS2)) then

Warum NOT groß und IF THEN AND klein?

Sidi61 4. Okt 2016 18:54

AW: Excel Sheets
 
Hallo p80286,

da hast du wohl recht, werde es dann einfach in die Grundeinstellung des jeweiligen Programms auslagern, das hat den Charme dass der Anwender das Format selbst wählen kann und somit u.U. auch für ältere Excel Versionen auf ggf. vorhandenen Zweit-Rechnern kompatibel sein kann.

Gruß
Sidi61

Chemiker 4. Okt 2016 22:37

AW: Excel Sheets
 
Hallo himitsu,

Zitat:

Warum NOT groß und IF THEN AND klein?
Weil ich es kann!!
Ich schreibe seit Turbo Pascal 3.0 NOT und NIL immer groß, es ist für mich leichter lesbar. Kann ja jeder machen wie er will.
Deine Abhandlung über die Boolesche Algebra ist ja großartig, allerdings wird durch Deine Umstellung eigentlich mein Anliegen maskiert. Und das sieht man ja beim Beitrag Ersteller, er fragt die Variablen jetzt überhaupt nicht mehr ab und wundert sich später das er noch ein paar Excel – Instanzen offen hat.

Bis bald Chemiker

Jumpy 5. Okt 2016 09:24

AW: Excel Sheets
 
Zitat:

Zitat von Sidi61 (Beitrag 1349753)
Hallo p80286,

da hast du wohl recht, werde es dann einfach in die Grundeinstellung des jeweiligen Programms auslagern, das hat den Charme dass der Anwender das Format selbst wählen kann und somit u.U. auch für ältere Excel Versionen auf ggf. vorhandenen Zweit-Rechnern kompatibel sein kann.

Gruß
Sidi61

Da wirst du aber trotzdem nicht drum rum kommen, in deiner Speicher-Routine die Excel-Version zu prüfen. Denn wenn du ein neues Excel hast, der Benutzer aber im alten xls-Format speichern will, um die Datei auch auf seinem alten Rechner öffnen zu können brauchst du beim "Save As"-Befehl andere Parameter.

Delphi-Quellcode:
function ExcelVersion:integer;
begin
  //ExcelApp.Version liefert sowas wie 14.0
  Result:=Trunc(StrToFloat(ExcelApp.Version))
end;

//irgendwo in der Speichern-Routine:
//ab Version 12.0 gibts meine ich xlsx
If ExcelVersion>=12 then //Excel-Version ist neu
  begin
  If GewünschteDateiEndung='xlsx' then
    ExcelApp.SaveAs(GewünschterDateiname)
  Else //Endung='xls' gewünscht
    //56=Altes Excel-Format benutzen in neueren Excels
    ExcelApp.SaveAs(GewünschterDateiname,56)
  end
Else //Excel-Version ist alt
  begin
  If GewünschteDateiEndung='xlsx' then
    showmessage('Altes Excel kann neues Format nicht speichern')
  Else //Endung='xls' gewünscht
    ExcelApp.SaveAs(GewünschterDateiname)
  end;
Die Magic-Numbers sollte man natürlich durch ordentlich benamste Konstanten ersetzen.

p80286 5. Okt 2016 12:08

AW: Excel Sheets
 
Zitat:

Zitat von Jumpy (Beitrag 1349799)
Die Magic-Numbers sollte man natürlich durch ordentlich benamste Konstanten ersetzen.

Vertu' ich mich oder gibt's die nicht schon in Word und Excel?

Gruß
K-H

Jumpy 5. Okt 2016 13:03

AW: Excel Sheets
 
Zitat:

Zitat von p80286 (Beitrag 1349830)
Zitat:

Zitat von Jumpy (Beitrag 1349799)
Die Magic-Numbers sollte man natürlich durch ordentlich benamste Konstanten ersetzen.

Vertu' ich mich oder gibt's die nicht schon in Word und Excel?

Gruß
K-H

Ja klar (heißt xlExcel8 aus der XlFileFormat-Enumeration), aber wenn du von Delphi aus mit Late-Binding arbeitest, wie im bisher hier gezeigten Code, stehen diese Konstanten ja nicht zur Verfügung. Wenn man verschiedene Generationen von Excel berücksichtigen will, ist das ja auch der sichere Weg, denn ein altes Excel würde den betreffenden Konstantennamen ja u.U. gar nicht kennen.

Sidi61 5. Okt 2016 15:02

AW: Excel Sheets
 
Hallo Jumpy,

okay, dann sieht die Sache natürlich anders aus, habe nicht gewusst dass sich dadurch SaveAs bezüglich der Parameter ändert.
Ab Excel 7, in der Versionsangabe also 12.0 ändert sich das Dateiformat.

Hallo Chemiker,
ich habe deine Abfragen dann wohl falsch aufgenommen, habe deinen Code so interpretiert dass du jedes mal abfragst ob die Variable auch ein Objekt enthält mit dem gearbeite werden kann. Verstehe allerdings auch jetzt noch nicht wo genau geprüft wird ob es noch offene Instanzen gibt die geschlossen werden müssen. Bin einfach mal naiv davon ausgegangen, wenn ich weiß was ich geöffnet habe, weiß ich auch was ich schließen muss :oops:

Gruß
Sidi61

Sidi61 5. Okt 2016 20:18

AW: Excel Sheets
 
Hallo Jumpy,

nochmals Danke für deinen Tip, habe ich wie folgt umgesetzt:

Delphi-Quellcode:
unction TFormExcel.Excel_Arbeitsmappe_speichern(Z: string):boolean;
Var OK : boolean;
begin
  OK := true;
  if ExcelVersion >= 12 then //ab 12 Format xlsx
  begin
    try
      if uppercase(DS) = 'XLSX' then ExcelApp.ActiveWorkbook.saveas(Z+'.'+DS);
      //56 = altes Excel-Format benutzen
      if uppercase(DS) = 'XLS' then ExcelApp.ActiveWorkbook.saveas(Z+'.'+DS,56);
    except
      showmessage('speichern von '+Z+'.'+DS+' ist fehlgeschlagen');
      ok := false;
    end;
  end else
  begin
    if uppercase(DS) = 'XLSX' then
    begin
      Showmessage('Das Dateiformat .xlsx wird von Ihrer Version nicht unterstützt, die Speicherung erfolgt im .xls Format');
      DS := 'xls';
    end;
    try
      ExcelApp.ActiveWorkbook.saveas(Z+'.'+DS);
    except
      showmessage('speichern von '+Z+'.'+DS+' ist fehlgeschlagen');
      ok := false;
    end;
  end;
  Result := OK;
end;
Funktioniert prächtig :thumb:

Woher stammt die 56, konnte nirgends eine Doku dazu finden:?:

Gruß
Sidi61

p80286 5. Okt 2016 21:19

AW: Excel Sheets
 
Dan schau mal hier herein:
https://msdn.microsoft.com/de-de/lib.../ff198017.aspx
https://msdn.microsoft.com/de-de/lib...ileformat.aspx

Gruß
K-H

Chemiker 6. Okt 2016 00:32

AW: Excel Sheets
 
Hallo Sidi61,

man kann bei einem aktiven Workbook auch das entsprechende Fileformat herauslesen, das bedeutet, wenn man zum Beispiel ein altes Workbook (XLS-Format) in ein neues Excel öffnet, so kann man das Fileformt lesen und anschließend unter diesem alten Format wieder abspeichern.

Delphi-Quellcode:
aFileFormat := ExcelApp.ActiveWorkbook.Fileformat;
ExcelApp.ActiveWorkbook.SaveAs(Filename:=DateiName, FileFormat:=aFileFormat);

Bis bald Chemiker


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