Discussion:
Listbox mit VBA auslesen
(zu alt für eine Antwort)
Michael K.
2008-08-12 14:02:55 UTC
Permalink
Hallo Leute,

ich habe folgendes Problem.
Ich habe eine Listbox mit VBA und SQL Befehl mit Daten gefüllt.
Nun möchte ich die Listbox mit VBA Code auslesen.
Leider geht das nicht, da keine Zeile markiert ist.
Wie kann ich den Inhalt der Listbox auslesen?
--
MfG


Michael K.
Um in direkten Emailkontakt zu treten,
füge ein s vor dem @ (at) beim meiner Emailadresse ein
Jens Schilling
2008-08-12 15:14:36 UTC
Permalink
Hallo, Michael
Post by Michael K.
ich habe folgendes Problem.
Ich habe eine Listbox mit VBA und SQL Befehl mit Daten gefüllt.
Nun möchte ich die Listbox mit VBA Code auslesen.
Leider geht das nicht, da keine Zeile markiert ist.
Wie kann ich den Inhalt der Listbox auslesen?
So ganz scheine ich Dein Problem nicht zu verstehen...

Wenn Du die Listbox durch eine SQL-Statement füllst, warum verwendest Du
dieses nicht gleich weiter ?
Ein Recordset darauf basierend stellt Dir doch die Daten zur Verfügung, oder
übersehe ich was ?

Gruss
Jens
Michael K.
2008-08-13 06:33:45 UTC
Permalink
Post by Jens Schilling
So ganz scheine ich Dein Problem nicht zu verstehen...
Ich fülle das Listenfeld über

Listenfeld.RowSource = strSQL

Auf der Eingabemaske sind einige Pulldownfelder und Eingabefelder.

Ich möchte diese Werte durch drücken des "SpeichernButton" per VBA
ausgelesen und die Werte je nach Rechten in die Datenbank schreiben.

Leider läßt sich das Listenfeld nicht auslesen, nur wenn ein Eintrag
selektiert ist.

Da das Listenfeld aber über ein Pulldownfeld befüllt wird, ist dort noch
nichts markiert.
Ich bräuchte jetzt eine Möglichkeit das Listenfeld auszulesen, ohne es zu
selektieren oder per VBA einen Eintrag z.b. den 2 zu selektieren.

Vielleicht kann mir ja da jemand helfen
Stefan Dase
2008-08-13 06:50:50 UTC
Permalink
Hallo Michael!
Post by Michael K.
Leider läßt sich das Listenfeld nicht auslesen, nur wenn ein Eintrag
selektiert ist.
Wie greifst du auf das Feld zu? Die .Text-Eigenschaft von
Steuerelementen steht nur zur Verfügung, wenn das Feld den Fokus hat.
Die .Value-Eigenschaft dagegen immer.
Post by Michael K.
Ich bräuchte jetzt eine Möglichkeit das Listenfeld auszulesen, ohne es zu
selektieren oder per VBA einen Eintrag z.b. den 2 zu selektieren.
Einen Eintrag im Kombi/Listenfeld auswählen: http://www.donkarl.com?FAQ4.12

HTH,
Stefan
Michael K.
2008-08-13 11:08:45 UTC
Permalink
Vielen Dank diese Lösung hat mir geholfen
Jens Schilling
2008-08-13 09:17:46 UTC
Permalink
Hallo, Michael
Post by Michael K.
Post by Jens Schilling
So ganz scheine ich Dein Problem nicht zu verstehen...
Ich fülle das Listenfeld über
Listenfeld.RowSource = strSQL
Auf der Eingabemaske sind einige Pulldownfelder und Eingabefelder.
Ich möchte diese Werte durch drücken des "SpeichernButton" per VBA
ausgelesen und die Werte je nach Rechten in die Datenbank schreiben.
Leider läßt sich das Listenfeld nicht auslesen, nur wenn ein Eintrag
selektiert ist.
Da das Listenfeld aber über ein Pulldownfeld befüllt wird, ist dort
noch nichts markiert.
Ich bräuchte jetzt eine Möglichkeit das Listenfeld auszulesen, ohne
es zu selektieren oder per VBA einen Eintrag z.b. den 2 zu
selektieren.
Vielleicht kann mir ja da jemand helfen
Nun, ich scheine Dich richtig verstanden zu haben, und wiederhole meinen
Vorschlag; lese doch einfach die Daten in ein Recordset ein, und hole Dir
was Du benötigst. Das Gerüst dazu könnte so aussehen :

Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL as String

' Hier wird die Datenquelle des Listenfeldes ausgelesen
strSQL = Me.Listenfeld.RowSource

Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
'Und nun sollten im Recordset die gleichen Daten wie im Listenfeld vorhanden
sein, mit denen kannst Du nun anstellen, was Du möchtest.

Do While Not rs.EOF
MsgBox rs(0)
rs.MoveNext
Loop

'Aufräumen nicht vergessen
rs.Close : Set rs = Nothing
Set db = Nothing
Josef Poetzl
2008-08-13 09:37:36 UTC
Permalink
Hallo!
Post by Jens Schilling
Post by Michael K.
Ich fülle das Listenfeld über
Listenfeld.RowSource = strSQL
[...]
Post by Jens Schilling
Nun, ich scheine Dich richtig verstanden zu haben, und wiederhole meinen
Vorschlag; lese doch einfach die Daten in ein Recordset ein, und hole Dir
was Du benötigst.
... oder verwende direkt das Recordset der Listbox. (das spart einen
weiteres Auswerten der SQL-Anweisung)

Dim rst As DAO.Recordset
Set rst = Me.Listenfeld.Recordset 'eventuell Recordset.Clone

Falls es nur um die Werte geht, könnte man auch die
Columns-Eigenschaft nutzen.

Wert = me.lstTest.Column(47,11)

Anm.: Der Zugriff über Recordset hat den Vorteil, dass Memo-Felder
nicht auf 255 Zeichen gekürzt werden.


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Jens Schilling
2008-08-13 09:53:16 UTC
Permalink
Hallo, Josef
Post by Josef Poetzl
... oder verwende direkt das Recordset der Listbox. (das spart einen
weiteres Auswerten der SQL-Anweisung)
Ist das versions-neutral, oder steht das erst - wie ich meine - ab A2000 zur
Verfügung ?
Ich hab' hier grad kein A97 zur Verfügung, um es prüfen zu können.

Tschüs
Jens
Josef Poetzl
2008-08-13 10:05:44 UTC
Permalink
Hallo!
Post by Jens Schilling
Post by Josef Poetzl
... oder verwende direkt das Recordset der Listbox. (das spart einen
weiteres Auswerten der SQL-Anweisung)
Ist das versions-neutral, oder steht das erst - wie ich meine - ab A2000 zur
Verfügung ?
Ich hab' hier grad kein A97 zur Verfügung, um es prüfen zu können.
Zugriff auf das Recordset ab Ac2000
Das Setzen des Recordsets ab Ac2002

Anm.:
Ich muss gestehen, dass ich meine Beispiele nicht mehr auf die
Funktionsfähigkeit unter Ac97 und älter prüfe, wenn im Beitrag nicht
explizit auf Ac97 verwiesen wird, da _ich_ Ac97 als überholt ansehe.


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Jens Schilling
2008-08-13 10:21:24 UTC
Permalink
Hallo, Josef
Post by Josef Poetzl
Post by Jens Schilling
Ist das versions-neutral, oder steht das erst - wie ich meine - ab
A2000 zur Verfügung ?
Zugriff auf das Recordset ab Ac2000
Das Setzen des Recordsets ab Ac2002
OK, danke für's Klarstellen.
Post by Josef Poetzl
Ich muss gestehen, dass ich meine Beispiele nicht mehr auf die
Funktionsfähigkeit unter Ac97 und älter prüfe, wenn im Beitrag nicht
explizit auf Ac97 verwiesen wird, da _ich_ Ac97 als überholt ansehe.
Ich denke, dass "da draussen" noch sehr viele 97er DBs existieren, und auch
noch unter A97 gehegt und gepflegt werden; daher *versuche* ich neutral zu
bleiben. Allerdings gibt es ein paar Dinge, die ich so schätzen gelernt
habe, dass ich nur zu gern vergesse, dass diese erst nach A97 zur Verfügung
stehen; OpenArgs für Berichte wäre so eines .

Tschüs
Jens
Josef Poetzl
2008-08-13 11:20:00 UTC
Permalink
Hallo!
Post by Jens Schilling
Ich denke, dass "da draussen" noch sehr viele 97er DBs existieren, und auch
noch unter A97 gehegt und gepflegt werden;
... daher auch mein Hinweis auf die explizite Angabe von Ac97 im
Beitrag. ;-)
Wenn kein Hinweis vorhanden ist, nehme ich meist die von mir
eingesetzte Version als Referenz - diese erwähne ich dann aber auch
nicht. :-)))
Post by Jens Schilling
daher *versuche* ich neutral zu bleiben.
... und ich werte Datenzugriffssicherheit höher als
Versions-Neutralität. ;-)

Im aktuellen Fall ist mit dem Zugriff auf das Recordset
sichergestellt, dass die identischen Datensätze durchlaufen werden,
was bei einer neuen Abfrage nicht sein muss, da in der Zwischenzeit
neue DS in der Datenbasis existieren könnten.

Anm.: Wenn schon versionsneutral, dann eher: Column(x, y)
(Ich prüfte das zwar nicht, gehe aber davon aus, dass das auch unter
Ac97 möglich ist ... obwohl: unter Ac2.0 läufts dann vermutlich wieder
nicht. ;-))


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Jens Schilling
2008-08-13 11:49:54 UTC
Permalink
Hallo, Josef
Post by Josef Poetzl
Im aktuellen Fall ist mit dem Zugriff auf das Recordset
sichergestellt, dass die identischen Datensätze durchlaufen werden,
... und was ich als Argument ebenso überzeugend finde, ist Dein Hinweis auf
die Memofelder.

Unsere Gewohnheiten aber werden wir eh beibehalten ... ;-)

Tschüs
Jens
Josef Poetzl
2008-08-13 12:47:28 UTC
Permalink
Hallo!
Post by Jens Schilling
Post by Josef Poetzl
Im aktuellen Fall ist mit dem Zugriff auf das Recordset
sichergestellt, dass die identischen Datensätze durchlaufen werden,
... und was ich als Argument ebenso überzeugend finde, ist Dein Hinweis auf
die Memofelder.
Was aber wiederum mit deinem Vorschlag genauso funktioniert. ;-)



Noch einmal kurz zusammengefasst die erwähnten Varianten:

1. neues Recordset mit RowSource öffnen

Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset(Me.ListBoxSteuerelement.RowSource)
With rst
While Not .EOF
machwasmit .Fields(0), .Fields(1)
.MoveNext
Wend
.Close
End With



2. ListBox-Recordset verwenden:

Dim rst As DAO.Recordset
Set rst = Me.ListBoxSteuerelement.Recordset.Clone
With rst
While Not .EOF
machwasmit .Fields(0), .Fields(1)
.MoveNext
Wend
End With


3. Zeilen mit Column(index, row) durchlaufen

Dim i As Long
Dim lngMaxCnt As Long
With Me.ListBoxSteuerelement
lngMaxCnt = .ListCount - 1 - .ColumnHeads
For i = -.ColumnHeads To lngMaxCnt
machwasmit .Column(0, i), .Column(1, i)
Next i
End With



4. (noch nicht erwähnte) Variante:
Wenn möglich auf das Durchlaufen verzichten und mittels
SQL-Anweisung(en) das gewünschte Ergebnis erzielen. ;-)



mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Peter Doering
2008-08-13 11:46:12 UTC
Permalink
Hallo Josef,
Post by Josef Poetzl
Post by Jens Schilling
Post by Michael K.
Ich fülle das Listenfeld über
Listenfeld.RowSource = strSQL
[...]
Post by Jens Schilling
Nun, ich scheine Dich richtig verstanden zu haben, und wiederhole meinen
Vorschlag; lese doch einfach die Daten in ein Recordset ein, und hole Dir
was Du benötigst.
... oder verwende direkt das Recordset der Listbox. (das spart einen
weiteres Auswerten der SQL-Anweisung)
[...]
Anm.: Der Zugriff über Recordset hat den Vorteil, dass Memo-Felder
nicht auf 255 Zeichen gekürzt werden.
Wuerde man Korinthen zaehlen, koennte man als Argument die Begrenzung der
Listbox auf 64k DS anfuehren, die beim von Jens vorgeschlagenen Recordset
keine Rolle spielen wuerde, aber wer hat schon so grosse Listenfelder ...
und wer zaehlt schon Korinthen ;-)

Gruss - Peter
Josef Poetzl
2008-08-13 12:10:53 UTC
Permalink
Hallo!
Post by Peter Doering
Post by Josef Poetzl
Post by Michael K.
Ich fülle das Listenfeld über
Listenfeld.RowSource = strSQL
[...]
Post by Peter Doering
Post by Josef Poetzl
... oder verwende direkt das Recordset der Listbox. (das spart einen
weiteres Auswerten der SQL-Anweisung)
[...]
Anm.: Der Zugriff über Recordset hat den Vorteil, dass Memo-Felder
nicht auf 255 Zeichen gekürzt werden.
Wuerde man Korinthen zaehlen, koennte man als Argument die Begrenzung der
Listbox auf 64k DS anfuehren, die beim von Jens vorgeschlagenen Recordset
keine Rolle spielen wuerde,
... genauso wenig wie bei Listbox.Recordset. ;-)
Post by Peter Doering
aber wer hat schon so grosse Listenfelder ...
genau.
Post by Peter Doering
und wer zaehlt schon Korinthen ;-)
Wenn es um Datenkonsistenz geht, erlaube ich mir diese durchaus zu
zählen. :-))

Man muss meiner Meinung nach berücksichtigen, ob man nur die
Datensätze aus der Listbox oder die Datensätze über die SQL-Anweisung
der Listbox erhalten möchte. Diese sind nicht zwingend identisch.
(und bei >65k DS muss man noch zusätzlich überlegen, ob man nur die
Zeilen der Listbox durcharbeiten möchte.)

Alle Varianten haben ihre Berechtigung. Man sollte nur wissen, dass
das Ergebnis von Listbox.Recordset nicht identisch mit dem Ergebnis
von Currendb.OpenRecordset(Listbox.rowsource) sein muss, dann wird man
es bestimmt passend einsetzen.


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Michael K.
2008-08-13 11:10:15 UTC
Permalink
Vielen Dank, werde diesen Code mal testen.
Loading...