zugriff auf erstellte datei



  • Hallo,

    ich habe mal eine kleine Anwendung erstellt, die über die OLE-Schnittstelle mit später Bindung Daten aus einer Excel-Datei liest und diese dann in einem StringGrid darstellt, ohne dass man dazu eine temporäre Datei erstellen muss.

    Hier mein Code:

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #include <ComObj.hpp> 
    #include <utilcls.h>
    #pragma hdrstop
    //---------------------------------------------------------------------------
    #include "HauptFormular.h"
    #include "StringParser.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    //---------------------------------------------------------------------------
    TExcel2GridFormular *Excel2GridFormular;
    //---------------------------------------------------------------------------
    __fastcall TExcel2GridFormular::TExcel2GridFormular(TComponent* Owner)
            : TForm(Owner)
    {
    }
    
    //---------------------------------------------------------------------------
    // Methode ExcelToStringList
    //---------------------------------------------------------------------------
    bool __fastcall TExcel2GridFormular::ExcelToStringList(TStrings *WerteListe,
                                                           int &AnzahlZeilen,
                                                           int &AnzahlSpalten)
    {
      // Variablendeklaration
      Variant Excel;
    
      // versuche Excel zu öffnen,
      // falls schon offen -> OK
      // falls geschlossen -> erzeuge neue Instanz
      try
      {
        // Excel ist bereits geöffnet
        Excel = GetActiveOleObject("Excel.Application");
      }
      catch(...)
      {
        // Excel ist noch nicht geöffnet
        Excel = CreateOleObject("Excel.Application");
      }
    
      // deaktiviere interne Meldungen von Excel
      Excel.OlePropertySet("DisplayAlerts", false);
    
      try
      {
        // Variablendeklaration
        Variant WorkBooks,
                ActiveWorkBook,
                WorkSheets,
                ExcelSheet,
                UsedRange,
                Columns,
                Rows,
                Range;
        AnsiString AktuellerInhalt = "";
    
        // ermittle alle Workbooks
        WorkBooks = Excel.OlePropertyGet("WorkBooks");
        // lade Workbook (Beispieldatei)
        WorkBooks.OleFunction("Open", "c:\\temp\\FDE_Abfrage.xls");
    
        // ermittle das aktuelle Workbook
        ActiveWorkBook = Excel.OlePropertyGet("ActiveWorkbook");
        // ermittle alle Worksheets
        WorkSheets = Excel.OlePropertyGet("Worksheets");
    
        // ermittle das aktuelle Worksheet und aktiviere es
        ExcelSheet = WorkSheets.OlePropertyGet("Item", 1);
        ExcelSheet.OleFunction("Activate");
    
        // bestimme den Bereich der benutzen Felder
        UsedRange = ExcelSheet.OlePropertyGet("UsedRange");
        // bestimme die Spalten des benutzten Bereichs
        Columns = UsedRange.OlePropertyGet("Columns");
        // bestimme die Zeilen des benutzen Bereichs
        Rows = UsedRange.OlePropertyGet("Rows");
        // ermittle die Anzahl der vorhandenen Spalten
        AnzahlSpalten = Columns.OlePropertyGet("Count");
        // ermittle die Anzahl der vorhandenen Zeilen
        AnzahlZeilen = Rows.OlePropertyGet("Count");
    
        // ermittle Einträge pro Zeile
        for(int i=1; i<=AnzahlZeilen; i++)
        {
          // ermittle Einträge pro Spalte
          for(int j=1; j<=AnzahlSpalten; j++)
          {
            // ermittle die aktuelle Zelle
            Range = ExcelSheet.OlePropertyGet("Cells", i, j);
    
            // wenn letzte Spalte in Zeile ausgewählt ist
            if(j == AnzahlSpalten)
            {
              // schreibe Wert von Zelle in String
              AktuellerInhalt += AnsiString(Range.OlePropertyGet("Value"));
            }
            // es ist nicht die letzte Spalte in Zeile ausgewählt
            else
            {
              // schreibe Wert von Zelle mit anschliessendem Semikolon in String
              AktuellerInhalt += AnsiString(Range.OlePropertyGet("Value")) + ";";
            }
          }
          // schreibe komplette Zeile in Stringliste
          WerteListe->Add(AktuellerInhalt);
          // leere den Inhalt des Strings wieder
          AktuellerInhalt = "";
        }
      }
      // Fehlerbehandlung
      catch(...)
      {
        // schliesse Excel-Datei
        Excel.OleFunction("Quit");
        Excel = Unassigned;
    
        // gib FALSE zurück -> Ermitteln der Daten war nicht erfolgreich
        return false;
      }
    
      // aktiviere interne Meldungen von Excel
      Excel.OlePropertySet("DisplayAlerts", true);
    
      // schliesse Excel-Datei
      Excel.OleFunction("Quit");
      Excel = Unassigned;
    
      // gib TRUE zurück -> Ermitteln der Daten war erfolgreich
      return true;
    }
    
    //---------------------------------------------------------------------------
    // Methode Button1Click()
    //---------------------------------------------------------------------------
    void __fastcall TExcel2GridFormular::Button1Click(TObject *Sender)
    {
      // schreibe Daten aus Stringliste in StringGrid
      StringListToStringGrid();
    }
    
    //---------------------------------------------------------------------------
    // Methode StringListToStringGrid()
    //---------------------------------------------------------------------------
    void __fastcall TExcel2GridFormular::StringListToStringGrid()
    {
      // Variablendeklaration
      TStringList *Liste = new TStringList;
      int Zeilen = 0;
      int Spalten = 0;
      int AktuelleSpalte = 0;
    
      // wenn Ermitteln der Daten aus Excel erfolgreich
      if(ExcelToStringList(Liste, Zeilen, Spalten))
      {
        // lege Anzahl der Zeilen fest
        StringGrid1->RowCount = Zeilen;
        // lege Anzahl der Spalen fest
        StringGrid1->ColCount = Spalten;
    
        // ermittle die Einträge aus der Liste mit den
        // Werten aus der Exceldatei
        for(int i=0; i<Liste->Count; i++)
        {
          //Variablendeklaration
          // ermittle den aktuellen Eintrag der Liste (=aktuelle Zeile)
          AnsiString AktuellerEintrag = Liste->Strings[i];
          // erzeuge neues StringParser-Objekt
          // (ist eigene Klasse zum Zerlegen und Prüfen von Strings)
          StringParser *Parser = new StringParser(AktuellerEintrag, ';');
    
          // solange noch Tokens vorhanden sind
          while(Parser->HasMoreTokens())
          {
            // schreibe aktuelles Token in entsprechende Zelle von StringGrid
            StringGrid1->Cells[AktuelleSpalte][i] = Parser->NextToken();
            // erhöhe die aktuelle Spalte um eins
            AktuelleSpalte++;
          }
          // setze die aktuelle Spalte wieder zurück
          // (jetzt wird neue Zeile wieder ausgewertet)
          AktuelleSpalte = 0;
    
          // lösche das StringParser-Objekt
          delete Parser;
          Parser = NULL;
        }
      }
    
      // lösche das StringList-Objekt
      delete Liste;
      Liste = NULL;
    }
    


  • // lösche das StringParser-Objekt
          delete Parser;
          Parser = NULL;
    

    omfg also allein ein Objekt Parser zu nennen ist schon schlechter Stil .. aber wenn man es dann aus dem Speicher löscht ihm dann noch etwas zuzuweisen auch wenn man nix zuweist ist unterste schublade der Programmier Künste @ JeGr



  • Original erstellt von 1ntrud0r:
    aber wenn man es dann aus dem Speicher löscht ihm dann noch etwas zuzuweisen auch wenn man nix zuweist ist unterste schublade der Programmier Künste

    ...alleine schon dieser Satz disqualifiziert dich...

    Du solltest nochmals lesen - denken - und wirst dich dann über die Dummheit deiner Aussage aufregen.

    @JeGr
    Schöner Code... schön formatiert, sauber kommentiert. Wenn auch fast etwas zu ausführlich. Vielleicht solltest du dich darauf beschränken - Funktion zusammenhängende Blöcke als Ganzes zu dokumentieren - So kann man dann im Zusammenhang mit der Absicht und den Funktionsnamen selbst rekonstruieren was es genau werden sollte.

    -junix

    <edit>Gottverdammte Ortographie... Das hat man davon, wenn man die Fehler nur mit halbem kopf korrigiert (: Da wird aus "Schöne Code" statt "Schöner Code" einfach mal "Schöne Coder" *lol*</edit>

    [ Dieser Beitrag wurde am 14.02.2003 um 14:53 Uhr von junix editiert. ]



  • Original erstellt von 1ntrud0r:
    **
    omfg also allein ein Objekt Parser zu nennen ist schon schlechter Stil .. aber wenn man es dann aus dem Speicher löscht ihm dann noch etwas zuzuweisen auch wenn man nix zuweist ist unterste schublade der Programmier Künste @ JeGr**

    Was hast du denn eigentlich für ein Problem?! 😕

    Wie ich meine Objekte benenne ist doch letztlich meine Sache. Ich weiss auf jeden Fall, was damit gemeint ist.

    Und was ist daran "unterste Schublade der Programmierkünste", wenn man nach dem Löschen eines Objektes den NULL-Pointer zuweist ??
    Ist doch um einiges besser, als wenn man den Zeiger irgendwo ins Nirvana zeigen lässt und irgend ein anderes Objekt nachher zufällig auch auf diesen Bereich zeigt. Dann kann's aber böse krachen.
    Somit weise ich dem gelöschten Objekt den NULL-Pointer zu und weiss damit genau, wo er hinzeigt.
    Dies ist meiner Ansicht nach wesentlich sicherer!



  • @junix: thx 😃

    Das mit den (ausführlichen) Kommentaren habe ich mir halt zwischenzeitlich so angewöhnt. Ich komme damit halt besser klar.

    (Lieber etwas zu viel Kommentar als zu wenig...)



  • Original erstellt von JeGr:
    wenn man nach dem Löschen eines Objektes den NULL-Pointer zuweist ??

    Das ist jetzt allerdings unterste Schublade der Artikulations-Kunst (-; Du weist dem Objekt gar nix zu (Es ist ja längst tot), sondern dem Zeiger auf das Objekt weist du NULL zu. Und das ist absolut richtig. So kann nämlich - mit etwas disziplin - jederzeit ein Zeiger auf NULL geprüft werden und man kann sicher sein, dass das Objekt dahinter gültig sein wird. Macht man das nicht hat man nach wie vor einen Zeiger auf den Bereich in dem einst ein Objekt lag. Das funktioniert genau solange wie das OS den Speicher nicht anderweitig vermietet...

    Das NULL-Setzen des Zeigers zu kritisieren oder gar als schlechten Stil zu bezeichnen disqualifizert den der diese Kritik anbringt mal grundstäzlich für Aussagen rund um Stilistik. Denn im Gegenteil es ist sogar sehr guter Stil.

    Was die Namensgebung anbelangt so ist dies hier nicht weiter gravierend da nur ein Parser verwendet wird. Würden hier mehrere Parser zum Zuge kommen und diese mit parser(1)-parser(n) benamst, sähe die ganze Sache schon etwas anders aus.

    -junix



  • Original erstellt von junix:
    ...alleine schon dieser Satz disqualifiziert dich...
    Du solltest nochmals lesen - denken - und wirst dich dann über die Dummheit deiner Aussage aufregen.
    [ Dieser Beitrag wurde am 14.02.2003 um 14:53 Uhr von [qb]junix
    editiert. ][/QB]

    du solltest lieber deine mod stelle aufgeben lieber ... junix ^^ mit solch kommentaren wie du schon öfters von dir gegeben hast ?! Diphamierend und ignorant mehr bist du nicht ! In deiner kranken Welt scheint es nur deinen Werten nach zu gehen !

    guter stil ist :

    assert(p_mMyObject);
    delete p_mMyObject;



  • Original erstellt von JeGr:
    system(KopierString.c_str());

    Das ist nicht dein Ernst, oder?



  • Original erstellt von Jansen:
    [quote]Original erstellt von JeGr:
    [qb]system(KopierString.c_str());

    Das ist nicht dein Ernst, oder?[/QB][/QUOTE]

    muhahah das hab ich ja noch gar net gesehen oh 😉 movefile() scheint ihm nen bissl nen fremdwort zu sein 🙂 genau wie mein spatzi junix 0 plan von memory leaks hat 🙂

    [ Dieser Beitrag wurde am 14.02.2003 um 16:27 Uhr von 1ntrud0r editiert. ]



  • Original erstellt von 1ntrud0r:
    **[...allgemeines ärgerablassen...]
    guter stil ist :

    assert(p_mMyObject);
    delete p_mMyObject;**

    mmmhm... und du weisst, auch was assert() genau macht und wann assert() ganz bestimmt NICHT hilft? Finde es trotzdem sehr freundlich dass du gleich noch ein Beispiel lieferst wieso du dich disqualifizert hast...

    Bevor du weiter deinen Ärger auf mich projezierst und dich lächerlich machst, würde ich dir empfehlen nochmals die Dokumentation zu assert() genau anzuschauen...

    -junix



  • Original erstellt von 1ntrud0r:
    [...blub...]genau wie mein spatzi junix 0 plan von memory leaks hat 🙂

    So, du krasser "Häkkr" (sweet wie immer)... hab ich ned, ja? *rotfl* na dann wirds wohl so sein. Ich kommentier das nicht weiter... aber erklär mir mal wo genau die Memory-Leaks hier zustandekommen sollen?

    -junix



  • Original erstellt von Jansen:
    [quote]Original erstellt von JeGr:
    [qb]system(KopierString.c_str());

    Das ist nicht dein Ernst, oder?[/QB][/QUOTE]
    wieso nicht?
    funktioniert doch...



  • goto funktioniert auch, trotzdem verwendet es kein Programmierer, der auch nur einen Funken von Ehre im Leib hat. 😉



  • Hi,
    irgendwo in der Hilfe des BCB steht übrigens, dass man gelöschten Zeigern NULL zuweisen soll um Fehler bei einer erneuten Löschung vorzubeugen!

    Alexander Sulfrian



  • Sehr richtig, Alexander... und auch nur wenn du null zuweist wird assert() vor einer weitern Löschung ansprechen und ich glaube das ist unserm "Einbrecher" (intrudor) auch plötzlich aufgefallen... (-;

    -junix


Anmelden zum Antworten