![]() |
Mehrere Excel-Dateien bearbeiten
Hallo Delphie-Gemeinde,
ich bin schon ziemlich am Verzweifeln, weil ich mit meinem Problem einfach nicht weiter komme. Mein Programm berechnet 2 verschiedene Gruppen von Werten. Die sollen auch getrennt in Exceldateien abgespeichert werden. Es gibt jeweils die Möglichkeiten : 'Neue Datei öffnen', 'vorhandene Datei öffnen' und wenn sie erst einmal geöffnet sind, sollen die nächsten Werte weiter in der jeweiligen geöffneten Datei abgespeichert werden. Dabei ist zu beachten, dass die Werte der Gruppe A in die Datei A und die Werte der Gruppe B in die Datei B abgelegt werden und nicht vertauscht werden dürfen. Je nach Anforderung werden dann immer wieder neue Werte errechnet und müssen in die dazugehörige Datei geschrieben werden. Mein Problem besteht nun darin, dass ich es einfach nicht schaffe, die jeweiligen Exceldateien auseinanderzuhalten bzw. gezielt zu beschreiben. Meistens habe ich die Meldung 'Ungültiger Index'. Bin für jeden Tipp dankbar, wie man grundsätzlich an dieses Problem herangehen sollte, um die Dateien sauber zu trennen. Mit freundlichen Grüßen delphinewbie |
AW: Mehrere Excel-Dateien bearbeiten
Kannst du mal etwas Code zeigen, was du schon hast? Wie schreibst du generell in eine Excel-Datei? Direkt in die Binär-Datei oder öffnest du eine Excel-Instanz per "fernsteuerung"?
|
AW: Mehrere Excel-Dateien bearbeiten
Zitat:
Code:
und bearbeite das dadurch jeweils gerade aktivierte Arbeitsblatt.
Procedure ActivateWorkSheet(BookIndex, SheetIndex: Integer);
begin fExcel.WorkBook [BookIndex].Activate; fExcel.WorkSheets [SheetIndex].Activate; end; wobei:
Code:
eröffnet durch:
var fExcel: OLEvariant;
Code:
Benötigt die Units ActiveX, ComObj und Variants.
function GetOrCreateExcelObject: IDispatch;
var ClassName: String; ClassID: TGUID; Unknown: IUnknown; begin ClassName:='Excel.Application'; ClassID := ProgIDToClassID(ClassName); if Succeeded(GetActiveObject(ClassID, nil, Unknown)) then OleCheck(Unknown.QueryInterface(IDispatch, Result)) else Result := CreateOleObject(ClassName); end; |
AW: Mehrere Excel-Dateien bearbeiten
Zitat:
Besser ist es da Objektvariablen anzulegen und dann direkt Werte aus Zellen auszulesen oder zuzuweisen, ala:
Delphi-Quellcode:
var
w1:Variant; //Variablen für Workbooks w2:Variant; ws1:Variant; //Variablen für Worksheets ws2:Variant; //Kenn das nur direkt aus VBA, kann sein, das in Delphi die Variablen //vom Typ Object sein müssen. In VBA reicht Variant. begin w1:=fExcel.Workbooks[1]; //Wenn Workbooks offen nur zuweisen, w2:=fExcel.Workbooks.Add(Pfadname); //sonst öffnen (oder war es mit .open?) ws1:=w1.Workshhets[4]; ws2:=w2.Workshhets[4]; //Machwas ws1.cells[1,1].Value := ws2.Cells[1,1].Value; end |
AW: Mehrere Excel-Dateien bearbeiten
Zitat:
Wenn man es aber schon komfortabel, flexibel und mit allen Feinheiten haben will, sollte man ohnehin alles in eine eigene Klasse kapseln. So jedenfalls mache ich das für MSWord und MSExcel in eigenen Klassen tMSExcel und tMSWord mit einer Vielzahl an Methoden zum Handling der Documents bzw. Datenblätter (deren komplexe interne Anweisungen in den Details man sich sowieso nicht dauernd merken kann). Damit sieht dann z.B. die Belegung einer Excel-Zelle ganz einfach so aus:
Code:
wobei als Parameter übergeben werden: WorkBookIndex, WorksheetIndex, Spalte, Reihe und Eintrag.
MSExcelApp.SetCellContent(2,1,4,3,s); // MSExcelApp ist die Instanz der Klasse
Diese Methode z.B. ist in meiner Klasse so implementiert:
Code:
wobei fExcel das in der Klasse deklarierte OleObject 'Excel.Application' ist, das im Constructor generiert wird,
function tMSExcel.SetCellContent(aBook, aSheet: Word; aCol, aRow: Word; content: string): Boolean;
begin result := false; if (aCol=0) or (aRow=0) then exit; if (aBook > high(ExcelSheets)) or (aSheet > high(ExcelSheets[aBook])) then exit; if not VarIsEmpty(fExcel) then begin if (aBook=0) or (aSheet=0) then // das gegenwärtig aktive Worksheet benutzen fExcel.ActiveSheet.Cells[aRow, aCol].Value := content else // auf explizit genanntes Worksheet zugreifen ExcelSheets[aBook, aSheet].Cells[aRow, aCol].Value := content; result := true; end; end; und ExcelSheets ein Array of Array of Olevariant ist mit der 1.Dimension für die WorkBooks und mit der 2.Dimension für die den Workbooks jeweils zugehörigen WorkSheets. Größe sowie Belegung des offenen Arrays werden bei Öffnung oder Neuanlage eines Workbooks sowie der entsprechenden WorkSheets gemäß derem jeweiligen Index automatisch zugewiesen buw. modifiziert in der Art:
Code:
und
Setlength(ExcelSheets,AnzahlWorksBooks+1,AnzahlWorkSheetsImBook+1);
Code:
Den jeweiligen Index = 0 lasse ich frei (also unassigned). so dass der Indexverlauf des Arrays 1:1 synchron mit dem der Zählung bei Excel verläuft.
ExcelSheets[i,j]:=fExcel.WorkBooks[i].Worksheets[j];
Das Ergebnis dieser automatischen Verwaltung ist der sehr komfortable Zugriff auf die verschiedenen Operationen mit Excel wie oben als Beispiel mit SetCellContent() gezeigt. |
AW: Mehrere Excel-Dateien bearbeiten
Sieht sehr interessant aus. Wir haben den Zugriff auch meist in einer Klasse gekapselt, haben aber nur ein paar Sonderfunktionen, die wir oft brauchen eingebaut. Für alles, was davon abweicht, müssen wir dann doch wieder weit durchgreifen, ala Excelklasse.Workbook.Worksheet....
Einzige weitere Erleichterung sind ein paar benannte Konstanten, sodass man VBA-Code nahezu 1 zu 1 übernehmen kann. |
AW: Mehrere Excel-Dateien bearbeiten
Zitat:
* wahlfreie Zugriffe auf verschiedene, gleichzeitig geöffnete Workbooks und deren einzelne Worksheets (wie oben gezeigt), * Eingabe und Auslesen einzelner Zellen oder ganzer Bereiche eines Worksheets, * Formatierung einer Zelle im Worksheet (Schrift, Farbe, Style), * Kopieren eines bestimmten Bereiches aus einem Worksheet in die Zwischenablage, * Übertragung eines Stringgrids in ein Worksheet oder vice versa, * Vorgaben zur Grafikdarstellung im Worksheet, * Pagelayout für die Druckausgabe (Header, Footer, Seitengröße, Ränder, Portrait vs. Landscape, FitToPage) Das einzige, was bei mir merwürdigerweise bisher nicht geklappt hat, ist die Übertragung einer Grafik aus einem Excel-Worksheet in den Positionsrahmen eines gleichzeitig geöffneten Winword-Dokumentes mittels ausschließlicher Anweisung per Delphicode. |
AW: Mehrere Excel-Dateien bearbeiten
Ist den das Frame Objekt von außen nicht erreichbar?
Per VBA in Excel geht sowas (war Neugierig):
Code:
Die Grafik wird im Positionsrahmen verankert, ist aber größer als dieser. Mit einfach nur Selection.Paste wird sie als Grafik in den Rahmen gequetscht. Wenn ich mal Zeit hab, probier ich das auch nochmal von Delphi aus.
Sub Test()
Dim w As Word.Application Dim d As Word.Document Dim f As Word.Frame ActiveSheet.ChartObjects("Diagramm 1").Activate ActiveChart.ChartArea.Select ActiveChart.ChartArea.Copy Set w = New Word.Application w.Visible = True Set d = w.Documents.Add d.Activate Set f = d.Frames.Add(w.Selection.Range) f.Range.Select w.Selection.PasteSpecial Link:=False, DataType:=wdPasteOLEObject, Placement _ :=wdFloatOverText, DisplayAsIcon:=False '... End Sub |
AW: Mehrere Excel-Dateien bearbeiten
So, nun bin ich nach einwöchiger Auszeit endlich wieder da.
Vielen Dank für Eure Tipps. Ich habe mich erstmal an jumpys Methode (#4) orientiert und es hat super geklappt. Soweit reicht mir das auch schon. Das einzige, was bei mir nicht funzt: Wenn zwei Excel-Mappen bereits geöffnet sind, möchte ich jeweils die Mappe anzeigen, in die gerade geschrieben wurde. w1 zeigt auf Mappe1; w2 auf Mappe2; ws1 zeigt z.B. auf Sheet2 der Mappe1; ws2 auf Sheet1 der Mappe2 Mit bspw. w1.Activate oder ws1.Activate funzt das bei mir nicht. Ist Activate dazu überhaupt die richtige Methode? Oder bin ich da noch auf dem Holzweg? Trotzdem erstmal vielen Dank für Eure Hilfen. Es ist gut zu wissen, wo man selbst für diese sicherlich trivialen Probleme eine Lösung findet und nicht gleich als Depp hingestellt wird. MfG delphinewbie |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:55 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 by Thomas Breitkreuz