In Excel Datei schreiben





  • Ich wollte sicher nicht das Rad neu erfinden. 😉

    Ne, deswegen fragte ich ja.

    Vielen Dank für den Tipp. 🙂



  • na wenn du mir nicht sagen willst was genau du machen willst kann ich dir leider nicht helfen! Aber mal nur als ein kleiner Tip willst du nachher ne FKT über ne Spalte machen die eigentlich NUMBER ist dann hast du mit der DB variante keine Chance!



  • rewe schrieb:

    Ich wollte sicher nicht das Rad neu erfinden. 😉

    Ne, deswegen fragte ich ja.

    Vielen Dank für den Tipp. 🙂

    kein problem wußte den link auch nur weil ich an diesem Thread damals ( etwas ) beteiligt war:

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-2319-and-highlight-is-excel.html

    ciao veganza



  • Polofreak schrieb:

    na wenn du mir nicht sagen willst was genau du machen willst kann ich dir leider nicht helfen! Aber mal nur als ein kleiner Tip willst du nachher ne FKT über ne Spalte machen die eigentlich NUMBER ist dann hast du mit der DB variante keine Chance!

    Ne, warum sollte ich dir das nicht sagen wollen?!? 😉

    Was ich machen will, habe ich eigentlich schon gesagt.
    Nur Zahlen+Text zellenweise in die Excel-Datei schreiben. Nichts weiter.

    Dafür sollte diese Klasse doch genau das richtige sein, oder? Oder warum denkst
    du das das nicht funktionieren wird?



  • Also ich nimm jetzt mal einfach ganz mutwillig wie ich bin an du willst daten aus einer DB in eine Excel-Tabelle schreiben, oder??
    Dann geht das nämlich viiiiiiiiiiiiiieeeeeeeeeeeeelll einfacher!!!! Flieg mal schnell über diesen Code hier:

    CDatabase database; 
      CString sDriver = "MICROSOFT EXCEL DRIVER (*.XLS)"; // exactly the same name as in the ODBC-Manager 
      CString sExcelFile = "c:\\demo.xls";                // Filename and path for the file to be created 
      CString sSql; 
    
      TRY 
      { 
        // Build the creation string for access without DSN 
    
        sSql.Format("DRIVER={%s};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s", 
                    sDriver, sExcelFile, sExcelFile); 
    
        // Create the database (i.e. Excel sheet) 
        if( database.OpenEx(sSql,CDatabase::noOdbcDialog) ) 
        { 
          // Create table structure 
          sSql = "CREATE TABLE demo (Name TEXT,Age NUMBER)"; 
          database.ExecuteSQL(sSql); 
    
          // Insert data 
          sSql = "INSERT INTO demo (Name,Age) VALUES ('Bruno Brutalinsky',45)"; 
          database.ExecuteSQL(sSql); 
        }       
    
        // Close database 
        database.Close(); 
      } 
      CATCH_ALL(e) 
      { 
        TRACE1("Driver not installed: %s",sDriver); 
      } 
      END_CATCH_ALL;
    


  • Polofreak schrieb:

    Also ich nimm jetzt mal einfach ganz mutwillig wie ich bin an du willst daten aus einer DB in eine Excel-Tabelle schreiben, oder??
    Dann geht das nämlich viiiiiiiiiiiiiieeeeeeeeeeeeelll einfacher!!!! Flieg mal schnell über diesen Code hier:

    Cool. Geht wirklich super einfach. Muss ich mir merken sollte ich das mal brauchen.

    Bei mir ist es eben so das die Daten nicht in einer Datenbank sind - die Daten sind in Form von STL-Vectoren gespeichert.

    Die Wrapper-Klasse von Godeguru werde ich jetzt trotzdem nicht benutzen. Die ist a) riesig und b) sollte die Klasse irgendwelche Probleme machen, bin ich ziemlich verloren.

    Werde es jetzt mit dieser Hilfe da machen
    http://www.a-m-i.de/tips/office/officeautomation.php#cppexample_Excel

    das schaut relativ einfach aus. Und sollte gerade reichen, um die gestellte Anforderung zu erreichen.



  • Bei genauerem Hinsehen hättest du vielleicht bemerkt das der Code von
    "Polofreak" in eine Excel-Sheet schreibt. Nur halt mit mit einem Excel-ODBC-
    Datenbanktreiber. 😉

    Das ist sicher einfacher als über COM, wenn das deinen Anforderungen, füllen
    von Zellen aus STL-Containern, genügt.



  • bist du dir sicher dass du das von dir ge URLte machen willst?? Das ist nicht das, das du willst! du kannst doch auch aus deinen Vectoren über meine gezeigte FKt schreiben! Musst nur diesen Teil dynamisch gestalten

    sSql = "INSERT INTO demo (Name,Age) VALUES ('Bruno Brutalinsky',45)"; 
          database.ExecuteSQL(sSql);
    

    Bzw halt mit ner Schleife drüber gehen!
    CDatabase ist nur für Excel
    bis morgen



  • ARGH. Hab es missverstanden. 😉

    Ne, klar, dann mach ich es natürlich so. 🙂

    EDIT:

    Hab es eben mal ausprobiert. Funktioniert genau so wie es soll!
    Danke! 😃



  • na siehste, jetzt haste echt richtig einfach das erstellen einer Excel-Datei und füllen über DB-Funktionen gesehen. Wenn du noch mehr Infos brauchst, kannst du auch mal in den Source schauen von Codeguru, das ist nämlich vom Prinzip her genau so gestaltet, kannst als da drin nach den Funktionen schauen. Wenn du doch noch formatieren willst, fett oder farbig oder autofit... dann melde dich einfach nochmal auch das bekämen wir hin 😉



  • @ Polofreak:

    Kannst da auch mal Code zu posten? Also was Formatierung von Zellen betrifft?



  • aber über das Database-Objekt geht es leider nicht.
    Ich kann dir gerne Code posten. Schau dir aber zuerst mal das nochmal an. Hast ja schon, aber haste das denn auch verstanden? Denn auf dem basiert was ich dir erklären will. Wenn du das verstanden hast dann versuch das, Grundprinzip mal aufzustellen und wenn du dann Probleme hast melde dich noch mal.



  • Ich melde mich noch mal.

    Also, ich brauche zwei Funktionen:

    - Schrift einer Zelle auf Fett ändern.
    - Format einer Zelle auf 'Zahl' ändern.

    Kannst mir helfen? Dank schon mal.

    BTW: Das Schreiben in Excel funktioniert sehr gut.
    Nur eine Kleinigkeit stört noch: Fülle ich z.B. den Wert "text" ab, steht in Excel schlussendlich effektiv "'text". Also mir einem führendem Hochkomma.
    Gibt es da eine Möglichkeit das dies nicht erscheint?



  • Es gibt schon möglichkeiten, dass das nicht erscheint, das Problem ist nur diese Möglickeit gibt es nicht wenn du Excel als DB Objekt benutzt! Dieses führende ' soll soviel bedeuten wie diese Zeile ist keine Zahl. Dazu müsstest du Excel nun auf eine andere Art und Weise automatisieren. Ich meine du hättest dich da mal in irgend eine Art eingelesen, denn ich hab dir zu verschiedenen automatisierungsarten ne Funktion zum fett schreiben. Aber wenn du sowas machen willst darfste nicht vergessen, du musst Excel als Objekt einbinden. Da kommste nicht drum herum. Ich glaube du hast dich in ein schema eingelesen, wozu diese Funktion passen könnte:

    // macht übergebenen Bereich (Schriftart) FETT
    bool CExtendedExcel::Fett(CString VonZelle, CString BisZelle)
    {
    	//LPCTSTR wird benötigt um Bereich zu holen
    	LPCTSTR von = _T(VonZelle);
    	LPCTSTR bis = _T(BisZelle);
    	try
    	{	//Bereich holen
    		xlRange = excel->GetRange(von,bis);
    		//Für gewählten Bereich Schrift fett machen
    		xlRange->Font->Bold = true; //Fett machen
    		return TRUE;
    	}
    	catch(_com_error &ce)
    	{//Fehlerbehandlung
    		m_sLastError = ce.Description();
    		return FALSE;
    	}
    }
    


  • Das mit dem führendem Komma ist kein Problem. Ich belasse es dabei.

    Ich muss also Excel als Objekt einbinden? Wie mache ich das?

    Edit:

    http://www.a-m-i.de/tips/office/officeautomation.php#cppexample_Excel
    Hier gibt es ja schon ein paar Funktionen. Ich nehme an das die Funktion Fett ebenfalls auf diesem Prinzip basiert.
    Gibt es denn nicht eine Klasse wie die geurlte, die aber mehr Möglichkeiten (Formatierung, etc.) bietet? Das müsste es doch sicher geben...



  • Es gibt mehrere Möglichkeiten z.B. so:

    #include "stdafx.h"
    #include <odbcinst.h> // glaub dieses Include brauchste gar nicht
    #include <afxdb.h>
    #import "C:\Programme\Microsoft Office\Office\MSO9.DLL"
    #import "C:\Programme\Gemeinsame Dateien\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
    #import "C:\Programme\Microsoft Office\Office\EXCEL9.OLB" \
    

    Am besten machste dir ne eigene Klasse wo du das rein machst. Die Header musst dann natürlich auch noch includen.
    nach dem du das gemacht hast solltest du noch:

    rename("DialogBox", "ExcelDialogBox") \
      rename("RGB", "ExcelRGB") \
      no_dual_interfaces
    
    	Excel::_ApplicationPtr excel;
    	Excel::_WorkbookPtr workbook;
    	Excel::_WorksheetPtr worksheet;
    	Excel::FontPtr font;
    	Excel::RangePtr xlRange;
    	Excel::_ChartPtr xlChart;
    

    Bei den PTR Objekten natürlich nur die die du auch brauchst. Jetzt solltest du noch dein ATL Objekt.

    Du musst dein Objekt aber auch noch initialisieren und wenn du es nciht mehr braucht uninitialisieren
    das machst du mit

    CoInitialize(NULL);
    

    bzw

    CoUnInitialize(NULL);
    

    Wenn du das alles hast musste dein File öffnen, das mach ich mal so:

    // öffnen der Exceldatei um sie zu bearbeiten
    bool CExtendedExcel::Open(bool visible, CString FileName)
    {// bool visible = anzeigen von Excel oder im Hintergrund arbeiten
     // CString Filename = welches File soll geöffnet werden
    	LPCTSTR tmp = _T(FileName);
    	try
    	{
    		// Initialisiere und überprüfen ob initialisiert
    		HRESULT hr = excel.CreateInstance(L"Excel.Application");
    		if(FAILED(hr))//Fehler beim initialisieren
    		{
    			char msg[1024] = {0};
    			sprintf(msg, "E: Fehler beim initialisieren: %d", hr);
    //			throw std::runtime_error(msg); // geht bei mir nicht
    		}
    		if (FileName.IsEmpty()) //Wenn kein FileName dann erstellen wir halt ein File
    			// erstellen des Workbooks
    			workbook = excel->Workbooks->Add(static_cast<long>(Excel::xlWorksheet));
    		else // Wenn ein File angegeben, dann öffnen
    			workbook = excel->Workbooks->Open(tmp);
    		worksheet = excel->ActiveSheet; // holen des aktiven Blattes
    		if (visible) // soll Excel sichtbar sein?
    			excel->Visible = TRUE; // Excel sichtbar
    	}
    	catch(_com_error &ce)
    	{
    		// Handle the error
    		m_sLastError = ce.Description();
    		return FALSE;
    	}
    	return TRUE;
    }
    


  • wenn du sowas findest wäre das schön, wäre ich auch für einen guten Link dankbar. also zu dem AMI Prinzip geht das Fett drucken ähnlich aber nicht gleich nach dem Prinzip findet man auch einiges auf der MSDN Website

    COleVariant
    		covTrue((short)TRUE),
    		covFalse((short)FALSE),
    		covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    
    	//Format A3:A8 as bold, vertical alignment = center.
    	range = objSheet.GetRange(COleVariant("A3"), COleVariant("A8"));
    	font = range.GetFont();
    	font.SetBold(covTrue);
    


  • Hab mal die Pfade angepasst. (verwende Office 97).
    Habe folgende Includes

    #include <odbcinst.h> // glaub dieses Include brauchste gar nicht 
    #include <afxdb.h> 
    #import "C:\Program Files\Microsoft Office\Office\MSO97.DLL"  
    #import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" // dieser include scheint die probleme hervorzurufen. 
    // was muss hier stehen? (für office 97)
    #import "C:\Program Files\Microsoft Office\Office\Excel8.olb"
    

    Problem ist, es kompiliert noch nicht. (errors)

    Fehlt ein include? Oder wo liegt das Problem?

    P.S. ist eine normale MFC-App mit nur den oben erwähnten Includes, sonst nix.

    Der Compiler gibt das aus:

    debug\mso97.tlh(863) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
    debug\vbe6ext.tlh(218) : error C2039: '_CommandBarsPtr' : is not a member of 'Office'
    debug\vbe6ext.tlh(218) : error C2146: syntax error : missing ';' before identifier 'CommandBars'
    debug\vbe6ext.tlh(218) : error C2501: '_CommandBarsPtr' : missing storage
    

    P.S Es gibt noch eine andere Möglichkeit das einzubinden. "Create class from type lib" (über den ClassWizard). So hat es funktioniert, aber eben nur so.

    P.S.2 Die verschiedenen Office versionen (97, 2000,...) haben eine verschiedene Syntax. Stimmt das?



  • die Includes stimmen glaube ich schon so er meckert ja auch nicht an den Includes rum zeig mal ein wenig Source um die CommandBars, denn dascheint was faul zu sein.


Anmelden zum Antworten