none
Wiederverwendbare Funktionen RRS feed

  • Frage

  • Hey,

    wie macht man Funktionen die man immer verwenden kann? Also zum Beispiel das Öffnen einer Connection in einer Funktion, sodass ich in allen Subs einfach nur sowas wie "connection.open" eingeben muss und es funktioniert, ohne immer in jeder neuen Sub oder Klasse den Connection String erneut anzugeben und zu deklarieren. Also praktisch etwas was man überall wiederverwenden kann.

    Gruß
    Freitag, 15. Oktober 2010 06:33

Antworten

  • Hallo,

    wie macht man Funktionen die man immer verwenden kann?
    Also zum Beispiel das Öffnen einer Connection in einer Funktion,
    sodass ich in allen Subs einfach nur sowas wie "connection.open"
    eingeben muss und es funktioniert, ohne immer in jeder neuen
    Sub oder Klasse den Connection String erneut anzugeben und
    zu deklarieren.
    Also praktisch etwas was man überall wiederverwenden kann.

    Das mit dem "überall wiederverwenden" ist bei Datenbank-
    funktionalitäten nicht ganz so simpel, sofern der Zugriff auf
    unterschiedliche DB-Systeme erfolgen soll. Angenommen
    Du willst wahlweise auf eine Access.mdb oder auf einen
    SqlServer zugreifen, dann brauchst Du schon mal zwei
    verschiedene Connection-Typen. Für die Access.mdb würdest
    Du eine OleDbConnection nutzen und für den SqlServer
    wäre das eine SqlConnection. Wenn Du Dir die Doku zu
    diesen beiden Connection-Typen ansiehst, wirst Du feststellen,
    dass sie im Connectionstring doch recht unterschiedliche
    Angaben erwarten.

    Eine OleDbConnection benötigt für den Zugriff auf eine Access.mdb
    den vollst. Pfad zur *.mdb und evtl. ein Datenbankpasswort und auch
    noch eine Information darüber, ob die *.mdb exklusiv oder im geteilten
    Modus geöffnet werden soll und evtl. auch noch ob mit Pagelocking oder Recordlocking gearbeitet werden soll. Deine Funktion sollte also diese Informationen als Parameter übernehmen können um daraus den
    passenden Connectionstring zu formen und auch die übrigen
    Eigenschaften der Connection mit den passenden Werten zu versorgen.

    Im Beispiel unter

        www.gssg.de -> Visual Basic -> VB.net
            -> Datenbank
                -> OleDb2 (Access.mdb)

    gibt es ein Klassenmodul mit dem Namen clsDbIO und darin zwei
    Function GetConnection(), die eine unterschiedliche Anzahl an
    Parametern übernehmen können. In beiden Fällen erzeugen diese
    Funcktionen einen Dateidialog, in welchem der Benutzer den
    Pfad zu der von ihm gewünschten *.mdb eingeben kann. Sofern
    diese *.mdb mit einem Passwort geschützt ist, wird der Benutzer in
    einem weiteren Dialog aufgefordert, dieses Passwort einzugeben.

    Für den SqlServer findest Du ebenfalls Beispiele unter

        www.gssg.de -> Visual Basic -> VB.net
            -> Datenbank
                -> SQLserver_00
                -> SQLserver_01
                -> SQLserver_02

    Darin kannst Du Dir ansehen, welche Informationen zum Öffnen
    der jeweiligen SqlConnection benötigt werden und wie daraus
    in einer Funktion ein passender Connectionstring erzeugt wird.

    Die Funktionalität dieser Beispiele solltest Du erst mal verstanden
    haben und dann kann man in einem weiteren Schritt überlegen,
    wie eine Funktion aussehen muss, die wahlweise eine OleDbConnction
    oder eine SqlConnection erstellen und öffnen kann.

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

    Freitag, 15. Oktober 2010 11:07
  • Hallo,

    wie macht man Funktionen die man immer verwenden kann?

    indem man häufig verwendete Funktionalität mit möglichst wenigen Abhängigkeiten kapselt. Wie man das macht, ist aber nicht mit paar Sätzen in einem Forenbeitrag erklärt. Dein Beispiel eignet sich dazu auch nur bedingt, denn dieses lässt sich auch ohne Kapslung bereits stark vereinfachen.

    Also zum Beispiel das Öffnen einer Connection in einer Funktion, sodass ich in allen Subs einfach nur sowas wie "connection.open" eingeben muss und es funktioniert, ohne immer in jeder neuen Sub oder Klasse den Connection String erneut anzugeben und zu deklarieren.

    wenn Du Deinen ConnectionString in den Anwendungseinstellungen (Projekt => Eigenschaften > Einstellungen) definierst, kannst Du diesen überall in der Anwendung über My.Settings.MyConnectionString abfragen. Ändern brauchst Du ihn später nur in den Anwendungseinstellungen (app.settings). Damit reduziert sich Dein Code für das Öffnen einer Connection bereits auf zwei Zeilen:

    Dim lConn As New SqlClient.SqlConnection(My.Settings.MyConnectionString)
    lConn.Open()
    

    + Fehlerbehandlung. Sinniger ist da schon eher, das komplette Handling des Datenzugriffs in Methoden zu kapseln. Nicht unbedingt in Modulen, die das Programm im Laufe der Zeit unübersichtlich machen, sondern in Klassen.

    Als Beispiel ohne Anspruch auf Korrektheit und Vollständigkeit:

    ' DataLayer.vb
    Imports System.Data.SqlClient
    
    Public Class DataLayer
     Public Sub New()
    
     End Sub
    
     Public Sub InsertLogin(ByVal name As String)
      Dim lConn As New SqlConnection(My.Settings.MySqlConnection)
    
      Try
       lConn.Open()
    
       Dim lCommand = New SqlCommand("INSERT INTO Users (Name) VALUES (@name)")
       lCommand.Parameters.Add(New SqlParameter("@name", name))
    
       lCommand.ExecuteNonQuery()
    
      Catch ex As Exception
       Throw New Exception("Insert login failed.", ex)
    
      Finally
       lConn.Close()
    
      End Try
     End Sub
    End Class
    
    ' Form1.vb
    Public Class Form1
     Private Sub Button1_Click(ByVal sender As System.Object, _
                  ByVal e As System.EventArgs _
                     ) Handles Button1.Click
    
      Dim lData As New DataLayer()
      lData.InsertLogin("foo")
    
     End Sub
    End Class
    

    Ähnlich kann man dann auch Methoden aufbauen, die eine Liste aller User als DataTable oder DataSet liefern. Wenn nur ein einzelner Wert aus der Datenbank gelesen werden soll, gibt man gleich den passenden Datentyp zurück. Das nur als grobe "Richtung".


    Thorsten Dörfler
    Microsoft MVP Visual Basic
    vb-faq.de
    Freitag, 15. Oktober 2010 09:55
    Moderator

Alle Antworten

  • Hallo,

    am einfachsten wäre es deine Funktion die die Verbindung mit einer Datenbank herstellt in ein Modul zu packen.

    Funktionen in Modulen sind in der gesamten Anwendung verfügbar und sind automatisch statisch (Shared).

    Du kannst die Funktionen aus dem Modul dann direkt über den Namen der Funktion aufrufen oder den vollqualifizierten Namen benutzen (Modul.Funktion). Ein Import ist nicht nötig.

    Besser wäre es an dieser Stelle vielleicht eine Factory zu benutzen um nicht unnötig viele Connection offen zu haben.

    Hoffe das hilft dir weiter.


    MfG, Sebastian Gross
    Freitag, 15. Oktober 2010 08:44
  • Mehr oder weniger hilft es mir weiter, aber die Umsetzung - daran hakts.

     

    Angenommen mein Connection string ist:    "Provider=wOLEDB;Server=192.999.9.1;uid=user3;pwd=getest;database=SQL2;"

     

    Wie mache ich daraus sowas, dass ich das immer nur via "conn.open()" oder ähnlichen aufrufen kann, ohne es ständig in neuen Subs oder Klassen deklarieren zu müssen?

    Freitag, 15. Oktober 2010 09:13
  • Hallo,

    hier ein Beispiel Anhand von einer MySQL Datenbankverbindung von einem Modul, dass eine Verbindung zurückgibt. Dabei prüft diese ob bereits eine Verbindung offen ist und öffnet bei bedarf eine neue (falls zum ersten Mal gestartet)

     

     

    Module DB
     Dim MySQLConnectionString As String
     Dim MyADOConnection As MySqlConnection
    
     Function GetConnection() As MySqlConnection
      MySQLConnectionString = "Server=myServer;" & _
            "Database=myDatabase;" & _
            "Uid=myUserID;" & _
            "Pwd=myPassword;" & _
            "Connect Timeout=30;"
    
      If(MyADOConnection == Nothing)
       MyADOConnection = New MySqlConnection(MySQLConnectionString)
       MyADOConnection.Open()
      End If
    
      Return MyADOConnection
     End Function
    
    End Module
    

    Aufrufen kannst du diese Funktion von überall aus deinem Programm zb so: 

    Dim con As MySqlConnection = GetConnection()


    MfG, Sebastian Gross
    Freitag, 15. Oktober 2010 09:25
  • Hallo,

    wie macht man Funktionen die man immer verwenden kann?

    indem man häufig verwendete Funktionalität mit möglichst wenigen Abhängigkeiten kapselt. Wie man das macht, ist aber nicht mit paar Sätzen in einem Forenbeitrag erklärt. Dein Beispiel eignet sich dazu auch nur bedingt, denn dieses lässt sich auch ohne Kapslung bereits stark vereinfachen.

    Also zum Beispiel das Öffnen einer Connection in einer Funktion, sodass ich in allen Subs einfach nur sowas wie "connection.open" eingeben muss und es funktioniert, ohne immer in jeder neuen Sub oder Klasse den Connection String erneut anzugeben und zu deklarieren.

    wenn Du Deinen ConnectionString in den Anwendungseinstellungen (Projekt => Eigenschaften > Einstellungen) definierst, kannst Du diesen überall in der Anwendung über My.Settings.MyConnectionString abfragen. Ändern brauchst Du ihn später nur in den Anwendungseinstellungen (app.settings). Damit reduziert sich Dein Code für das Öffnen einer Connection bereits auf zwei Zeilen:

    Dim lConn As New SqlClient.SqlConnection(My.Settings.MyConnectionString)
    lConn.Open()
    

    + Fehlerbehandlung. Sinniger ist da schon eher, das komplette Handling des Datenzugriffs in Methoden zu kapseln. Nicht unbedingt in Modulen, die das Programm im Laufe der Zeit unübersichtlich machen, sondern in Klassen.

    Als Beispiel ohne Anspruch auf Korrektheit und Vollständigkeit:

    ' DataLayer.vb
    Imports System.Data.SqlClient
    
    Public Class DataLayer
     Public Sub New()
    
     End Sub
    
     Public Sub InsertLogin(ByVal name As String)
      Dim lConn As New SqlConnection(My.Settings.MySqlConnection)
    
      Try
       lConn.Open()
    
       Dim lCommand = New SqlCommand("INSERT INTO Users (Name) VALUES (@name)")
       lCommand.Parameters.Add(New SqlParameter("@name", name))
    
       lCommand.ExecuteNonQuery()
    
      Catch ex As Exception
       Throw New Exception("Insert login failed.", ex)
    
      Finally
       lConn.Close()
    
      End Try
     End Sub
    End Class
    
    ' Form1.vb
    Public Class Form1
     Private Sub Button1_Click(ByVal sender As System.Object, _
                  ByVal e As System.EventArgs _
                     ) Handles Button1.Click
    
      Dim lData As New DataLayer()
      lData.InsertLogin("foo")
    
     End Sub
    End Class
    

    Ähnlich kann man dann auch Methoden aufbauen, die eine Liste aller User als DataTable oder DataSet liefern. Wenn nur ein einzelner Wert aus der Datenbank gelesen werden soll, gibt man gleich den passenden Datentyp zurück. Das nur als grobe "Richtung".


    Thorsten Dörfler
    Microsoft MVP Visual Basic
    vb-faq.de
    Freitag, 15. Oktober 2010 09:55
    Moderator
  • Hier sagt er mir Ausdruck erwartet bei dem gleichheitszeichen. Was ist daran falsch bzw, was muss dort hinein?
     If (MyADOConnection == Nothing)
    Freitag, 15. Oktober 2010 09:56
  • Oh das ist mein Fehler, da war ich noch mit einem Gedanken in C# in VB.NET musst du nur ein "=" verwenden statt "=="

    Ich vermute du bist noch ein Anfänger, daher würde ich dir empfehlen dich mit den Grundlagen auseinanderzusetzen.
    Dazu kannst du eins der Kostenlos verfügbaren eBooks lesen wie zb dieses von Microsoft:

    Visual Basic 2008
    http://www.microsoft.com/germany/msdn/aktuell/news/MicrosoftVisualBasic2008DasEntwicklerbuch.mspx

     

    @Thorsten

    Normalerweise versuche ich Module auch zu meiden wo es geht, aber bietet sich in diesem Falle die Verwendung nicht an?
    Wenn man das Ganze in eine Klasse packt wird doch im Endeffekt das Selbe herauskommen (Public Shared) das modul wird ja auch zu einer Klasse kompiliert die dann als Public Shared markiert wird.


    MfG, Sebastian Gross
    Freitag, 15. Oktober 2010 10:00
  • Hallo Sebastian,

    Oh das ist mein Fehler, da war ich noch mit einem Gedanken in C# in VB.NET musst du nur ein "=" verwenden statt "=="

    *mööp* Auch nicht.
    If conn Is Nothing Then
     ...
    End If
    

    Thorsten Dörfler
    Microsoft MVP Visual Basic
    vb-faq.de
    Freitag, 15. Oktober 2010 10:06
    Moderator
  • Hallo,

    wie macht man Funktionen die man immer verwenden kann?
    Also zum Beispiel das Öffnen einer Connection in einer Funktion,
    sodass ich in allen Subs einfach nur sowas wie "connection.open"
    eingeben muss und es funktioniert, ohne immer in jeder neuen
    Sub oder Klasse den Connection String erneut anzugeben und
    zu deklarieren.
    Also praktisch etwas was man überall wiederverwenden kann.

    Das mit dem "überall wiederverwenden" ist bei Datenbank-
    funktionalitäten nicht ganz so simpel, sofern der Zugriff auf
    unterschiedliche DB-Systeme erfolgen soll. Angenommen
    Du willst wahlweise auf eine Access.mdb oder auf einen
    SqlServer zugreifen, dann brauchst Du schon mal zwei
    verschiedene Connection-Typen. Für die Access.mdb würdest
    Du eine OleDbConnection nutzen und für den SqlServer
    wäre das eine SqlConnection. Wenn Du Dir die Doku zu
    diesen beiden Connection-Typen ansiehst, wirst Du feststellen,
    dass sie im Connectionstring doch recht unterschiedliche
    Angaben erwarten.

    Eine OleDbConnection benötigt für den Zugriff auf eine Access.mdb
    den vollst. Pfad zur *.mdb und evtl. ein Datenbankpasswort und auch
    noch eine Information darüber, ob die *.mdb exklusiv oder im geteilten
    Modus geöffnet werden soll und evtl. auch noch ob mit Pagelocking oder Recordlocking gearbeitet werden soll. Deine Funktion sollte also diese Informationen als Parameter übernehmen können um daraus den
    passenden Connectionstring zu formen und auch die übrigen
    Eigenschaften der Connection mit den passenden Werten zu versorgen.

    Im Beispiel unter

        www.gssg.de -> Visual Basic -> VB.net
            -> Datenbank
                -> OleDb2 (Access.mdb)

    gibt es ein Klassenmodul mit dem Namen clsDbIO und darin zwei
    Function GetConnection(), die eine unterschiedliche Anzahl an
    Parametern übernehmen können. In beiden Fällen erzeugen diese
    Funcktionen einen Dateidialog, in welchem der Benutzer den
    Pfad zu der von ihm gewünschten *.mdb eingeben kann. Sofern
    diese *.mdb mit einem Passwort geschützt ist, wird der Benutzer in
    einem weiteren Dialog aufgefordert, dieses Passwort einzugeben.

    Für den SqlServer findest Du ebenfalls Beispiele unter

        www.gssg.de -> Visual Basic -> VB.net
            -> Datenbank
                -> SQLserver_00
                -> SQLserver_01
                -> SQLserver_02

    Darin kannst Du Dir ansehen, welche Informationen zum Öffnen
    der jeweiligen SqlConnection benötigt werden und wie daraus
    in einer Funktion ein passender Connectionstring erzeugt wird.

    Die Funktionalität dieser Beispiele solltest Du erst mal verstanden
    haben und dann kann man in einem weiteren Schritt überlegen,
    wie eine Funktion aussehen muss, die wahlweise eine OleDbConnction
    oder eine SqlConnection erstellen und öffnen kann.

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

    Freitag, 15. Oktober 2010 11:07