Galileo Computing < openbook >
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung

...powered by haas.homelinux.net...

Einstieg in VB.NET von René Martin
- Für Programmiereinsteiger -
Einstieg in VB.NET
gp Kapitel 9 Datenbankzugriff
  gp 9.1 Tabellen
  gp 9.2 Abfragen
    gp 9.2.1 Sortieren in einer Abfrage
    gp 9.2.2 Filtern in einer Abfrage
  gp 9.3 Beziehungen zwischen Tabellen
  gp 9.4 Zugriff von VB.NET auf die Datenbank
    gp 9.4.1 Gebundene Formulare
    gp 9.4.2 Steuerung des Formulars
    gp 9.4.3 Gebundene Formulare ohne Assistent
    gp 9.4.4 Ungebundene Formulare


Galileo Computing

9.4 Zugriff von VB.NET auf die Datenbank  downtop


Galileo Computing

9.4.1 Gebundene Formulare  downtop

Wird nun ein Formular an eine Datenbank gebunden, dann stellt VB.NET drei zentrale Steuerelemente zur Verfügung: »OleDbConnection«, »OleDbDataAdapter« und »DataSet«. Sie finden sie im Register »Daten« der Toolbox. Es handelt sich hierbei nicht um Steuerelemente, sondern um eine .dll-Datei, die zur Verfügung gestellt wird.

Abbildung

Abbildung 9.9   Die Elemente

Wenn Sie wenig vertraut sind mit den Befehlen zum Datenzugriff, dann sollten Sie zuerst die »OleDbDataAdapter-Komponente« auf das Formular ziehen. Danach startet ein Willkommensbildschirm. Im zweiten Schritt wird die Datenverbindung hergestellt. Mit dem Button »Neue Verbindung« müssen gewisse Datenzugriffs-Eigenschaften festgelegt werden. Im ersten Registerblatt »Provider« wird die Art des Datenbankzugriffs festgelegt. Wählen Sie »Microsoft Jet 4.0 OLE DB Provider«, um einen Zugriff zur Access-Datenbank zu erhalten.

Abbildung

Abbildung 9.10   Der Provider wird eingestellt.

Mit der Schaltfläche »Weiter« gelangen Sie zum zweiten Registerblatt »Verbindung«, wo der Datenbankname ausgewählt werden kann. Die Verbindung kann getestet werden. Sollten verschiedene Benutzer mit unterschiedlichen Konten an dieser Datei arbeiten, so ist der entsprechende Benutzername auszuwählen. Ebenso kann das Kennwort festgelegt werden, falls eins vorhanden ist.

Abbildung

Abbildung 9.11   Die Verbindung wird hergestellt.

Hinter dem Register »Erweitert« verbergen sich verschiedene Zugriffsmöglichkeiten auf die Datenbank. Da in unserem Beispiel der Benutzer alle Daten lesen und ändern darf, kann »ReadWrite« gewählt oder die Voreinstellung »Share Deny None« belassen werden.

Alle vorgenommenen Einstellungen finden Sie im vierten Registerblatt »Alle« angezeigt.

Abbildung

Abbildung 9.12   Die Datenbankverbindung wurde hergestellt.

Im nächsten Schritt werden Sie gefragt, ob Sie bereits vorhandene SQL-Anweisungen von gespeicherten Prozeduren oder eigene SQL-Anweisungen verwenden möchten. Da bislang noch keine SQL-Statements vorliegen, ist die Frage obsolet. Es geht einen Schritt weiter. Dort können Sie nun die SQL-Anweisungen »per Hand« eingeben oder sich erneut mit einem Abfragegenerator helfen lassen. Ähnlich wie in Access baut die Abfrage entweder auf einer Tabelle oder auf einer bereits definierten Abfrage (»Sicht«) auf.

Abbildung

Abbildung 9.13   Eine Tabelle wird ausgewählt.

Die Spalten werden ausgewählt, die Ausgabe kann ausgeblendet, die Sortierung eingeschaltet und ein oder mehrere Filterkriterien eingegeben werden. Der Abfrage-Generator erzeugt dabei den zugehörigen SQL-Code.

Abbildung

Abbildung 9.14   Die Abfrage

Abbildung

Abbildung 9.15   Der Code erscheint anschließend im Fenster des Datenadapters.

Im letzten Schritt wird Ihnen mitgeteilt, dass der »OleDataAdapter1« erfolgreich konfiguriert wurde. Er befindet sich nun – zusammen mit der »OleDbConnection1-Komponente« am unteren Rand des Fensters. Gleichzeitig wurde in VB.NET ein neuer Menüpunkt Daten eingefügt. Darüber könnte er erneut konfiguriert werden. Interessanter ist jedoch die Vorschau (Daten Datenvorschau). Damit kann überprüft werden, ob die Verbindung hergestellt wurde beziehungsweise ob die Sortier- und Auswahlkriterien korrekt eingestellt wurden.

Abbildung

Abbildung 9.16   Die Datenvorschau

Nun kann über das Menü Daten Dataset generieren oder aus der Toolbox über die Komponente »DataSet« ein neues Dataset erzeugt werden. Es erscheint ebenfalls am unteren Rand des Fensters.

Abbildung

Abbildung 9.17   Das Dataset wird erzeugt.

Schließlich kann das Steuerelement »DataGrid« auf das Formular gezogen werden. Wird das Formular gestartet, erscheint eine Leerstelle. Damit es mit den richtigen Daten gefüllt wird, muss beim Laden des Formulars »DataSet1« gefüllt werden. Im Ereignis »Load« wird Folgendes festgelegt:

Private Sub frmDB_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) 
Handles MyBase.Load
   Me.OleDbDataAdapter1.Fill(Me.DataSet1)
End Sub
Abbildung

Abbildung 9.18   Die Entwurfsansicht

Abbildung

Abbildung 9.19   Das fertige Formular – die Eigenschaft »Dock« wurde in der Kategorie »Layout« auf »Fill« gesetzt.

Schließlich muss in den Eigenschaften in der Kategorie »Daten« die Datenquelle (DataSource) auf das korrekte Objekt gesetzt werden (DataSet1.t_kunden).


Galileo Computing

9.4.2 Steuerung des Formulars  downtop

Natürlich müssen die Daten nicht nur tabellarisch angezeigt werden. Wie von vielen Datenbanken bekannt, kann auch lediglich ein Datensatz angezeigt werden, es können allerdings eine ganze Reihe von Feldern angezeigt werden. Dafür stehen Ihnen die übrigen Steuerelemente zur Verfügung, die bereits besprochen wurden. Natürlich verwendet man in der Regel Textfelder, um editierbare Daten anzuzeigen, Radiobuttons und Checkboxes für Ja/Nein-Abfragen, Listenfelder und Kombinationsfelder für Auswahllisten.

In unserem Beispiel der Kunden werden zwei weitere Spalten in der Datenbank hinzugefügt: »Geschlecht« vom Typ Zahl (»1« steht für weiblich, »2« für männlich) und »Infopost« vom Typ »Ja/Nein«.

Auf einem weiteren Formular, das an die Tabelle gebunden wird wie oben beschrieben, werden nun die Textfelder angebracht. Damit sie direkt mit dem DataSet verknüpft werden können, wird die Komponente »DataView« benötigt. In der Eigenschaft »Table« in der Kategorie »Daten« wird die Tabelle eingestellt, die das DataSet zur Verfügung stellt (t_Kunden). Nun kann jedes Steuerelement an das DataView-Feld gebunden werden.

Abbildung

Abbildung 9.20   Über die Eigenschaften werden die Daten an die Felder gebunden.

Das Kontrollkästchen erhält in der Kategorie »Daten« die Eigenschaft »Checked«, die Zuordnung zum entsprechenden Feld.

Verwendet man das alte Formular, welches noch nicht die neuen Felder »Geschlecht« und Infopost« kennt, so muss man den »OleDbAdapter« in den Eigenschaften korrekt formatieren, das heißt in der SQL-Abfrage die zusätzlichen Felder hinzufügen.

Damit eine Navigation möglich ist, werden am unteren Rand vier Buttons angebracht, welche einen Datensatz vor- oder zurückspringen oder sich auf den ersten oder letzten Datensatz bewegen. Sie werden butErster, butZurück, butWeiter und butLetzter genannt. Beim Laden wird das DataSet gefüllt:

Private Sub frmDB2_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
   Me.OleDbDataAdapter1.Fill(Me.DataSet11)
End Sub

Der erste Datensatz wird erreicht, indem die Position auf 0 gesetzt wird (auch hier beginnt die Zählung wieder bei 0!).

Private Sub butErster_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
butErster.Click
   Me.BindingContext(Me.DataView1).Position = 0
End Sub

Beim Weiter- und Zurückspringen wird die Position um 1 erniedrigt, beziehungsweise erhöht:

Private Sub butWeiter_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
butWeiter.Click
   Me.BindingContext(Me.DataView1).Position += 1
End Sub

Private Sub butZurück_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
butZurück.Click
   Me.BindingContext(Me.DataView1).Position -= 1
End Sub

Um auf den letzten Datensatz zu springen, muss die Anzahl der Datensätze ermittelt werden:

Private Sub butLetzter_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
butLetzter.Click
   Me.BindingContext(Me.DataView1).Position = _
   Me.DataSet11.t_Kunden.Rows.Count - 1
End Sub

Damit der Benutzer weiß, »auf welchem Datensatz er sich befindet«, wird ein Bezeichnungsfeld eingefügt, welches die Gesamtzahl der Datensätze und die aktuelle Position anzeigt:

Private Sub PosAnzeigen()
  Me.lblPos.Text = _
  (Me.BindingContext(Me.DataView1).Position + 1).ToString _
  & " von " & Me.DataView1.Count
End Sub

Es wird in jeder der oberen vier Prozeduren und beim Laden aufgerufen:

Call PosAnzeigen()

Viele Datenbanksysteme liefern einen Fehler, wenn der Datensatzzeiger auf dem ersten Datensatz steht und der Benutzer einen Satz zurückgehen möchte. Man könnte dies abfangen mit:

Private Sub butZurück_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
butZurück.Click
   If Me.BindingContext(Me.DataView1).Position > 1 Then
      Me.BindingContext(Me.DataView1).Position -= 1
      Call PosAnzeigen()
   End If
End Sub

Allerdings ist dies in VB.NET nicht nötig, da eine Position kleiner 0 als erste interpretiert wird und eine Position über dem größten als letzte.

Abbildung

Abbildung 9.21   Die Datensätze mit Navigation

Die Anzeige der aktuellen Position mittels einer Prozedur ist umständlich, weil sie von jeder Prozedur, in welcher die Datensätze verändert werden, aufgerufen wird. Außerdem können die Radiobuttons nicht direkt an das Feld »Geschlecht« gebunden werden. Wie dies funktioniert, wird im nächsten Kapitel beschrieben.


Galileo Computing

9.4.3 Gebundene Formulare ohne Assistent  downtop

Man kann den Datenbankzugriff auch völlig ohne Assistenten steuern. Die bisher verwendeten Objekte liegen alle in der Klasse System.Data. Es wäre sinnvoll, zusätzlich das Objekt »System.Data.OleDb« zu importieren, da dort weitere wichtige Objekte liegen. Um zu zeigen, welches Objekt wo liegt, beschränke ich mich auf:

Imports System.Data

Anschließend wird für die gesamte Klasse deklariert:

Dim objConnection As OleDb.OleDbConnection = _
   New OleDb.OleDbConnection _
   ("Provider=Microsoft.Jet.OLEDB.4.0; " & _
   "Data Source=D:\Data\Kapitel09\Rechnungen.mdb")
Dim objDataAdapter As OleDb.OleDbDataAdapter
Dim objDataSet As DataSet
Dim objDataView As DataView

Der Provider stellt einen Zugriff auf Ihre Daten her. Ist die Datenbank mit einem Kennwort geschützt, so muss dieses mit angegeben werden, beispielsweise:

User Id=Martin; Password=Medardus;

Wird auf einen SQL-Server zugegriffen, dann werden folgende Argumente übergeben:

Tabelle 9.4   Die wichtigsten Verbindungsargumente des SQL-Server-Providers
Argument Bedeutung
Server der Name des Servers
Database der Name der Datenbank
Connection Timeout das Timeout für den Verbindungsaufbau. Wird es überschritten, erzeugt der Provider eine Ausnahme
Trusted_Connection eine vertraute Verbindung
User Id der SQL-Server-Loginname
Password das Passwort

Dies könnte beispielsweise so aussehen:

Dim objConnection As OleDb.OleDbConnection = _
New OleDbConnection("Provider=SQLOLEDB; " & _
"Data Source=localhost; Initial Catalog=pubs; " & _
"User ID=Martin; Password=Medardus; ")

Beim Laden wird ein neues DataSet erstellt. Die Verbindung zur definierten Datenbank wird hergestellt. Damit wird mit einer SQL-Anweisung auf die entsprechenden Daten einer Tabelle (oder Abfrage) zugegriffen. Der DataAdapter wird gefüllt, das DataView-Objekt verweist auf eine Tabelle:

Private Sub frmDB2_Load(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles MyBase.Load
   objDataView = Nothing
   objDataSet = New DataSet()
   objConnection.Open()

   objDataAdapter = New OleDb.OleDbDataAdapter _
   ("SELECT * FROM t_Kunden", objConnection)
   objDataAdapter.Fill(objDataSet, "t_Kunden")
   objDataView = _
      New DataView(objDataSet.Tables("t_Kunden"))

Damit sind per Programmierung die Schritte durchgeführt, die in den beiden vorangegangenen Kapiteln der Assistent erledigte. Nun müssen noch die Steuerelemente an die entsprechenden Felder gebunden werden:

With Me
   .txtVorname.DataBindings.Add("Text", _
      objDataView, "Vorname")
   .txtZuname.DataBindings.Add("Text", objDataView, _
      "Zuname")
   .txtStraße.DataBindings.Add("Text", objDataView, _
      "Straße")
   .txtPLZ.DataBindings.Add("Text", objDataView, "Plz")
   .txtOrt.DataBindings.Add("Text", objDataView, "Ort")
   .chkInfopost.DataBindings.Add("Checked", objDataView, _
      "Infopost")
End With

Damit beim Vor- oder Zurückblättern die korrekte Bezeichnung angezeigt wird, muss eine Ereignisprozedur definiert werden:

Private Sub Datensatz_Ändern(ByVal sender As Object, _
   ByVal e As System.EventArgs)
   Dim dblPos As Double = _
   Me.BindingContext(objDataView).Position
   Me.lblPos.Text = (dblPos + 1).ToString & " von " & _
   objDataView.Count
   Me.radFrau.Checked = _
      (objDataView.Item(dblPos).Item("Geschlecht") = 1)
   Me.radHerr.Checked = _
      (objDataView.Item(dblPos).Item("Geschlecht") = 2)
End Sub

Der erste Teil ist bekannt: Auf dem Label wird der korrekte Text angezeigt. An die Eigenschaft »Checked« wird nun der Wahrheitswert übergeben, der ermittelt wird, indem in der korrekten Zeile (dblPos) der entsprechenden Spalte (Geschlecht) abgefragt wird, ob eine 1 oder 2 steht. Damit die Ereignisprozedur funktioniert, muss sie im Load-Ereignis definiert werden:

AddHandler Me.BindingContext(objDataView). _
PositionChanged, AddressOf Datensatz_Ändern

Da beim Laden des Formulars das Objekt DataView bereits auf den ersten Datensatz gesetzt wird, muss er explizit angestoßen werden:

   Me.Datensatz_Ändern(objDataView, New System.EventArgs())
End Sub

Er wird nun von jedem der vier Prozeduren aufgerufen, mit denen sich der Benutzer über die Datensätze bewegt. Zu beachten ist, dass beim Entladen des Formulars die Verbindung geschlossen werden muss:

Private Sub frmDB3_Closed(ByVal sender As Object, _
   ByVal e As System.EventArgs) Handles MyBase.Closed
   objConnection.Close()
   objDataSet = Nothing
End Sub
Abbildung

Abbildung 9.22   Nun wird auch das Geschlecht aktualisiert.


Galileo Computing

9.4.4 Ungebundene Formulare  toptop

Im letzten Kapitel ist sicherlich deutlich geworden, dass auch beim Datenbankzugriff kein Assistent oder Steuerelement benötigt wird. Dieser Gedanke soll weiter ausgeführt werden. Auf das Formular werden vier weitere Buttons gesetzt, die mit »Neu«, »Anhängen«, »Ändern« und »Löschen« beschriftet werden. Der Button »Neu« hat die Aufgabe, die vorhandenen Textfelder zu löschen. Entweder so:

With Me
   .txtVorname.Text = ""
   .txtZuname.Text = ""
...
End With

oder etwas eleganter mit Hilfe einer Schleife:

Private Sub butNeu_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles butNeu.Click
   Dim ctl As Control
   For Each ctl In Me.Controls
      If ctl.Name.StartsWith("txt") = True Then
         ctl.Text = ""
      End If
   Next
End Sub

Trägt nun der Benutzer die neuen Daten ein und klickt auf den zweiten Button, dann müssen sie zurück in die Datenbank geschrieben werden. Dazu wird als Objekt eine neue Zeile deklariert (objZeile). Sie wird mit den neuen Einträgen gefüllt. Diese Zeile kann dann an das DataSet-Objekt angehängt werden:

Private Sub butAnhängen_Click(ByVal sender As _
   System.Object, ByVal e As System.EventArgs) Handles _
   butAnhängen.Click
   Dim objZeile As DataRow
   objZeile = objDataSet.Tables("t_Kunden").NewRow()
   With objZeile
      .Item("Vorname") = txtVorname.Text
      .Item("Zuname") = txtZuname.Text
      .Item("Straße") = txtStraße.Text
      .Item("Plz") = txtPLZ.Text
      .Item("Ort") = txtOrt.Text
      .Item("Infopost") = chkInfopost.Checked
      If radFrau.Checked = True Then
         .Item("Geschlecht") = 1
      Else
         .Item("Geschlecht") = 2
      End If
   End With
   objDataSet.Tables("t_Kunden").Rows.Add(objZeile)
   objDataAdapter.Update(objDataSet, "t_Kunden")
End Sub
Abbildung

Abbildung 9.23   Der neue Datensatz wird angefügt.

Wichtig ist dabei, dass der Datensatz nicht nur an das DataSet angefügt wird, sondern dass das DataSet in die Datenbank zurückgeschrieben wird. Dies könnte im Ereignis des Schließens geschehen oder direkt nachdem der Benutzer auf den Button geklickt hat. Der Befehl Update verlangt ein DataSet und den Namen der Tabelle, in welche die Daten geschrieben werden:

objDataAdapter.Update(objDataSet, "t_Kunden")

Analog hierzu funktioniert das Verändern eines Datensatzes:

Private Sub butÄndern_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
butÄndern.Click
   Dim dblPos As Double
   dblPos = Me.BindingContext(objDataView).Position
   With objDataSet.Tables("t_Kunden").Rows(dblPos)
      .Item("Vorname") = txtVorname.Text
      .Item("Zuname") = txtZuname.Text
      .Item("Straße") = txtStraße.Text
      .Item("Plz") = txtPLZ.Text
      .Item("Ort") = txtOrt.Text
      .Item("Infopost") = chkInfopost.Checked
      If radFrau.Checked = True Then
         .Item("Geschlecht") = 1
      Else
         .Item("Geschlecht") = 2
      End If
   End With
   objDataAdapter.Update(objDataSet, "t_Kunden")
End Sub

Und das Löschen einer Zeile erledigt die Methode Delete:

Private Sub butLÖschen_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles butLÖschen.Click
   objDataSet.Tables("t_Kunden").Rows(2).Delete()
   objDataAdapter.Update(objDataSet, "t_Kunden")
End Sub
Abbildung

Abbildung 9.24   Ein Datensatz wurde gelöscht.

Ein DataSet verwaltet also die Beziehungen (Relations) und die Tabellen (Tables). Im obigen Beispiel hätte ich auch eine Tabelle vom Typ DataTable deklarieren und sie entsprechend füllen können:

Dim objTabelle As DataTable = objDataSet.Tables("t_Kunden")
objZeile = objTabelle.NewRow()
...

Sie verfügt über folgende Eigenschaften und Methoden:

Tabelle 9.5   Die wichtigsten Eigenschaften und Methoden der Tabelle
Eigenschaft/Methode Beschreibung
AcceptChanges schreibt Änderungen, die an Datensätzen vorgenommen wurden, in das DataSet
Clear löscht alle Daten
Columns die Auflistung der Spalten
Rows die Auflistung der Zeilen
DataSet das DataSet, zu dem die Tabelle gehört
NewRow erstellt eine neue DataRow
Reset setzt die Tabelle auf den ursprünglichen Zustand zurück
PrimaryKey der Primärschlüssel (kann gelesen oder geschrieben werden)
TableName der Name der Tabelle

Auch die Zeile (DataRow) verfügt über eine Vielzahl von Methoden und einige Eigenschaften:

Tabelle 9.6   Die wichtigsten Eigenschaften und Methoden der DataRow
Eigenschaft/Methode Beschreibung
AcceptChanges übernimmt die Änderungen
BeginEdit, EndEdit, CancelEdit beginnt, beendet und unterbricht einen Editiervorgang. Dies ist wichtig, wenn mehrere Benutzer auf eine Tabelle zugreifen
Delete löscht die Zeile
Item ruft die Daten einer Spalte ab oder legt sie fest

Vielleicht mag die Überschrift dieses Unterkapitels »ungebundene Formulare« etwas irritieren, aber gezeigt werden soll in diesem Abschnitt, wie auf eine Datenbank zugegriffen wird und bestimmte Informationen herausgelöst werden. Dem Benutzer wird ein Formular zur Suche bestimmter Datensätze zur Verfügung gestellt. In ein Textfeld (txtSuche) gibt er beispielsweise den zu suchenden Zunamen ein. Wird er in der Datenbank gefunden, dann wird er angezeigt.

Abbildung

Abbildung 9.25   Ein einfaches Suchformular

Dem Suchen liegt folgender Gedanke zugrunde: Zuerst wird das DataView-Objekt nach dem Kriterium sortiert und anschließend wird in der Spalte, in der zuvor sortiert wurde, gesucht. Die zentralen Befehle sehen wie folgt aus:

Dim intIndex As Integer
strSuchText = Me.txtSuche.Text
objDataView.Sort = "Zuname"
intIndex = objDataView.Find(strSuchText)
Me.BindingContext(objDataView).Position = intIndex

Das genügt. Das Formular wird noch ein wenig verfeinert, indem zu Beginn alle Steuerelemente – bis auf die für die Suche erforderlichen – weggeblendet werden. Nach erfolgreicher Suche werden sie angezeigt.

Abbildung

Abbildung 9.26   Gesucht ...

Abbildung

Abbildung 9.27   ... und gefunden

Der Code beim Laden sieht folgendermaßen aus (zugegeben: man könnte die Eigenschaften auch hart einstellen):

Dim ctl As Control
For Each ctl In Me.Controls
   If ctl.Name.StartsWith("txt") = True Or _
      ctl.Name.StartsWith("lbl") = True Then
      ctl.Visible = False
   End If
Next
Me.chkInfopost.Visible = False
Me.txtSuche.Visible = True
End Sub

Der Code, mit dem die Steuerelemente sichtbar gemacht werden:

Dim ctl As Control
For Each ctl In Me.Controls
   ctl.Visible = True
Next

Was geschieht nun aber, wenn kein Datensatz gefunden wurde, der dem Suchkriterium entspricht? Oder was passiert, wenn mehrere Datensätze gefunden werden? Diese beiden Fälle sollten abgefangen werden. Der erste Fall – kein Datensatz wurde gefunden – ist relativ einfach. Es wird eine Variable objZeilen() vom Typ DataRowView als Array deklariert. Ihr werden alle gefundenen Zeilen übergeben. Ist ihre Anzahl = 0, dann wurde nichts gefunden:

Private Sub butSuchen_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles butSuchen.Click
   Dim objZeilen() As DataRowView
   strSuchText = Me.txtSuche.Text
   objDataView.Sort = "Zuname"
   objZeilen = objDataView.FindRows(strSuchText)
   If objZeilen.Length = 0 Then
      MessageBox.Show("Sorry, kein " & _
      strSuchText & " vorhanden.")
      Me.txtSuche.Text = ""
      Me.txtSuche.Select()
Abbildung

Abbildung 9.28   Nicht jeder wird in meiner Datenbank gefunden.

Beträgt die Anzahl der gefundenen Datensätze 1 oder mehr als 1, dann wird die erste Position angesprungen. Mit einem Filter (RowFilter) können alle gültigen Datensätze selektiert werden. Davon wird der erste ausgewählt:

Else
   Dim intIndex As Integer
   Me.BindingContext(objDataView).Position = 0
   objDataView.RowFilter = "Zuname = '" & strSuchText & "'"
   Me.BindingContext(objDataView).Position = 0

Und wie geht es weiter? Ist die Anzahl größer als 1, dann erscheint ein Button »butWeitersuchen«, der mit dem Text »Weitersuchen« beschriftet ist:

   Dim ctl As Control
   For Each ctl In Me.Controls
      ctl.Visible = True
   Next
   If objZeilen.Length > 1 Then
      Me.butWeitersuchen.Visible = True
   Else
      Me.butWeitersuchen.Visible = False
   End If

Hinter dem Steuerelement steckt lediglich der Befehl, mit dem die Position des DataView-Objekts um 1 erhöht wird:

Private Sub butWeitersuchen_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles butWeitersuchen.Click
   Dim ctl As Control
   objDataView.RowFilter = "Zuname = '" & strSuchText & "'"
   Me.BindingContext(objDataView).Position += 1

   For Each ctl In Me.Controls
      ctl.Visible = True
   Next
End Sub

Nun hätte der Benutzer die Möglichkeit, den Suchtext zwischen »Suchen« und »Weitersuchen« zu ändern. Damit er nach einer solchen Änderung nicht weitersuchen kann, wird dieser Button wieder unsichtbar:

Private Sub txtSuche_TextChanged(ByVal sender As Object, ByVal e 
As System.EventArgs) Handles txtSuche.TextChanged
Me.butWeitersuchen.Visible = False
End Sub

Und schließlich sollte zu Beginn jeder Prozedur ein mögliches Filterkriterium ausgeschaltet werden:

objDataView.RowFilter = ""

Damit ist ein einfacher Suchmechanismus implementiert.

Abbildung

Abbildung 9.29   Der erste gefundene Datensatz

Abbildung

Abbildung 9.30   Es gibt so viele »Martins« auf dieser Welt ...

 

  

VB.NET

Einstieg in ASP.NET

Einstieg in C#

Visual C#

VB.NET und Datenbanken

Einstieg in XML