![]() |
Excel mit mehreren Sheets öffnen
Moin ich habe folgendes Problem:
Ich habe eine xls Datei mit mehreren Sheets und möchte sie in Stringgrid einlesen. Mit dem ersten Sheet funktioniert es auch aber ab dem 2. kommt immer eine Fehlermeldung. "Die Activate Methode des Range Objektes konnte nicht ausgeführt werden" Jemand eine Idee wo mein Denkfehler ist?
Code:
function TTools.Xls_To_StringGrid(AGrid: TStringGrid; AXLSFile: string; Sheetname : string): Boolean;
const xlCellTypeLastCell = $0000000B; var XLApp, Sheet: OLEVariant; RangeMatrix: Variant; x, y, k, r: Integer; begin Result := False; XLApp := CreateOleObject('Excel.Application'); // Create Excel-OLE Object try XLApp.Visible := True; // Excel XLApp.Workbooks.Open(AXLSFile); // Open the Workbook Sheet := XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[sheetname]; // Sheet := XLApp.Workbooks[1].WorkSheets[1]; // In order to know the dimension of the WorkSheet, i.e the number of rows // and the number of columns, we activate the last non-empty cell of it Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate; x := XLApp.ActiveCell.Row; // Get the value of the last row y := XLApp.ActiveCell.Column; // Get the value of the last column // Set Stringgrid's row &col dimensions. AGrid.RowCount := x; AGrid.ColCount := y; RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value; // Assign the Variant associated with the WorkSheet to the Delphi Variant // Define the loop for filling in the TStringGrid k := 1; repeat for r := 1 to y do AGrid.Cells[(r - 1), (k - 1)] := RangeMatrix[K, R]; Inc(k, 1); AGrid.RowCount := k + 1; until k > x; // Unassign the Delphi Variant Matrix RangeMatrix := Unassigned; finally // Quit Excel if not VarIsEmpty(XLApp) then begin XLApp.DisplayAlerts := False; XLApp.Quit; XLAPP := Unassigned; Sheet := Unassigned; Result := True; end; end; end; procedure TTools.EinlesenFClick(Sender: TObject); begin Xls_To_StringGrid(DE_XLS, ExcelE.Text, 'DE'); Xls_To_StringGrid(CH_XLS, ExcelE.Text, 'CH'); end; |
AW: Excel mit mehreren Sheets öffnen
unsicher:
War es nicht so, dass Excel zwischen technischen (intern) und sichtbaren Sheetnames unterscheidet? Die beiden Attribute können identischen Inhalt haben oder sich unterscheiden (bei kopierten Sheets z.B.). Einfach mal ein workbook öffnen und alles sheetnamen ausgeben lassen bzw. Doku nachschlagen, wie das mit der Sheetbenennung/Zugriff ist. |
AW: Excel mit mehreren Sheets öffnen
also wenn ich XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[sheetname].name mir als showmessage ausgeben lasse passt es, das er das sheet findet. Er hat auch immer nur dann ein Problem, wenn ich nicht mit Sheet 1 arbeiten möchte (die Sheets sind vom Aufbau identisch).
und er hat eindeutig mit "Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;" ein Problem, wenn ich das auskommentiere läufts durch, nur bekomme ich natürlich nicht das Ergebnis was ich brauche. |
AW: Excel mit mehreren Sheets öffnen
Vermutlich geht es nicht, weil es sich nicht um das aktive Sheet handelt.
|
AW: Excel mit mehreren Sheets öffnen
Das habe ich auch schon probiert, dann bekomme ich die Fehlermeldung:
"Variante des Typs (Error) konnte nicht in Typ (OleStr) konvertiert werden." Und das auch nur wenn ich "Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;" mit drin habe. ... Edit: Es lag an der Exceldatei, kleine Korrekturen haben den Fehler behoben. -.- |
AW: Excel mit mehreren Sheets öffnen
Zitat:
Ich meine, dass du vorher noch das hier ausführen musst:
Delphi-Quellcode:
Sheet.Select;
|
AW: Excel mit mehreren Sheets öffnen
Hallo Moombas
hier Sheet := XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[sheetname]; muss das nicht so lauten? XLApp.workbooks.open(ExtractFileName(AXLSFile)); Sheet := XLApp.WorkSheets[sheetname].Select; Gruss Peter |
AW: Excel mit mehreren Sheets öffnen
Hmm..
Zitat:
Du müsstest zunächst das Sheet selber auf 'active' setzen, nicht nur die 'Cells.SpecialCells'. 'Sheet.Activate;' |
AW: Excel mit mehreren Sheets öffnen
Es lag an der Exceldatei, kleine Korrekturen haben den Fehler behoben.
|
AW: Excel mit mehreren Sheets öffnen
Moin zusammen,
ich bin es nochmal und habe einen kleinen Nachtrag/Nachfrage, die am besten hierzu passt. Der Fehler der Exceltabelle beim Einlesen lag immer dann vor, wenn ein Filter gesetzt war und dieser bestimmte Zeilen raus gefiltert hat (ich war davon ausgegangen, das der Filter nur eine optische Geschichte ist und im Hintergrund die Tabelle ja noch alle Daten hat). Weiß jemand wie ich den Filter über Delphi entferne? Das was in den Excel-Makros drin steht, hat leider nicht geholfen, denn wenn ich "Sheet.ShowAllData;" aktiviere kann mein Programm die Exceldatei nicht mehr einlesen (keine Fehlermeldung, das Stringgrid bleibt einfach leer). Ich würde damit gerne diese Fehlerquelle ausschließen.
Delphi-Quellcode:
function XLS_To_StringGrid(AXLApp : OleVariant; AGrid : TStringGrid; Sheetname : string):Boolean;
const xlCellTypeLastCell = $0000000B; var Sheet: OLEVariant; RangeMatrix: Variant; X, Y, K, R: Integer; begin Result := False; try try if (Sheetname <> '') and HaveSheet(AXLApp, Sheetname) then begin Sheet := AXLApp.WorkSheets[Sheetname]; end else Sheet := AXLApp.WorkSheets[1]; // In order to know the dimension of the WorkSheet, i.e the number of rows // and the number of columns, we activate the last non-empty cell of it Sheet.select; // Sheet.ShowAllData; Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate; X := AXLApp.ActiveCell.Row; // Get the value of the last row Y := AXLApp.ActiveCell.Column; // Get the value of the last column // Set Stringgrid's row &col dimensions. AGrid.RowCount := X; // Excel-Row 1 = Header AGrid.ColCount := Y; RangeMatrix := Sheet.Range['A1', Sheet.Cells.Item[X, Y]].Value; // Assign the Variant associated with the WorkSheet to the Delphi Variant // Define the loop for filling in the TStringGrid K := 0; While (K < X) do begin Inc(K); for r := 1 to y do AGrid.Cells[(R - 1), (K - 1)] := RangeMatrix[K, R]; end; Result := True; except // Logging... end; finally RangeMatrix := Unassigned; Sheet := Unassigned; end; end; |
AW: Excel mit mehreren Sheets öffnen
Sheet.UsedRange.Columns.AutoFilter
sollte den Autofilter abwechslnd ein und ausschalten. |
AW: Excel mit mehreren Sheets öffnen
Danke Ralph hierfür, allerdings ist ein umschalten (ein/aus) der Autofilter denke ich nicht so gut. Da der Filter sonst gesetzt wird, wo vorher keiner war und das möchte ich eigentlich auch so beibehalten. Daher wollte ich ihn einfach "löschen", was laut Excelmakro ".ShowAllData" ist. Jedoch keine Ahnung wo ich das einsetzen muss, wenn "sheet.ShowAllData"nicht funktioniert.
|
AW: Excel mit mehreren Sheets öffnen
Hmm..
Um zu Prüfen, ob ein Filter aktiviert wurde:
Delphi-Quellcode:
if Excel.ActiveSheet.FilterMode then
und um das Filtern auf einem Sheet auszuschalten:
Delphi-Quellcode:
Excel.ActiveSheet.AutoFilterMode := False;
|
AW: Excel mit mehreren Sheets öffnen
Das ist zu 95% so, wie ich es gesucht habe^^ Zwar ist der Filter dann komplett weg (und nicht nur die Filterbedingungen raus) aber das ist nicht schlimm und umgeht damit das "Speicherproblem".
Edit: Mit "if AXLApp.ActiveSheet.FilterMode then AXLApp.ActiveSheet.ShowAllData;" geht es wie gewollt :D Danke für den Tipp HolgerX Beim Laden der Datei sieht es dann so aus:
Delphi-Quellcode:
Und beim Speichern so:
function XLS_To_StringGrid(AXLApp : OleVariant; AGrid : TStringGrid; Sheetname : string):Boolean;
const xlCellTypeLastCell = $0000000B; var Sheet: OLEVariant; RangeMatrix: Variant; X, Y, K, R: Integer; begin Result := False; try try if (Sheetname <> '') and HaveSheet(AXLApp, Sheetname) then begin Sheet := AXLApp.WorkSheets[Sheetname]; end else Sheet := AXLApp.WorkSheets[1]; // In order to know the dimension of the WorkSheet, i.e the number of rows // and the number of columns, we activate the last non-empty cell of it Sheet.select; if AXLApp.ActiveSheet.FilterMode then AXLApp.ActiveSheet.ShowAllData; //Fix: Fehler durch gesetzte Filter vermeiden Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate; X := AXLApp.ActiveCell.Row; // Get the value of the last row Y := AXLApp.ActiveCell.Column; // Get the value of the last column // Set Stringgrid's row &col dimensions. AGrid.RowCount := X; // Excel-Row 1 = Header AGrid.ColCount := Y; RangeMatrix := Sheet.Range['A1', Sheet.Cells.Item[X, Y]].Value; // Assign the Variant associated with the WorkSheet to the Delphi Variant // Define the loop for filling in the TStringGrid K := 0; While (K < X) do begin Inc(K); for r := 1 to y do AGrid.Cells[(R - 1), (K - 1)] := RangeMatrix[K, R]; end; Result := True; except // Logging... end; finally RangeMatrix := Unassigned; Sheet := Unassigned; end; end;
Delphi-Quellcode:
function StringGridToXLS(AXLApp : OleVariant; AGrid : TStringGrid; Sheetname : string):Boolean;
const xlCellTypeLastCell = $0000000B; var Sheet: OLEVariant; MaxCol : Integer; MaxRow : Integer; Range : OleVariant; Data : OleVariant; Col : Integer; Row : Integer; R1,R2 : string; begin Result := False; try //Worksheet auswählen if (Sheetname <> '') and HaveSheet(AXLApp, Sheetname) then begin Sheet := AXLApp.WorkSheets[sheetname]; end else Sheet := AXLApp.WorkSheets[1]; Sheet.select; if AXLApp.ActiveSheet.FilterMode then AXLApp.ActiveSheet.ShowAllData; //Fix: Fehler durch gesetzte Filter vermeiden // Der vorhandenen Daten im Grid, nicht der möglichen in Excel... MaxCol := AGrid.ColCount; MaxRow := AGrid.RowCount; if (MaxRow > 0) and (MaxCol > 0) then begin //Bereich auswählen R1 := RefToCell(1, 1); R2 := RefToCell(MaxCol, MaxRow); Range := Sheet.Range[R1, R2]; if not VarIsNull(Range) then begin //Daten aus Grid holen Data := VarArrayCreate([1, MaxRow, 1, MaxCol], varVariant); for Row := 0 to Pred(MaxRow) do begin for Col := 0 to Pred(MaxCol) do begin Data[Succ(Row), Succ(Col)] := AGrid.Cells[Col, Row]; end; end; //Daten dem Excelsheet übergeben Range.Value := Data; Range.Columns.AutoFit; Result := True; end; end; finally SaveExcel(AXLApp); Range := UnAssigned; Sheet := Unassigned; Data := Unassigned; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:36 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