Gibt es in VB2005 so etwas wie ein RecordSet wie in VB6

10/09/2007 - 13:41 von Anton Reinthaler | Report spam
Hi NG

Vor einigen Wochen hab ich mich entschlossen von VB6 auf VB2005 umzusteigen.
Seit Wochen versuche ich nun, ein klitzekleines Versuchsbeispiel zu
realisieren, welches in VB6 kein Problem wàre.
Und jeden Tag mehr treibt mich VB2005 in den Wahnsinn.
Ich Google, ich lese in den diversen Hilfen, hab mir ein Buch
gekauft(wahrscheinlich das falsche), aber nichts hilft mir weiter.

Hab eine Datenbank, eine Tabelle daraus lasse ich durch eine DataGridView
anzeigen.
Ich wollte anhand des Eintrages in einer Textbox die DatGridView auf die
passende Zeile setzen. Wird in die Textbox z.B. "ge" geschrieben, will ich
das mit "Nachname LIKE 'ge'"erreichen, die gefundene Zeile soll die erste
sein. Der Anwender sollte dann noch die Möglichkeit haben, in der
DataGridView zu blàttern und zu scrollen, bis er den richtigen Datensatz mit
der RETURN-Taste auswàhlt.

Ich habe den Eindruck, alle wichtigen Eigenschaften sind ReadOnly. Z.B.
konnte ich nirgends eine aktuelle Zeile im DataGridView setzen. Wie auch
immer, mit viel Glück habe ich das endlich geschafft.

Und jetzt wollte ich diese Datensàtze àndern, funktioniert nicht, wieder
Google ich, wieder lese und lese ich in den Hilfen, nichts was ich verwenden
könnte.

Was brauche ich alles für dieses saublöde Beispiel?

Ich habe eine Connection
Ich habe einen DataAdapter (Mit dem "SELECT..")
Ich habe eine DataTable (gefüllt vom DataAdapter mit Fill())
DataTable hat kein MoveNext usw. und auch keine Position, also hab ich mir
auch noch einen BindingSource zugelegt.
Der BindingSource hat als .DataSource den DataTable
Die DataGridView hat als .DataSource auch den DataTable.

Ich habe aber kein DataSet. Will ich auch nicht.
Oder brauch ich das unbedingt?

Wo schreib ich jetzt eine Änderung rein?
In den BindingSource hab ich den geànderten Wert schon geschrieben, ich kann
ihn auch sehen. Genügt das?
Und wie mache ich das Update?

Alles was mir an Hinweisen im Internet so unterkommt, und was ich auch
halbwegs verstehe klingt immer sehr einfach: "Na, damit das alles funzt
brauchst du nur DataAdapter.Update(DataTable) schreiben." oder àhnliches.
Funktioniert bei mir aber nicht.

Dass BindingSource.Current() auf den richtigen Datensatz zeigt, sehe ich an
dem .Rows.ItemArray von DataRowView.
Record = CType(BindingSource.Current() , DataRowView)
Da steht auch schon der geànderte Wert drin.

Wo muß ich den geànderten Wert noch hinschreiben?
DataTable.Rows ist ja schreibgeschützt.
Und wieso funktioniert DataAdapter.Update(DataTable) bei mir nicht?
Die Fehlermeldung:
Aktualisieren erfordert einen gültigen UpdateCommand, wenn eine
DataRow-Auflistung mit modifizierten Zeilen weitergegeben wird.

Ja, ziemlich lange Frage, ich weiß.
Grüße
Toni
 

Lesen sie die antworten

#1 Peter Götz
10/09/2007 - 15:19 | Warnen spam
Hallo Anton,

Vor einigen Wochen hab ich mich entschlossen von
VB6 auf VB2005 umzusteigen.
Seit Wochen versuche ich nun, ein klitzekleines
Versuchsbeispiel zu realisieren, welches in VB6
kein Problem wàre.



In VB.net mit ADO.net eigentlich noch weniger problematisch
und deutlich komfortabler.

Und jeden Tag mehr treibt mich VB2005 in den Wahnsinn.
Ich Google, ich lese in den diversen Hilfen, hab mir ein Buch
gekauft(wahrscheinlich das falsche), aber nichts hilft mir weiter.

Hab eine Datenbank, eine Tabelle daraus lasse ich durch eine
DataGridView anzeigen.



Und wer oder was ist die Datenquelle für Dein DataGridView?
Das DGV ist nur ein Anzeigemedium, die Daten selbst werden
in einer DataTable/DataView oder in Arrays, Arraylist usw.
gespeichert.

Ich wollte anhand des Eintrages in einer Textbox die
DatGridView auf die passende Zeile setzen. Wird in
die Textbox z.B. "ge" geschrieben, will ich das mit
"Nachname LIKE 'ge'"erreichen, die gefundene Zeile
soll die erste sein. Der Anwender sollte dann noch die
Möglichkeit haben, in der DataGridView zu blàttern
und zu scrollen, bis er den richtigen Datensatz mit
der RETURN-Taste auswàhlt.

Ich habe den Eindruck, alle wichtigen Eigenschaften
sind ReadOnly. Z.B. konnte ich nirgends eine aktuelle
Zeile im DataGridView setzen. Wie auch
immer, mit viel Glück habe ich das endlich geschafft.

Und jetzt wollte ich diese Datensàtze àndern,
funktioniert nicht, wieder Google ich, wieder lese
und lese ich in den Hilfen, nichts was ich verwenden
könnte.

Was brauche ich alles für dieses saublöde Beispiel?

Ich habe eine Connection
Ich habe einen DataAdapter (Mit dem "SELECT..")
Ich habe eine DataTable (gefüllt vom DataAdapter mit Fill())



Ok, dann hast du ja schon mal eine DataTable, die
Daten enthàlt.

DataTable hat kein MoveNext usw. und auch keine Position,



Das ist auch nicht Sache der DataTable.
Die eigentliche DataSource für Dein DataGridView ist
ein DataView-Objekt, das Du entweder explizit per
Code erstellen kannst oder welches implizit erzeugt
wird, wenn Du Deinem DataGridView als DataSource
einfach einen Verweis auf die DataTable gibst.
Besser ist es, Du erstellst Dir zu Deiner DataTable
eine zugehörige DataView

dim DV as DataView
DV = new DataView(DeineDataTable)

und diese bindest Du dann an Dein DataGridVieW

DGV.DataSource = DV

Damit werden die Daten aus Deiner DataTable im DGV
schon mal sichtbar. Damit Du nun nicht nur durch Mausklicks
oder mit Hilfe der Cursortasten im Datenbestand navigieren
kannst, brauchst Du noch einen CurrencyManager.

Dim CM as CurrencyManager
CM = DirectCast(Me.BindingContext(DV), CurrencyManager)

und der hat nun die von Dir bei der DataTable vermisste
Position-Eigenschaft.



also hab ich mir
auch noch einen BindingSource zugelegt.



Die u.a. auch einen CurrencyManager kapselt.
Es ist besser auf BindingSource erst mal zu
verzichten und rein mit den grundlegenden Objekten
DataTable, DataView und CurrencyManager zu
experimentieren, damit Du deren Funktionalitàten
wirklich kennen- und verstehen lernst.

Der BindingSource hat als .DataSource den
DataTable. Die DataGridView hat als .DataSource
auch den DataTable.



Nein, tatsàchlich ist die DataSource Deines DataGridView
eine implizit erzeugte DataView.


Ich habe aber kein DataSet. Will ich auch nicht.
Oder brauch ich das unbedingt?



Nein, wenn Du lediglich eine einzige DataTable
zu verwalten hast, wàre ein DataSet völlig überflüssiger
Ballast.

Wo schreib ich jetzt eine Änderung rein?



In die DataTable:

DataTable.Rows(y).Item(x) = NeuerWert

In den BindingSource hab ich den geànderten
Wert schon geschrieben, ich kann
ihn auch sehen. Genügt das?
Und wie mache ich das Update?



Dazu braucht Dein DataAdapter einen UpdateCommand
bzw. für neue Datensàtze einen InsertCommand, sowie
einen DeleteCommand zum Löschen von Datensàtzen.
Anhand der Eigenschaft DataTable.Rows(x).RowState
kann der DataAdapter erkennen, ob es sich um eine
neue, geànderte, gelöschte oder unverànderte Zeile
handelt und reagiert beim DataAdapter.Update dann
mit dem passenden Command.

Du kannst aber auch einen DataAdapter verzichten und
direkt per Command.ExecuteNonQuery Insert-, Update-,
oder DeleteCommands ausführen.

Alles was mir an Hinweisen im Internet so unterkommt,
und was ich auch halbwegs verstehe klingt immer sehr
einfach: "Na, damit das alles funzt brauchst du nur
DataAdapter.Update(DataTable) schreiben." oder àhnliches.
Funktioniert bei mir aber nicht.



Deshalb mache Dich erst mal mit DataTable, DataView und
CurrencyManager vertraut. Wenn Du das verinnerlicht hast
nimm Dir Connection, DataAdapter, DataReader und
Command mit zugehörigen Parameter-Objekten vor.


Dass BindingSource.Current() auf den richtigen
Datensatz zeigt,



Was letztlich vom darin gekapselten CurrencyManager.Current
kommt.

sehe ich an dem .Rows.ItemArray von DataRowView.



Wobei DataRowView das "Sicht-Objekt" für eine Zeile
der DataView ist, welche Du offenbar ohne es zu
wissen implizit erzeugt hast.

Record = CType(BindingSource.Current() , DataRowView)
Da steht auch schon der geànderte Wert drin.

Wo muß ich den geànderten Wert noch hinschreiben?
DataTable.Rows ist ja schreibgeschützt.



DataTable.Rows(RowIndex).Item(ColIndex).Item aber nicht.

Und wieso funktioniert DataAdapter.Update(DataTable)
bei mir nicht?



Weil Du vermutlich für Deinen DataAdapter lediglich einen
Select-Command aber noch keine Insert-, Update u. Delete-
Commands definiert hast.

Die Fehlermeldung:
Aktualisieren erfordert einen gültigen UpdateCommand,



Ja, so isses, und diesen UpdateCommand hast Du
offenbar noch nicht definiert.

wenn eine DataRow-Auflistung mit modifizierten
Zeilen weitergegeben wird.



Wobei "modifizierte" Zeilen dadurch gekennzeichnet sind,
dass deren RowState-Eigenschaft den Wert
"DataRowState.Modified" hat.

Schau Dir mal das nachfolgende Beispiel an:

' /// Code in einer leeren Form
Public Class Form1
Private WithEvents DGV As DataGridView
Private WithEvents btnPrev As Button
Private WithEvents btnNext As Button

Private mDT As DataTable
Private mDV As DataView
Private mCM As CurrencyManager

Private Sub Form1_Load _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles MyBase.Load

Me.Size = New Size(300, 350)
CreateControls()
CreateData()
DGV.DataSource = mDV

' Auskommentierung der nàchsten Zeile zum
' Testen mal entfernen.
' mDV.RowFilter = "Text Like 'M*'"
End Sub

Private Sub CreateData()
Dim i As Integer
Dim DR As DataRow

mDT = New DataTable
With mDT
.Columns.Add("ID", GetType(Integer))
.Columns.Add("Text", GetType(String))
For i = 1 To 12
DR = .NewRow
DR.Item(0) = i
DR.Item(1) = MonthName(i)
.Rows.Add(DR)
Next
.AcceptChanges()
End With

mDV = New DataView(mDT)

mCM = _
DirectCast _
(Me.BindingContext(mDV), CurrencyManager)

End Sub

Private Sub CreateControls()
DGV = New DataGridView
With DGV
.SetBounds _
(10, 10, _
Me.ClientSize.Width - 20, _
Me.ClientSize.Height - 60)

.Anchor = AnchorStyles.Left Or _
AnchorStyles.Top Or _
AnchorStyles.Right Or _
AnchorStyles.Bottom
End With
Me.Controls.Add(DGV)

btnPrev = New Button
With btnPrev
.SetBounds _
(10, DGV.Bottom + 10, 50, 30)

.Anchor = AnchorStyles.Left Or _
AnchorStyles.Bottom
.Text = "<"
End With
Me.Controls.Add(btnPrev)

btnNext = New Button
With btnNext
.SetBounds(btnPrev.Right + 5, btnPrev.Top, 50, 30)
.Anchor = AnchorStyles.Left Or AnchorStyles.Bottom
.Text = ">"
End With
Me.Controls.Add(btnNext)
End Sub

Private Sub btnPrev_Click _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles btnPrev.Click

mCM.Position -= 1
End Sub

Private Sub btnNext_Click _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles btnNext.Click

mCM.Position += 1
End Sub
End Class
' \\\ E N T E

Damit kannst Du Dir erst mal ansehen, was DataTable
DataView und CurrencyManager so zu bieten haben.
Danach schau Dir mal die Doku zu

DataView
.Sort
.Find()
.FindRows()
.RowFilter
.RowStateFilter

und

DataRow
.Select()
.Rows.Find()
.Rows.IndexOf()

an. Damit hast Du dann schon mal eine Vielzahl von
Möglichkeiten nach bestimmten Datensàtzen zu
suchen, Datensàtze herauszufiltern oder zu sortieren.

Wenn das alles klar ist, dann nimm Dir wie oben schon
erwàhnt Connection, DataAdapter, DataReader und
Command- mit Parameter-Objekten vor.

Weitere Beispiele findest du unter

www.gssg.de -> Visual Basic -> VB.net

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

Ähnliche fragen