TDBComboBox per ADO dynamisch füllen



  • Hallo

    Ich fülle per ADO aus einer Access-Datenbank eine TDBComboBox (ist im Formular
    vorhanden) über einen Button-Event. Dies erzeugt jedoch eine EAccessViolation bei dem Ausdruck cmbA->DataSource = dsMonate;
    Habe schon alles versucht... Mit dem Wizzard von C++Builder6 klappt es, aber ich benötige es dynamisch, da ich die Combobox immer unterschiedlich befülle (je nach Kategorie). Der Code steht in der Main.cpp nicht im Header-File.

    Code:

    TADOQuery *ADOQuery;
    TDataSource *dsMonate;

    void __fastcall TMainForm::cmdCalClick(TObject *Sender)
    {

    // Verbindung zur DB
    AnsiString connStr;
    connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F:\\timeorg.mdb";
    ADOQuery->ConnectionString = connStr;
    ADOQuery->SQL->Add("SELECT DISTINCT monat FROM projektdaten");
    ADOQuery->Active = true;
    ADOQuery->Open();

    // Combo anbinden
    TDBComboBox *cmbA; // Combo nochmals deklariert für Main Form
    dsMonate->DataSet = ADOQuery;
    cmbA->DataSource = dsMonate; // hier ist der Fehler
    cmbA->DataField = "monat";

    }

    Eine weitere Frage:
    Im Header File werden alle GUI Komponenten (Labels, Textboxen, Buttons) deklariert.
    Sofern man jedoch in der .cpp Datei darauf zugreifen will, muß man sie dort neu
    deklarieren. Warum ? Der Header-File wird doch dort included. Hängt das mit dem Compiler zusammen?

    Danke für alle Antworten

    Gruß



  • Man muß diese GUI-Komponenten nicht neu deklarieren. Da machst du irgendwas falsch. Laß diese Deklarationen dort wieder weg. Da muß ja eine Access-Violation kommen.
    Welche Fehlermeldung hattest du vorher?



  • Die TADOQuery und TDataSource sind nicht auf der MainForm, also erzeuge ich sie hier.

    Auf der MainForm sind mehrere TDBComboBoxen.
    Wenn ich Sie nicht neu deklariere mit "TDBComboBox *cmbA;"
    bekomme ich die Fehlermeldung:
    [C++ Fehler] Tmcpp.cpp(257): E2451 Undefiniertes Symbol 'cmbA'

    Wenn ich sie deklariere, kommt als Warnung:
    [C++ Warnung] Tmcpp.cpp(257): W8013 Wahrscheinliche Verwendung von 'cmbA' vor Definition
    und bei Programmausführung als Exception:
    Eaccesviolation an Adresse ... mit Zugriffsverletzung.

    Ich wundere mich ja selbst darüber, denn im Header sind ja alle auf der MainForm plazierten Komponenten schon definiert, und der wird ja schließlich included.

    Da ich neu in C++ bin, bin ich von C++ sehr erstaunt alles nochmals deklarieren zu müssen, und kann es eigentlich nicht glauben.



  • schau mal bitte in die FAQ unter Forms -> "Variablenübergabe an andere Form"
    das geht ebenso mit Komponenten



  • javad schrieb:

    Da ich neu in C++ bin, bin ich von C++ sehr erstaunt alles nochmals deklarieren zu müssen, und kann es eigentlich nicht glauben.

    Ich hatte es zwar vorher schon gesagt, aber ich machs lieber nochmal. Du mußt/darfst die im Header einer Form deklarierten Variablen nicht neu deklarieren. Damit erzeugst du neue, uninitialiserte, lokale Variablen. Bitte lies dir ein C++-Tutorial zum Thema Variablen und Pointer durch.



  • Erstmal Danke für die Antwort.

    Genau so sehe ich es auch, dazu wird der Header ja included.

    Es geht eigentlich nicht um ADO, sondern darum.

    Ich habe einen Button-Event. Wenn ich darin eine Combobox ändere, geht es.
    Wenn ich im Event eine weitere Funktion aufrufe, die die Combobox ändern soll,
    geht es nicht.

    // Deklaration der Funktion
    void setComboA();

    //Button-Event
    void __fastcall TMainForm::cmdCalClick(TObject *Sender)
    {
    // DBComboBox leeren
    cmbA->Clear();

    // Aufruf Funktion
    setComboA();
    }

    void setComboA() {
    // weitere Anweisungen für ComboBoxA
    cmbA->Visible = true;
    // hier kommt als Fehler: E2451 Undefiniertes Symbol 'cmbA'
    }

    Gruß



  • setComboA ist keine Memberfunktion von TMainForm und kann somit auch nicht auf deren Member zugreifen. Entweder du machst setComboA zur Memberfunktion oder du übergibst ihr noch einen Pointer auf die Mainform.

    void setComboA(TMainForm* form) {
    // weitere Anweisungen für ComboBoxA
      form->cmbA->Visible = true;
    // hier kommt als Fehler: E2451 Undefiniertes Symbol 'cmbA' - jetzt nicht mehr
    }
    


  • YEP!

    Es geht so:

    //Deklar. Funktion
    void setComboA(TMainForm* MainForm);

    //Aufruf:
    setComboA(MainForm);

    void setComboA(TMainForm* MainForm) {
    MainForm->cmbA->Clear();
    }

    oder so:

    //Deklar. Funktion
    void setComboA();

    Aufruf:
    setComboA();

    void setComboA() {
    MainForm->cmbA->Clear();
    }

    Ich habe keine Ahnung, was der Unterschied ist 😉
    Werde mir jetzt ansehen, was Member-Variablen sind, und wieso
    C++ das bei einer TForm braucht. In Java oder VB.Net ist der Zugriff
    auf Komponenten ohne Ableitung über den Container möglich.

    Endlich klappts, und ich kann einen Großteil des GUI erstellen.

    Vielen, vielen Dank für deine raschen Antworten.
    Ich sitze schon einige Tage daran. War wohl die Hitze 😃



  • Ich kenn zwar Java jetzt nicht, kann mir aber kaum vorstellen, dass man dort auf Klassenmember ohne Klassen instanz zugreifen kann (es sei denn sie sind statisch).
    Dir fehlen anscheinend noch die OOP-Grundlagen.
    http://tutorial.schornboeck.net/oop2.htm
    Außerdem wurden hier keine Container abgeleitet. Oder sind Container in Java sowas wie hier Instanzen?



  • In Java oder VB.Net ist es nur nötig vor einer
    GUI Komponente die Form anzugeben, wie bei
    MainForm->cmbA->Clear(), wenn eine Klasseninstanz
    in einer andereren Klasse erzeugt wurde.

    Sonst genügt: cmbA.setVisible(true);

    Unter Container verstehe ich hier die MainForm als Owner der ComboBox.
    Es wird kein Container abgeleitet, sondern von einem Container...
    Das Ding, wo Die Combo draufsitzt ...

    Im Sinne der OOP verwende ich eine neue Funktion ... denk mal nach über die Punkte Wiederverwendbarkeit, Geheimnisprinzip und Kapselung von Funktionen (in Java übrigens Methoden genannt)



  • Hallo

    Das istin C++ alles genauso. Das wirst du schon merken, wenn du ein Tutorial zum Thema OOP in C++ durchgenommen hast.

    bis bald
    akari



  • Ja Danke...
    mich nervt nur unwahrscheinlich, das ich einen Ausdruck wie:

    void __fastcall TMainForm::cmdClientsClick(TObject *Sender)

    überhaupt nicht kapiere.

    _fastcall mit einem Unterstrich oder 2 ???
    2 Doppelpunkte ????

    Dieser Synthax ist mir aus anderen Sprachen nicht bekannt.

    Den Zuweisungsoperator "->" gibts sonst auch nirgends 😃

    Und Zeiger / Pointer kenne ich bisher auch nicht.
    Muß man sich halt draufschaffen.

    Aber dafür, daß ich in einer Woche eine Datenbankanwendung zum Laufen gebracht habe, läuft es ganz gut.

    Bin schon gespannt, was kommt wenn Combos ins Grid sollen etc ...

    Viele Grüße



  • Hallo

    Es stimmt schon das C++ umständlicher als java erscheint, wenn man Java gewöhnt ist. Nichtsdestrotrotz ist des Objektmodell fast dasselbe. Die Syntax und die Grundlagen solltest du aber unbedingt verstehen, wenn du mit der VCL solche Sachenn machen willst.

    _fastcall mit einem Unterstrich oder 2 ???

    __fastcall ist ein VCL-spezifisches Schlüsselwort. Und wird dort immer mit zwei Unterstrichen geschrieben. Es ist für Optimierungszwecke bei den Methdoenaufrufen da.

    2 Doppelpunkte ????

    Die bezeichnen das die folgende Methode eine Implementaion der vorher genannten Klasse ist.

    Den Zuweisungsoperator "->" gibts sonst auch nirgends 😃

    a->b ist äquivalent zu
    *(a).b. Das heißt a ist ein Pointer auf eine Klasseninstanz, deren Element b aufgerufen werden soll.

    Und Zeiger / Pointer kenne ich bisher auch nicht.

    Das solltest du aber unbedingt beherschen, denn grad in der VCL wirst du viel mit Pointern arbeiten.

    bis bald
    akari



  • Wer nicht fragt, bleibt dumm 😕

    Vielen, vielen Dank Dir 🙂 👍


Anmelden zum Antworten