Datenbank mit MFC bearbeitet - nichts geht mehr !?!?



  • Na gut, ist zwar etwas komplex, aber ich versuchs mal:
    ➡ Datei Datenbank.h

    class CDatenbank : public CRecordset
    {
    public:
        SaveNewSet (CPartien *);
        CDataenbank(CDatabase* pDatabase = NULL);
        DECLARE_DYNAMIC(CDatenbank)
    
    // Feld-/Parameterdaten
        //{{AFX_FIELD(CPartienSet, CRecordset)
    
        // ... Deklaration der Feldvariablen der Datenbank
        // angelegt vom Klassenassistenten!
    
        //}}AFX_FIELD
    }
    

    ➡ Datei Datenbank.cpp

    // CDatenbank Implementierung
    
    IMPLEMENT_DYNAMIC(CDatenbank, CRecordset)
    
    CDatenbank::CDatenbank(CDatabase* pdb)
        : CRecordset(pdb)
    {
        //{{AFX_FIELD_INIT(CPartienSet)
    
        // ... Initialisierung der Feldvariablen
        // angelegt vom Klassenassistenten!
    
        //}}AFX_FIELD_INIT
    
        m_nDefaultType = snapshot;
        Open(AFX_DB_USE_DEFAULT_TYPE, NULL, skipDeletedRecords);
    }
    
    CDatenbank::SaveNewSet(CDaten *pAktDaten)
    {
        AddNew();
    
        // ... Feldvariablen mit Werten aus struct pAktDaten füllen
    
        Update();
    }
    

    ➡ Datei DatenbankView.h

    class CPartienForm : public CRecordView
    {
    protected: // Nur aus Serialisierung erzeugen
        CPartienForm();
        DECLARE_DYNCREATE(CPartienForm)
    
    public:
        //{{AFX_DATA(CPartienForm)
        // ... Deklaration der Variablen der Steuerelemente, u.a.
        CPartienSet* m_pSet;
        // ...
        //}}AFX_DATA
    
    // Überladungen
        // Vom Klassenassistenten generierte Überladungen virtueller Funktionen
        //{{AFX_VIRTUAL(CPartienForm)
        public:
        virtual BOOL OnMove(UINT nIDMoveCommand);
        // ...
        //}}AFX_VIRTUAL
    
    // Generierte Message-Map-Funktionen
    protected:
        //{{AFX_MSG(CPartienForm)
        afx_msg void OnDatabaseGenerate();
        // ... 
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    };
    

    ➡ Datei DatenbankView.cpp

    void CDatenbankView::OnDatabaseGenerate() 
    {
        CString message( (LPCSTR) AFX_IDS_WRNGENERATE);
        int select = AfxMessageBox (message, MB_OKCANCEL && MB_ICONEXCLAMATION, 0);
        if (select == IDCANCEL)
            return;
        CProgrammDoc* doc = GetDocument();
        doc->GenerateDB();    // Aufruf der Funktion zum Bearbeiten der Datenbank
    }
    

    ➡ Datei CProgrammDoc.h

    class CProgrammDoc : public CDocument
    {
    protected: // Nur aus Serialisierung erzeugen
        CProgrammDoc();
        DECLARE_DYNCREATE(CProgrammDoc)
    
    // Attribute
    public:
        CDatenbank m_tabelleSet;
        // ... (weitere Member)
    
    // Implementierung
    public:
        CGenerateDBDlg m_generateDBView;
        GenerateDB();
        UINT BearbeiteDatenbank( VOID *pParam);
        GeneratePartie();
        // ...
    }
    

    ➡ Datei Datei CProgrammDoc.h

    CProgrammDoc::GenerateDB()
    {
        // als ertsen wird ein Dialogfenster nichtmodal geöffnet
        m_generateDBView.Create(IDD_DBGENERATE, NULL);
    
        // dann wird Datenbank initialisiert und gegebenenfalls
        // alle Datensätze gelöscht
        // ...
        if (!(m_tabelleSet.IsBOF() || m_tabelleSet.IsEOF()))
        {
            if (m_tabelleSet.CanTransact())
                m_tabelleSet.m_pDatabase->BeginTrans();
            m_tabelleSet.MoveFirst();
            while (!m_tabelleSet.IsEOF())
            {
                m_tabelleSet.Delete();
                m_tabelleSet.MoveNext();
            }
            if (m_tabelleSet.CanTransact())
                m_tabelleSet.m_pDatabase->CommitTrans();
        }
    
        // ... Weitere initialisierungen
        BearbeiteDatenbank(&GenParam);
        // Ab hier fangen die Probleme an:
        // (die nachfolgenden Funktionen sind nur zum testen!)
        m_tabelleSet.IsBOF()    // gibt Wert 0 zurück
        m_tabelleSet.IsEOF()    // gibt Wert 0 zurück
        // ... aber
        CRecordSetStatus rStatus;
        m_tabelleSet.GetStatus(rStatus);
        // liefert rStatus.m_lCurrentRecord = -1 (!?!?)
    }
    
    UINT CProgrammDoc::BearbeiteDatenbank(VOID *pParam)
    {
        // Diese Funktion führt Berechnungen aus, die dann zum Speichern in der Datenbank 
        // an eine weitere Funktion übergeben werden.
        // Die Ergebnisse der Berechnungen werden im Dialogfenster ausgegeben
        // ...
        m_generateDBView.UpdateData(FALSE);
        m_generateDBView.UpdateWindow();
        // ...
        // Bei der Berechnung ruft sich die Funktion rekursiv selber auf ...
        DatenbankBearbeiten(pParamNew);
        // ...
        GeneratePartie();    // Übergabe zum Speichern in Datenbank
    }
    
    CProgrammDoc::GeneratePartie()
    {
        // Übertragen der Daten in Datensatz-Variablen,
        // Verknüpfung mit anderen Tabellen
        // ...
        // und Tabelle speichern
        if (m_tabelleSet.CanTransact())
            m_tabelleSet.m_pDatabase->BeginTrans();
    
        m_tabelleSet.SaveNewSet(&m_partien);		// Tabelle in DB speichern
    
        if (m_tabelleSet.CanTransact())
            m_tabelle.m_pDatabase->CommitTrans();
    

    Bis hin zur Bearbeitung und speicherung der Datensätz funktioniert alles prima.
    Nach dem Funktionsaufruf von DatenbankBearbeiten() steht der Cursor in der Tabelle auf -1 (wenn ich das richtig interpretiere)
    Wenn ich die Anwendung komplett schließe und dann wieder starte sind alle vorher erstellten Datensätze vorhanden ud lassen sich anzeigen.

    Ich hoffe, das hilft jetzt weiter 😉

    Gruß WinCoder;



  • Hat wirklich keiner 'ne Idee?!?
    Hab' schon alles mögliche probiert und komm nicht weiter! 😞



  • WinCoder schrieb:

    Hat wirklich keiner 'ne Idee?!?

    estartu_de schrieb:

    Requery?



  • estartu_de schrieb:

    Requery?

    Ja, Hab ich auch schon probiert, Hilft aber nichts!
    Das Ergebnis ist immer noch das gleiche! 😞

    Gruß WinCoder



  • An welcher Stelle hast du es versucht?

    Und auf meine zweite Frage von oben hätte ich auch gerne eine Antwort:
    Was passiert, wenn du die Anwenung zu machst und wieder auf?
    🙂



  • estartu_de schrieb:

    Was passiert, wenn du die Anwenung zu machst und wieder auf?

    WinCoder schrieb:

    Wenn ich die Anwendung komplett schließe und dann wieder starte sind alle vorher erstellten Datensätze vorhanden ud lassen sich anzeigen.

    😃



  • Ohne den ganzen Quelltext durchgelesen zu haben usw. vermute ich übrigens mal, dass das CRecordView-Fenster einen Refresh braucht bzw. die angezeigten Daten sind ja nach der Bearbeitung veraltet und die neuen müssten mal in das Fenster geholt werden...



  • Ups! 🙄 *brillesuch*

    Okay, dann tippe ich wirklich auf ein fehlendes Requery. So ein Verhalten ist ein schönes Indiz dafür. 🙂



  • Hallo allerseits,

    Ersteinmal vielen Dank.

    estartu_de schrieb:

    An welcher Stelle hast du es versucht?

    Also Requerry habe ich versucht, und zwar an dieser Stelle:
    ➡ Datei CProgrammDoc.cpp

    // ... Weitere initialisierungen
        BearbeiteDatenbank(&GenParam);
        // Ab hier fangen die Probleme an:
        // (die nachfolgenden Funktionen sind nur zum testen!)
    
        m_tabelleSet.Requery();
    
        m_tabelleSet.IsBOF()    // gibt Wert 0 zurück
        m_tabelleSet.IsEOF()    // gibt Wert 0 zurück
        // ... aber
        m_tabelleSet.MoveFirst()    // .. oder ähnlicher Movebefehl führen zu Exception!
    

    estartu_de schrieb:

    Und auf meine zweite Frage von oben hätte ich auch gerne eine Antwort:
    Was passiert, wenn du die Anwenung zu machst und wieder auf?
    🙂

    Wenn ich die Anwendung schließe und dann neu starte, sind alle zuvor erstellten Datensätze vorhanden und ich kann darauf zugreifen.

    Kann es vielleicht daran liegen, daß im Programm immer nur Datensätze hinzugefügt werden.
    Habe auch schon versucht, die Tabelle mal als snapshot und mal als dynaset zu öffnen. Ändert aber nichts am Ergebnis.

    Gruß WinCoder



  • Ist eine Wrapper vonmir. Header sollte selbsterklärend sein.
    Hier kannst du auf einfachste weise SQL-Query an die DB senden.
    Ist aufgebaut wie meine MySQL-Wrapper nur eben für ODBC. Die Connect-Methode ist etwas abders aber sonst fast gleich.



  • Unix-Tom schrieb:

    www.sensorme.de/dateien/odbc.zip

    Ist eine Wrapper vonmir. Header sollte selbsterklärend sein.
    Hier kannst du auf einfachste weise SQL-Query an die DB senden.
    Ist aufgebaut wie meine MySQL-Wrapper nur eben für ODBC. Die Connect-Methode ist etwas abders aber sonst fast gleich.

    Vielen Dank, werd' ich mir gleich mal anschauen.

    Habe durch viel 'rumprobieren (erstmal) eine Lösung gefunden. 🙂
    Hatte in der Klasse einen Parameter zum Filtern angelegt. Den habe ich jetzt rausgenommen und plötzlich geht's! 😮
    Weiß zwar nicht so richtig, warum bzw was ich da falsch gemacht habe, aber es geht erstmal! 🤡

    Also nochmal Dank an alle!

    Gruß WinCoder


Anmelden zum Antworten