Zelleninhalt aus bestehender Excel97-Tabelle auslesen
-
Hallo,
ich (Einsteiger...) habe mir über MFC einen Befehlssatz erstellt um auf Excel-Tabellen zugreifen zu können (ist das so korrekt?)...
Über welche Befehlsfolge kann ich auf einen Zelleninhalt einer Excel-Tabelle zugreifen und diesen dazu verwenden, um den Dateinamen zu ändern?
Ich vermute, daß ich dieses überrange = sheet.GetRange(COleVariant("VON"),COleVariant("BIS")); ergebnis = range.GetValue();
bekommme. Jetzt ist nur noch meine Frage, wie ich eine bestehende Datei öffne und welchen Datentyp ergebnis haben muß... Kann ich zum abspeichern die Funktion
book.SaveCopyAs("ERGEBNISPFAD");
verwenden?
Danke für eure Antworten...
-
Okay, ich wandle meine Frage ab:
Wie ist die Vorgehensweise zum Öffnen einer bestehenden Excel-Tabelle?
Verwendung ist VC++ 6.0 und Excel 97...
Kann mir jemand ein Beispiel posten? Bis jetzt habe ich:void CAutoProjectDlg::OnRun() { // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen // Commonly used OLE variants. COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); _Application app; Workbooks books; _Workbook book; Worksheets sheets; _Worksheet sheet; Range range; Font font; Range cols; // TEST // Start Excel and get Application object. if(!app.CreateDispatch("Excel.Application")) { AfxMessageBox("Couldn't start Excel and get Application object."); return; } //Get a new workbook. // Hier kommt mein Problem: books.Open("J:\\test1.xls"); // wie schaffe ich jetzt die Verknüpfung zur Variablen 'book'? // ein einfaches book = books.Open("J:\\test1.xls"); erzeugt einen Speicherfehler... //Get the first sheet. sheets =book.GetSheets(); sheet = sheets.GetItem(COleVariant("Tabelle1"));
Den Code habe ich von der Microsoft-Seite übernommen. Dazu gesagt, daß ich in der excel8.h den Prototypen für 'Open' wie folgt abgeändert habe:
ausLPDISPATCH Workbooks::Open(LPCTSTR Filename, const VARIANT& UpdateLinks, const VARIANT& ReadOnly, const VARIANT& Format, const VARIANT& Password, const VARIANT& WriteResPassword, const VARIANT& IgnoreReadOnlyRecommended, const VARIANT& Origin, const VARIANT& Delimiter, const VARIANT& Editable, const VARIANT& Notify, const VARIANT& Converter, const VARIANT& AddToMru);
in
LPDISPATCH Open(LPCTSTR Filename);
;
in der excel8.cpp hab ich auch dementsprechend (stand in ner Google-Group) die Funktion entsprechend abgeändert:LPDISPATCH Workbooks::Open(LPCTSTR Filename) { LPDISPATCH result; static BYTE parms[] = VTS_BSTR; InvokeHelper(0x2aa, DISPATCH_METHOD, VT_DISPATCH, (void*)&result,parms, Filename); return result; }
Ich hoffe, ich habe alles einigermaßen richtig dargestellt... Es geht mir nur darum, einen popeligen Tabelleneintrag auszulesen....
-
Okay... Ich habs selbst rausbekommen. Zwar mehr mit der Brechstange als mit Verstand, aber immerhin... Es ist noch schweinisch lahm und an einigen Ecken beendet er den Excel-Prozess nicht sauber... Verbesserungsvorschläge immer gerne....
void CAutoProjectDlg::OnRun() { COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); // Ausgabevariable ist ein Union VARIANT output; int i, laenge; char * string, * string2; _Application app; Workbooks books; _Workbook book; Worksheets sheets; _Worksheet sheet; Range range; Font font; Range cols; /* Display an Open File common dialog Dependencies: CFileDialog (MFC) (software.unclassified.de) */ // Create an instance CFileDialog fileDlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY, "Excel-Files (*.xls)|*.xls|All Files (*.*)|*.*||", this); CString dateiname, ausgabedatei; // Initializes m_ofn structure DWORD MAXFILE = 2562; //2562 is the max fileDlg.m_ofn.nMaxFile = MAXFILE; char* pc = new char[MAXFILE]; fileDlg.m_ofn.lpstrFile = pc; fileDlg.m_ofn.lpstrFile[0] = NULL; fileDlg.m_ofn.lpstrTitle = "Öffnen"; // Call DoModal system ("md c:\\programme\\sicherung"); if(!app.CreateDispatch("Excel.Application")) { AfxMessageBox("Couldn't start Excel and get Application object."); return; } if (fileDlg.DoModal() == IDOK) { CListBox m_cList1; POSITION pos = fileDlg.GetStartPosition(); while(pos !=NULL) { dateiname = fileDlg.GetNextPathName(pos); // TEST // Start Excel and get Application object. //Get a new workbook. books = app.GetWorkbooks(); book = books.Open(dateiname); //Get the first sheet. sheets = book.GetSheets(); // Zugriff auf das Tabellenblatt 1.Einstieg sheet = sheets.GetItem(COleVariant("1.Einstieg")); // Zugriff auf Zelle F6 range = sheet.GetRange(COleVariant("F6"),COleVariant("F6")); // Rückgabe von GetValue als VARIANT-Struktur in output output = range.GetValue(); for (laenge = 0; output.bstrVal[laenge]; laenge++); string = (char *) malloc (laenge * sizeof (char)); sprintf (string, ""); for (i = 0; i < laenge; i++) { if ((output.bstrVal[i] == '\\') || (output.bstrVal[i] == '/') || (output.bstrVal[i] == '.') || (output.bstrVal[i] == ':') || (output.bstrVal[i] == ';') || (output.bstrVal[i] == ',')) sprintf (string, "%s-\0", string); else sprintf (string, "%s%c\0", string, output.bstrVal[i]); } string2 = (char *) malloc (laenge+sizeof("c:\\programme\\SICHERUNG\\ - TESTDATEI\0") * sizeof (char)); sprintf (string2, "c:\\programme\\SICHERUNG\\%s - TESTDATEI.xls\0", string); book.SaveAs(COleVariant(string2), covOptional, covOptional, covOptional, covOptional,covOptional, (long)1, //AccessMode: xlNoChange = 1 covOptional, covTrue, //AddToMru covOptional, covOptional); books.Close(); } } app.Quit(); }
-
Vielleicht hilft dir das weiter:
http://download.pearsoned.de/leseecke/VCPLUS6_21Tg/data/start.htm
http://www.henkessoft.de/mfc_einsteigerbuch_kapitel12.htm
-
*g*
Das man nur Antworten bekommt, wenn man ein Problem gelöst hat...
Mein Problem ist weiterhin das saubere beenden des Excel-Prozesses... Kann ich das irgendwie sicherstellen? Die Zeileapp.Quit();
hab ich ja bereits am Ende... Diese würde ich jetzt nochmal gerne aufrufen, wenn das Kreuz zum Schließen der Dialogbox aktiviert wird...
Desweiteren habe ich noch ein Performance-Problem. Das Öffnen und Speichern der Mappen erfolgt sehr langsam. Das kann allerdings auch am Netzzugriff liegen, wenn ich das ganze auf der Festplatte durchführen ist es zwar auch nicht das schnellste, läuft aber recht annehmbar... Gibt es eine Möglichkeit, das ganze noch zu beschleunigen?