TDBComboBox per ADO dynamisch füllen

javad

Grünschnabel
Hallo

Ich fülle per ADO aus einer Access-Datenbank eine TDBComboBox über einen Button-Event. Dies erzeugt jedoch eine EAccessViolation bei
dem ersten Ausdruck ADOQuery-> ...
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
dsMonate->DataSet = ADOQuery;
cmbA->DataSource = dsMonate;
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ß
 

javad

Grünschnabel
javad hat gesagt.:
Hallo

Ich fülle per ADO aus einer Access-Datenbank eine TDBComboBox über einen Button-Event. Dies erzeugt jedoch eine EAccessViolation bei
dem ersten Ausdruck ADOQuery-> ...
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
dsMonate->DataSet = ADOQuery;

TDBComboBox *cmbA;
cmbA->DataSource = dsMonate; // jetzt ist der Fehler hier
cmbA->DataField = "monat";​
}

Gruß


Ich bin jetzt einen Schritt weiter gekommen durch:
TADOQuery *ADOQuery = new TADOQuery(NULL);
TDataSource *dsMonate = new TDataSource(NULL);
Die Deklaration fehlte für die Query und die DataSource.

Jetzt meckert der Compiler aber beim Füllen der Combobox bei
cmbA->DataSource = dsMonate;

Mit TDBComboBox *cmbA; klappt es nicht und mit
TDBComboBox *cmbA = new TDBComboBox(Null);
auch nicht, da die Combo ja schon auf der Form plaziert wurde.

Was tun ? Das kann doch nicht so schwer sein, eineDBComboBox
dynamisch / ohne Wizzard zu füllen.
 

Turri

Erfahrenes Mitglied
Hallo,

Wo genau liegt jetzt das Problem?
Wenn Sie schon auf dem Form ist(dann hast dir die aus der Komponentenauswahl geholt)
dann kannst du doch mit
Code:
DBComboBox1->DataSource...
darauf zugreifen...

wenn du die ComboBox völlig dynamisch erzeugen willst vergess den Owner bzw. Parent nicht!

Könnte so aussehn
Code:
TDBComboBox *cmbA = new TDBComboBox(MainForm1);
cmbA->Parent = MainForm1;  // kann auch cmba->Owner = MainForm1; sein, hab gerade keinen Borländer zur Hand ;-)
cmbA->DataSource = dsMonate;
cmbA->DataField = "monat";

So müsste das dann eigentlich gehn...

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?
Man muss sie nicht neu deklarieren, hast du bspw. ein Panel auf deinem Form liegen, dann steht im Published Teil in der Header bspw.
Code:
TPanel *panel1;
dann kannst du in der .cpp auf das Panel mit
Code:
panel1->visible = true;   // oder ähnliches
darauf zugreifen

MfG Turri
 

javad

Grünschnabel
Turri hat gesagt.:
Man muss sie nicht neu deklarieren, hast du bspw. ein Panel auf deinem Form liegen, dann steht im Published Teil in der Header bspw.
Code:
TPanel *panel1;
dann kannst du in der .cpp auf das Panel mit
Code:
panel1->visible = true;   // oder ähnliches
darauf zugreifen

MfG Turri


Stimmt genau, darum geht es eigentlich, es hat mit ADO nichts zu tun:

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. Warum ?

// 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'​
}


Vielen Dank für die Antwort. Ich hatte so eine Problem noch nie. Ist in C++ bei Funktionen
noch mehr anzugeben, wenn man auf eine Form-Komponente zugreift?
 

Turri

Erfahrenes Mitglied
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. Warum ?

Code:
void __fastcall TMainForm::cmdCalClick(TObject *Sender)
{
  ...
}

wie du siehst bist du mit dem Event in der Klasse "TMainForm"...
erkennt man ja an dem "TMainForm::..."

wenn du in deiner Funktion deine ComboBox änder willst brauchst du den Zeiger des Forms.

in der Funktion müsstest du dann schreiben: (ich nehm mein Panel1 Beispiel) ;-)
Code:
MainForm1->panel1->visible = true;

Da ja deine Funktion, keine Funktion der Klasse TMainForm ist.

MfG Turri
 

javad

Grünschnabel
Turri hat gesagt.:
Code:
void __fastcall TMainForm::cmdCalClick(TObject *Sender)
{
  ...
}

wie du siehst bist du mit dem Event in der Klasse "TMainForm"...
erkennt man ja an dem "TMainForm::..."

wenn du in deiner Funktion deine ComboBox änder willst brauchst du den Zeiger des Forms.

in der Funktion müsstest du dann schreiben: (ich nehm mein Panel1 Beispiel) ;-)
Code:
MainForm1->panel1->visible = true;

Da ja deine Funktion, keine Funktion der Klasse TMainForm ist.

MfG Turri


Also gibt es 2 Möglichkeiten:

1. MainForm1->...Anweisungen

oder:

2. die Funktion zu einer Funktion der Klasse TMainForm zu machen
Wie geht das?

Bin C++ Newbie ;)
Was bedeutet __fastcall (mal ein Unterstrich, mal 2, wie ich gesehen habe)

Warum 2 Doppelpunkte nach TMainForm::

Ist mir aus anderen Sprachen (JAVA, VB.Net etc nicht bekannt)

Habe schon etliche Tutorials angesehen ... ud gegoogelt

Gruß und Danke im Voraus
 

Turri

Erfahrenes Mitglied
2. die Funktion zu einer Funktion der Klasse TMainForm zu machen
Wie geht das?

in deiner Header Datei gibt ja die Klasse "class TMainForm".
In den public Teil der Klasse schreibst du deinen Funktionsnamen

Code:
public:
    void deineFunktion();

in der cpp schreibst du dann ausserhalb jeglicher Events

Code:
void TMainForm::deineFunktion()
{
   // hier kannst du jetzt
   panel1->visible = true; // schreiben, das "MainForm1->" kannst du weglassen
}

Die "::" sind Namensraumbegrenzungen. Damit man weiß zu welcher Klasse die Funktion gehört.

Und das __fastcall gibts eigentlich nur mit 2 Unterstrichen...
die Seite erklärts ganz gut glaube ich. http://72.14.221.104/search?q=cache...ll.html+"__fastcall"&hl=de&gl=de&ct=clnk&cd=5 :google:

MfG Turri
 
Zuletzt bearbeitet:

javad

Grünschnabel
Vielen Dank für deine Antworten. ;-)

Das hat mir als Newbie enorm geholfen (auch der Link).
Jetzt weiß ich wo ich weiterforschen muß. ;)