SQL Verbindung beim Formular laden herstellen
Damit die Übersicht gewahrt bleibt eröffne ich hier ne neue Anfrage.
Hallo zusammen,
also ich hab (immernoch ) ein Excel-Formular das mit wenn ich auf nen Button klicke eine Verbindung zu einer SQL-Datenbank herstellt.
Private Sub CommandButton5_Click()
Set condb = New ADODB.Connection
condb.Open "DRIVER=MySQL ODBC 3.51 Driver; SERVER=localhost; DATABASE=datenbank;USER=xxxx;PASSWORD=xxxx;"
Dim rec As ADODB.Recordset
Set rec = New ADODB.Recordset
rec.CursorLocation = adUseClient
rec.Open "SELECT * FROM `table`ORDER BY `feld1`.`feld2` ", condb, adOpenForwardOnly, adLockReadOnly
rec.MoveFirst
While Not rec.EOF
ComboBox6.AddItem (rec.Fields(3))
ComboBox8.AddItem (rec.Fields(3))
rec.MoveNext
Wend
condb.Close
End Sub
Nun versuche ich aber das die Verbindung schon hergestellt wird wenn ich die Form öffne.
Hab ein Modul
Sub Start ()
UserForm5.Show
End Sub
Habe hier denn o. g. Code (für die SQL-Verbindung) eingefügt - hier meldet er mir aber - Objekt fehlt
Wahrscheinlich wegen der Combobox......
Wie bringe ich es fertig das er mir beim Laden/Öffnen der Form die SQL-Verbindung herstellt und die Combobox6 und 8 mit Daten fuellt.
Danke und Gruß
Manuel
Hallo zusammen,
also ich hab (immernoch ) ein Excel-Formular das mit wenn ich auf nen Button klicke eine Verbindung zu einer SQL-Datenbank herstellt.
Private Sub CommandButton5_Click()
Set condb = New ADODB.Connection
condb.Open "DRIVER=MySQL ODBC 3.51 Driver; SERVER=localhost; DATABASE=datenbank;USER=xxxx;PASSWORD=xxxx;"
Dim rec As ADODB.Recordset
Set rec = New ADODB.Recordset
rec.CursorLocation = adUseClient
rec.Open "SELECT * FROM `table`ORDER BY `feld1`.`feld2` ", condb, adOpenForwardOnly, adLockReadOnly
rec.MoveFirst
While Not rec.EOF
ComboBox6.AddItem (rec.Fields(3))
ComboBox8.AddItem (rec.Fields(3))
rec.MoveNext
Wend
condb.Close
End Sub
Nun versuche ich aber das die Verbindung schon hergestellt wird wenn ich die Form öffne.
Hab ein Modul
Sub Start ()
UserForm5.Show
End Sub
Habe hier denn o. g. Code (für die SQL-Verbindung) eingefügt - hier meldet er mir aber - Objekt fehlt
Wahrscheinlich wegen der Combobox......
Wie bringe ich es fertig das er mir beim Laden/Öffnen der Form die SQL-Verbindung herstellt und die Combobox6 und 8 mit Daten fuellt.
Danke und Gruß
Manuel
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 80433
Url: https://administrator.de/contentid/80433
Ausgedruckt am: 20.11.2024 um 13:11 Uhr
12 Kommentare
Neuester Kommentar
hi,
du kannst mal versuchen, einfach den formularnamen vor die comboboxen zu packen, damit er weiß wo er diese findet:
also komplett dann so ->
Sub Start ()
UserForm5.Show
Set condb = New ADODB.Connection
condb.Open "DRIVER=MySQL ODBC 3.51 Driver; SERVER=localhost; DATABASE=datenbank;USER=xxxx;PASSWORD=xxxx;"
Dim rec As ADODB.Recordset
Set rec = New ADODB.Recordset
rec.CursorLocation = adUseClient
rec.Open "SELECT * FROM `table`ORDER BY `feld1`.`feld2` ", condb, adOpenForwardOnly, adLockReadOnly
rec.MoveFirst
While Not rec.EOF
UserForm5.ComboBox6.AddItem (rec.Fields(3))
UserForm5.ComboBox8.AddItem (rec.Fields(3))
rec.MoveNext
Wend
condb.Close
End Sub
du kannst mal versuchen, einfach den formularnamen vor die comboboxen zu packen, damit er weiß wo er diese findet:
also komplett dann so ->
Sub Start ()
UserForm5.Show
Set condb = New ADODB.Connection
condb.Open "DRIVER=MySQL ODBC 3.51 Driver; SERVER=localhost; DATABASE=datenbank;USER=xxxx;PASSWORD=xxxx;"
Dim rec As ADODB.Recordset
Set rec = New ADODB.Recordset
rec.CursorLocation = adUseClient
rec.Open "SELECT * FROM `table`ORDER BY `feld1`.`feld2` ", condb, adOpenForwardOnly, adLockReadOnly
rec.MoveFirst
While Not rec.EOF
UserForm5.ComboBox6.AddItem (rec.Fields(3))
UserForm5.ComboBox8.AddItem (rec.Fields(3))
rec.MoveNext
Wend
condb.Close
End Sub
Hallo Manuel,
Jein. Momentan ist Dein Recordset ja lokal in der Sub() Start. Sprich nach verlassen der Sub nicht mehr existent.
Und wenn ich das richtig verstehe soll die richtige Telefonnummer nach Auswahl des Firmennamens (ComboBox6_AfterUpdate) eingeblendet werden. Eine TextBox hat nur die Eigenschaft Text für einen Wert (nicht wie die Items Auflistung bei der ComboBox ).
Aslo könntest Du entweder das RecordSet global machen und nach Auswahl in der ComboBox6 die Find-methode des RecordSets aufrufen.
Andererseits könntest Du in der Sub-Start Wend-Schleife auch ein Array mit den Telefonnummern füllen
BG, Felix -misterdemeanor-
eine Sache waere da noch - und zwar versuche
ich - also wenn ich in der Combobox6 einen
Wert stehen hab - hier is es der Firmennamen
- soll er mir in Textfeld39 die dazugehoerige
Telefonnummer schreiben.
Muss ich hier in der Wend-Schleife dies
schon deklarieren?
ich - also wenn ich in der Combobox6 einen
Wert stehen hab - hier is es der Firmennamen
- soll er mir in Textfeld39 die dazugehoerige
Telefonnummer schreiben.
Muss ich hier in der Wend-Schleife dies
schon deklarieren?
Jein. Momentan ist Dein Recordset ja lokal in der Sub() Start. Sprich nach verlassen der Sub nicht mehr existent.
Und wenn ich das richtig verstehe soll die richtige Telefonnummer nach Auswahl des Firmennamens (ComboBox6_AfterUpdate) eingeblendet werden. Eine TextBox hat nur die Eigenschaft Text für einen Wert (nicht wie die Items Auflistung bei der ComboBox ).
Aslo könntest Du entweder das RecordSet global machen und nach Auswahl in der ComboBox6 die Find-methode des RecordSets aufrufen.
Andererseits könntest Du in der Sub-Start Wend-Schleife auch ein Array mit den Telefonnummern füllen
BG, Felix -misterdemeanor-
nein...bloß nicht! *g
So baust Du ja jedes mal eine Verbindung auf nachdem man etwas aus der ComboBox gewählt hat.
Außerdem wäre in Deinem Textfeld dann einfach die Telefonnummer(und nur die eine) des letzten Datensatzes.
Wenn ich das richtig vermute hast Du in Deiner Tabelle "table" 3 Felder aud die Du zugreifen willst--->Firmenname, Telefonnummer und ein drittes. ich würde Dir jetzt einfach raten das Recordset welches Du in der Sub-Start mit Daten füllst global verügbar zu machen. Ist nicht sehr fein aber für Dich die beste Lösung. Um das zu bewerkstelligen deklarierst Du die Recordset-Variable nicht in der Sub-Start sondern auf Modulebene mit Public rec As ADODB.Recordset.
In Deiner Sub ComboBox6_AfterUpdate() kannst Du nun auch auf das Recordset zugreifen. Um den entsprechenden Datensatz, respektive die zu der ComboBox Auswahl zugehörige Telefonnummer zu erhalten tippst Du folgendes ein:
Da ich nicht wusste und Du es immer verschieden gepostet hat must Du noch das entsprechende Feld anpassen. Hier exemplarisch PhoneNumber. Eventuell musst Du in der Sub-Start noch die Recordset.Open-Function anpassen. Du hast einen Vorwärtscursor, um die Find Methode richtig anzuwenden ist glaube ich ein Dynamischer Cursor nötig.
So baust Du ja jedes mal eine Verbindung auf nachdem man etwas aus der ComboBox gewählt hat.
Außerdem wäre in Deinem Textfeld dann einfach die Telefonnummer(und nur die eine) des letzten Datensatzes.
Wenn ich das richtig vermute hast Du in Deiner Tabelle "table" 3 Felder aud die Du zugreifen willst--->Firmenname, Telefonnummer und ein drittes. ich würde Dir jetzt einfach raten das Recordset welches Du in der Sub-Start mit Daten füllst global verügbar zu machen. Ist nicht sehr fein aber für Dich die beste Lösung. Um das zu bewerkstelligen deklarierst Du die Recordset-Variable nicht in der Sub-Start sondern auf Modulebene mit Public rec As ADODB.Recordset.
In Deiner Sub ComboBox6_AfterUpdate() kannst Du nun auch auf das Recordset zugreifen. Um den entsprechenden Datensatz, respektive die zu der ComboBox Auswahl zugehörige Telefonnummer zu erhalten tippst Du folgendes ein:
rec.MoveFirst
rec.Find "Firmenname='" & UserForm5.ComboBox6.Text & "'"
If (Not rec.EOF) Or (Not rec.BOF) Then
UserForm5.TextBox37.Text = rec.Fields("PhoneNumber")
Else
UserForm5.TextBox37.Text = "Keine Tel-nummer vorhanden"
End If
Da ich nicht wusste und Du es immer verschieden gepostet hat must Du noch das entsprechende Feld anpassen. Hier exemplarisch PhoneNumber. Eventuell musst Du in der Sub-Start noch die Recordset.Open-Function anpassen. Du hast einen Vorwärtscursor, um die Find Methode richtig anzuwenden ist glaube ich ein Dynamischer Cursor nötig.
Hallo manuel,
also auf ein Neues *g Hatte nach dem letzten Post von Dir eigentlich schon resigniert.
Um direkt einen zweiten Hieb auszuteilen: Zwei Dinge gefallen mir an Deinem Programmierstil ganz und gar nicht. Du benennst die Steuerelemente nicht. Wenn Du (oder jemand anderes) diesen Code liest blickt man nicht durch. Benenne sie einfach! ComboBox6 z.B. cboFirma oder TextBox37 txtPhone. Zweitens habe ich einige andere Threads von Dir gelesen. Für jeden Pfirlefanz baust Du immer eine neue Verbindung zu ein DB auf. Das ist sehr unfein. Eigentlich noch ein dritter Punkt: RTFM! Selbst die lokale Hilfe von Office/VBA/Excel/ADO beinhaltet viel wissenswertes. Nimm es mir bitte nicht übel. Will wirklich nicht klug###ern nur die Welt verbessern
Nun aber zu Deinem Problem...
Kein Wunder wenn Du das eintippst:
Im Form5 hab ich bei Combobox6 aktualiseren
diesen Code -->
Private Sub ComboBox6_AfterUpdate()
...
Hier das erwähnte aufbauen einer Verbindung. Jedes mal wenn in der ComboBox etwas ausgewählt wird. Wie gesagtsehr unfein.
Desweiteren würdest Du keine Schleife schreiben hättest Du mal nachgeschaut was die [RecordSet].Find Function anstellt! Was Du hier getipselt hast ist eine Endlosschleife die nur wegen einem Fehler nicht weitergeht.
Code ist nicht getestet, hoffe er geht.
BG, Felix -misterdemeanor-
also auf ein Neues *g Hatte nach dem letzten Post von Dir eigentlich schon resigniert.
Um direkt einen zweiten Hieb auszuteilen: Zwei Dinge gefallen mir an Deinem Programmierstil ganz und gar nicht. Du benennst die Steuerelemente nicht. Wenn Du (oder jemand anderes) diesen Code liest blickt man nicht durch. Benenne sie einfach! ComboBox6 z.B. cboFirma oder TextBox37 txtPhone. Zweitens habe ich einige andere Threads von Dir gelesen. Für jeden Pfirlefanz baust Du immer eine neue Verbindung zu ein DB auf. Das ist sehr unfein. Eigentlich noch ein dritter Punkt: RTFM! Selbst die lokale Hilfe von Office/VBA/Excel/ADO beinhaltet viel wissenswertes. Nimm es mir bitte nicht übel. Will wirklich nicht klug###ern nur die Welt verbessern
Nun aber zu Deinem Problem...
Fehlermeldung -->
Entweder BOF oder EOF ist True, oder der
aktuelle Datnsatz wurde gelöscht. Der
angeforderte Vorgang benötigt einen
aktuellen Datensatz.
Entweder BOF oder EOF ist True, oder der
aktuelle Datnsatz wurde gelöscht. Der
angeforderte Vorgang benötigt einen
aktuellen Datensatz.
Kein Wunder wenn Du das eintippst:
Im Form5 hab ich bei Combobox6 aktualiseren
diesen Code -->
Private Sub ComboBox6_AfterUpdate()
...
' Datenbankanbindung
Set condb = New ADODB.Connection
condb.Open "DRIVER=MySQL ODBC 3.51
Driver; SERVER=localhost;
DATABASE=datenbank;USER=XXXX;PASSWORD=XXXX;"
Set rec = New ADODB.Recordset
rec.CursorLocation = adUseClient
rec.Open "SELECT * FROM `table ` ORDER
BY `CompName1` ", condb,
adOpenForwardOnly, adLockReadOnly
rec.MoveFirst
Wenn ich das richtig verstehe ist Deine Sub Start im Klassenmodul von UserForm5, richtig? In einem vorigen Post gab ich Dir den Rat ein globales Recordset zu verwenden.Set condb = New ADODB.Connection
condb.Open "DRIVER=MySQL ODBC 3.51
Driver; SERVER=localhost;
DATABASE=datenbank;USER=XXXX;PASSWORD=XXXX;"
Set rec = New ADODB.Recordset
rec.CursorLocation = adUseClient
rec.Open "SELECT * FROM `table ` ORDER
BY `CompName1` ", condb,
adOpenForwardOnly, adLockReadOnly
rec.MoveFirst
While Not rec.BOF
rec.Find "PhoneNo='"
& ComboBox6.Text &
"'"
Wenn in der ComboBox6 der Firmenname steht, in der Tabelle respektive dem RecordSet ein Feld mit Name PhoneNo existiert welches die Telefonnummern hält, macht es kein Sinn im Feld PhoneNo nach einem Firmennamen zu suchen...richtig?rec.Find "PhoneNo='"
& ComboBox6.Text &
"'"
rec.Find "firmenname='" & ComboBox6.Text & "'"
If (Not rec.EOF) Or (Not rec.BOF)
Then
TextBox39.Text =
rec.Fields("PhoneNo")
Else
TextBox39.Text = "Keine
Tel-nummer vorhanden"
rec.MoveNext
End If
Wend
End Sub
Um dem Spuk mal ein Ende zu setzen poste ich Dir einfach mal folgenden Code (Klassenmodul UserForm5 mit ComboBox und Start Code). ComboBox_AfterUpdate war von mir schlecht gewählt, daher jetzt imChange-Event.Then
TextBox39.Text =
rec.Fields("PhoneNo")
Else
TextBox39.Text = "Keine
Tel-nummer vorhanden"
rec.MoveNext
End If
Wend
End Sub
Private ConDB As ADODB.Connection 'im Klassenmodul verfügbare Connection
Sub Start()
Dim rec As ADODB.Recordset
Set rec = New ADODB.Recordset
'Einmaliges herstellen der Verbindung.
Set ConDB = New ADODB.Connection
ConDB.Open "DRIVER=MySQL ODBC 3.51 Driver; SERVER=localhost; DATABASE=1stbp_sender;USER=root;PASSWORD=root;"
rec.CursorLocation = adUseClient
rec.Open "SELECT * FROM `table` ORDER BY `sender`.`CompName1` ", ConDB, adOpenForwardOnly, adLockReadOnly
rec.MoveFirst
While Not rec.EOF
UserForm5.ComboBox6.AddItem (rec.Fields(3))
UserForm5.ComboBox8.AddItem (rec.Fields(2))
rec.MoveNext
Wend
rec.Close
Set rec = Nothing
UserForm5.Show
End Sub
Private Sub ComboBox6_Change()
Dim strBandNr As String, Zähler As Long, strSenderID As String
Dim rec As ADODB.Recordset
If VarVorhanden("EigenerMerker") = False Then
With Application.ActiveWorkbook.CustomDocumentProperties
.Add Name:="EigenerMerker", _
LinkToContent:=False, _
Type:=msoPropertyTypeNumber, _
Value:=0
End With
End If
Zähler = CLng(Application.ActiveWorkbook.CustomDocumentProperties("EigenerMerker").Value)
Zähler = Zähler + 1
strBandNr = Left([ComboBox6], 3) & Year(Date) & CStr(Format(Zähler, "0000"))
TextBox28 = strBandNr
Testbox37 = strSenderID
Set rec = New ADODB.Recordset
rec.CursorLocation = adUseClient
'Bitte noch die WHERE Klausel anpassen-->Firmenname
rec.Open "SELECT * FROM `table ` WHERE Firmenname='" & ComboBox6 & "'", ConDB, adOpenForwardOnly, adLockReadOnly
'Wenn das Recordset nun ein (oder mehrere) Firmennamen beinhaltet Telefonnummer in die TextBox
'Ggfls. reagieren wenn mehrere identische Firmennamen, bleibt Dir überlassen
If rec.RecordCount >= 1 Then
'Prüfen ob im Feld PhoneNo Daten vorhanden
If (rec.Fields("PhoneNo") <> "") And Not IsNull(rec.Fields("PhoneNo")) Then
TextBox39.Text = rec.Fields("PhoneNo")
End If
Else 'Dürfte nicht eintreten da Firmenname(Combobox) ja aus gleicher Tabelle
TextBox39.Text = "Keine Tel-nummer vorhanden"
End If
rec.Close
Set rec = Nothing
End Sub
Code ist nicht getestet, hoffe er geht.
BG, Felix -misterdemeanor-
Hi Manuel,
wir reden wohl irgendwie aneinander vorbei. Liegt aber an mir da ich schlicht und einfach das was Du schreibst falsch interpretiere. Hätten wir einmal 10 Minuten an einem Tisch gesessen wäre das sich nicht passiert.
Lass uns jetzt mal zusammenfassen. Wir haben im Grunde 3 Elemente die wir unterbringen wollen:
1. und 2. kommen in ein Modul --> Standardmodul. Dann musst Du die Connection aber Public deklarieren (Public ConDB As ADODB.Connection). Hatte im letzten Post von Dir mal wieder etwas missverstanden. (Das Modul heißt wohl "Form5 Start"...?
3. Kommt dann in Dein UserForm-Code. Was ja dann wohl "Form 5" heißt. Das ist nebenbei gesagt ein Klassenmodul. Hast also doch schon desöfteren damit gearbeitet.
Alright, so sollte es jetzt eigentlicch funktionieren.
OK. Fand ich übrigens super das Du meine Kritik so "sportlich" genommen hast. Aber glaube mir: Vor allem üersichtlich geschriebener Code (u.a. eben Benennung der Controls) und Kommentare erleichtern das warten und erweitern mittelgroßer Applikationen ungemein. Nicht zuletzt hilft es auch Leuten in Foren wie hier z.B. den Durchblick zu bekommen.
Schönes Wochenende
BG, Felix -misterdemeanor-
wir reden wohl irgendwie aneinander vorbei. Liegt aber an mir da ich schlicht und einfach das was Du schreibst falsch interpretiere. Hätten wir einmal 10 Minuten an einem Tisch gesessen wäre das sich nicht passiert.
Lass uns jetzt mal zusammenfassen. Wir haben im Grunde 3 Elemente die wir unterbringen wollen:
- Die Sub Start()
- Eine globale ADODB.Connection
- Der Ereignishandler für das Change Event der ComboBox6 (ComboBox6_Change)
1. und 2. kommen in ein Modul --> Standardmodul. Dann musst Du die Connection aber Public deklarieren (Public ConDB As ADODB.Connection). Hatte im letzten Post von Dir mal wieder etwas missverstanden. (Das Modul heißt wohl "Form5 Start"...?
3. Kommt dann in Dein UserForm-Code. Was ja dann wohl "Form 5" heißt. Das ist nebenbei gesagt ein Klassenmodul. Hast also doch schon desöfteren damit gearbeitet.
Alright, so sollte es jetzt eigentlicch funktionieren.
OK. Fand ich übrigens super das Du meine Kritik so "sportlich" genommen hast. Aber glaube mir: Vor allem üersichtlich geschriebener Code (u.a. eben Benennung der Controls) und Kommentare erleichtern das warten und erweitern mittelgroßer Applikationen ungemein. Nicht zuletzt hilft es auch Leuten in Foren wie hier z.B. den Durchblick zu bekommen.
UserForm5.ComboBox6.AddItem (rec.Fields(3))
z.B. ist nicht sehr Aussagekräftig. Es ist wirklich nur ein gut gemeinter Rat.Schönes Wochenende
BG, Felix -misterdemeanor-