Datenbank filter



  • Hallo...

    Ich habe ein kleines Problem mit einer Datenbank.
    So... ich habe zwei Tabellen (Adressen und Zeit).
    Die Tabellen sind mit Access so verknüpft, dass alle Datensätze aus Zeit die zu dieser Adresse gehören angezeigt werden. In Access funzt das super.
    Adressen möchte ich in Feldern ausgeben und alle Datensätze aus Zeit die zu dieser Adresse gehören sollen in einem Listenelement ausgeben werden.
    Wenn ich dann zur nächsten Adresse springe sollen auch da die Zeiten ausgegeben werden die zu dieser Adresse gehören.

    Wie bekomme ich das hin? ¿ ?

    mfg uwe



  • Hi @ all

    Das würde mich auch mal interessieren, wie ich zwei Tabellen ansprechen kann.

    Vielleicht könnte noch jemand kurz erklären, wie man ohne den MFC Assi ne DB ansprechen und Datensätze ändern kann. Steht soviel ich weiß in der FAQ auch nicht drin !

    Gruß



  • benutze CDaoDatabase und CDaoRecordset



  • Sorry, habs vergessen zu erwähnen, muss über ODBC laufen,

    Mit den beiden Klassen kann ich auch nicht viel anfangen.



  • hallo...ich brauche auch ODBC

    uwe



  • Hi,
    man kann die ODBC Verbindung entweder beim anlegen eines neuen Progs einrichten, wenn man im Projektassistenten eine Datenbankanwendung anlegt oder das auch später im Projekt machen.
    Dafuer leitet man eine Klasse von "CRecordSet" ab und kann hier dann in einer Abfrage die Datenbank und die Tabelle(n) auswaehlen. In der neuen Klasse tauchen dann deine DB-Spalten als Membervariablen auf und in der Klasse, aus der du auf die Inhalte zugreifen willst, legst du dir einen Zeiger auf deine neue Datenbankklasse an. Jetzt kannst du ueber m_pDeinZeiger->m_DeineSpalte auf deine DB Inhalte zugreifen.
    Hier hast du jetzt auch die Möglichkeit, einen Filter zu setzen. Geht über
    m_pDeinZeiger->m_strFilter("WHERE adresse.id = zeit.de" (ein INNERJOIN funzt hier afaik nicht). Dieser Filter muss aber vor m_pDeinZeiger->open() stehen.
    Man hat auch die Moeglichkeit, in der Methode CRecordSet::GetDefaultSQL() schon zu filtern. Standardmaessig ist da ein Select * implementiert, dass eben ueber m_strFilter() eingeschraenkt werden kann.

    Ich hoffe, das stimmt so alles

    Gruesse
    items



  • halloele....

    mit dem einbinden der datenbank habe ich keine probleme...

    mir würde mehr die filterrung helfen.
    wie ich das filtern kann...

    Das erste Feld ist " m_ID" aus Adressen Typ int,
    das zweite Feld ist " m_ID2" aus Zeit Typ int.
    so sind die Tabellen auch in Access verknüpft.

    so wollte ich das auch in meinem Programm machen.

    mfg uwe



  • Hi,
    In Adressen hast du als Primaerschluessel das Feld ID und in Zeit das Feld adressen_id (das den Primaerschluessel von adressen aufnimmt). Umgekehrt hast du in Zeit das Feld ID2 und in Adressen das Feld zeit_id (das wiederum den Primaerschluessel von Zeit aufnimmt).
    Dann kannst du das auf zwei Arten verknuepfen:

    1. m_pDeinZeiger->m_strFilter = "WHERE adressen.id = zeit.adressen_id"
    2. m_pDeinZeiger->m_strFilter = "WHERE zeit.id = adressen.zeit_id"

    Je nachdem was du schreibst, wird CRecordSet::GetDefaultSQL() ergaenzt um den entsprechenden Filter, d.h. dein Select * Statement wird um diesen Filter modifiziert und nur die Datensaetze, auf die dieser Filter zutrifft, werden zurueckgegeben.

    Falls du das nicht so verknuepfst, bekommst du ein sogenanntes "Karthesisches Produkt" (hoffe, das ist so richtig geschrieben 🤡. Das heisst, jede Spalte der Tabelle Zeit ist mit jeder Spalte der Tabelle Adressen verknuepft. Deshalb musst du den Filter auf jeden Fall an irgendeiner Stelle setzen. Und das machst du eben vor dem Open. Dann greifst du ganz normal auf die Membervariablen der Ableitung von CRecordSet zu.

    Sollte so funzen. Ansonsten beschreib mal was nicht klappt, wenn du es so machst.
    Gruesse
    Ralf



  • hallo...

    Hier mein code und die fehlermeldung

    UpdateData();
    
        // Mein Filter: 
        // Zwei Tabellen
        // 1. Tabelle Adressen  = m_ID
        // 2. Tabelle Zeiterfassung m_DatenSatzID2
        //  Wenn ich auf Datensatz 2 aus Adressen bin sollen alle Datensätze 
        //  aus Zeiterfassung in das Listenelement übernommen werden.
    
            // Diese Fehlermeldung bekomme ich!
            // Syntaxfehler (fehlender Operator in Abfrage Ausdruck
    
        m_pSet->m_strFilter = "WHERE adressen.m_id = zeiterfassung.DatenSatzID2";
    
        // Recordset aktualisieren ( Suchregel wird angewendet )
        m_pSet->Requery();
        // Alte Items der CListCtrl löschen
        m_list.DeleteAllItems();
        // Solange Elemente vorhanden
    
        while (!m_pSet->IsEOF() )
        {
            // in CListCtrl einfügen
            int item = m_list.InsertItem(0,m_pSet->m_strFilter);
            m_list.SetItemText(item,1,m_pSet->m_ZeitEin);
            m_list.SetItemText(item,2,m_pSet->m_ZeitAus);
            m_list.SetItemText(item,3,m_pSet->m_MinusZeit);
            m_list.SetItemText(item,4,m_pSet->m_PlusZeit);
            // Aktellen Datensatz um eins weitersetzen
        m_pSet->MoveNext();
        }
    
    mfg uwe
    


  • Hi,
    Zwei Probleme gibt es da:
    1. Der Filter String:
    Der muss natuerlich ohne "WHERE" verschickt werden (Sorry). Also so:

    m_pSet->m_strFilter = "adressen.m_id = zeiterfassung.DatenSatzID2";

    Da m_strFilter da "WHERE" bereits Bestandteil von m_strFIlter() ist.

    2. Der String an sich:
    m_strFilter muss, wie ich schrieb, vor dem "m_pSet->open();" abgeschickt werden. Wenn du aber im Anwendungs Assistenten von CRecordView ableitest, dann ist an der Stelle der Connect zur DB ja schon offen. Das heisst, mit m_strFilter wird man an dieser Stelle nicht mehr froh. In diesem Fall koenntest du eine weitere Klasse von CRecordSet ableiten und dann einen Zeiger auf diese Klasse initialisieren. Das heisst, im geoeffneten Connect einen zweiten oeffnen und hier mit m_strFilter arbeiten. Eine andere Moeglichkeit waere, in CRecordSet::GetDefaultSQL() zu arbeiten. Da steht sowas wie "_T("[adressen][zeit]");", was nichts anderes bedeutet als "_T("SELECT * from adressen,zeit");".
    Das heisst, du kannst hier das Statement erweitern auf "_T("SELECT * from adressen,zeit WHERE [adressen].id = [zeit].adressen_id");" Damit passt du bereits das Standard-Statement an und kannst dir dann den Wiggel mit m_strFilter sparen. Du musst dann allerdings _T("[adressen][zeit]"); auskommentieren.

    Gruss
    items



  • Hallo !

    Du könntest das ganze auch in Access mit einer Abfrage machen, indem Du die
    Tabelle mit den Adressen und den Zeiten verknüpfst. Damit erhält man eine
    dritte Tabelle in denen die daten deiner Abfrage Sind. Nun Könntest Du
    in VC++ diese Tabelle mit einen CDaoRecordSet einbinden, und Du müßtest dich
    nicht mehr darum kümmern die daten auszuwerten, da diese Aufgabe nun die
    Datenbank für dich übernimmt.

    Viele Grüße
    Michael



  • hallo....

    Danke für die super hilfe.

    Ich werde gleich mal probieren....

    mfg uwe



  • lese dir mal das durch dort wird es gezeigt wie
    es gemacht wird

    http://members.aon.at/murli2001/db5/db5.html

    Vossy



  • halloele...

    den link kenne ich schon aus der FAQ aber dank.

    das ist auch nicht das was ich brauche.
    mit dem Verknüpfen funzt jetzt.

    aber leider bekomme ich immer nur einen Datensatz aus Zeit angezeigt.
    Zu jeder Adresse sind aber viele Datensätze in Zeit gespeichert die ich in einer Liste ausgeben will und wenn ich bei adressen einen Datensatz weiter gehe z.b. von datensatz 1 zu zwei dann sollen auch da alle datensätze aus zeit angezeigt werden.

    wat nun?
    😕 mfg uwe



  • halloele....

    keiner eine lösung...?¿?

    mfg uwe



  • hallo....

    hemm... das problem steht noch!

    kennt einer vielleicht ein Buch MFC und Datenbanken oder so...in der art.

    mfg Uwe



  • Ich kümmere mich morgen drum versprochen
    Mail angekommen
    Vossy



  • Moin,
    kriegst du denn in Access die richtige Ausgabe wenn du eine SQL Abfrage machst,
    die deine beiden Tabellen ueber "adressen.m_id = zeiterfassung.DatenSatzID2" verknuepfst?

    Also sowas wie:
    SELECT * FROM adressen INNER JOIN zeit ON adressen.m_id = zeiterfassung.DatenSatzID2;
    bzw.
    SELECT * FROM adressen, zeit WHERE adressen.m_id = zeit.DatenSatzID2;

    Dann haette man das Problemchen schon mal ein bisschen eingegrenzt auf Access oder VC.

    Gruesse
    items



  • hallo...

    ich habs...Danke fuer die Hilfe

    ich war(bin) einfach zu dumm... 😃

    mfg uwe



  • Oooch,
    jetzt sag wenigstens mal, was es denn nun war 🤡

    Gruesse
    items


Log in to reply