none
Datenbank bei Visual Basic-Windows Forms speichern und importieren

Answers

  • Hallo,

    schau Dir für den Anfang vielleicht mal die Videos an:
    http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#formsoverdata

    Gruß Elmar

    Tuesday, April 13, 2010 7:30 AM
    Answerer
  • Hallo,

    durch Deine Anforderung in der Ausgangsfrage verbietet sich das eine oder andere.
    Man kann zwar Daten in einer ausführbaren Datei ablegen, und sie z. B. als Ressource
    abrufen, siehe Assembly.GetManifestResourceStream

    Was man aber nicht kann, wäre Daten in der EXE wieder zu speichern.
    Und genausowenig sollte man Daten im Anwendungsverzeichnis speichern,
    denn dort hat ein normaler Anwender in der Regel keinen Zugriff.

    Speichern solltest Du jegliche veränderlichen DAten in den vorgesehen Verzeichnissen,
    die über die SpecialFolder-Enumeration und Environment.GetFolderPath

    Für Daten, die für alle Benutzer gleich sind wäre ApplicationCommonData
    und für Daten die bei jedem Benutzer unterschiedlich sind ApplicationData.
    Für Windows Forms Anwendungen erhälst Du den Pfad + Produkt + Version
    über Application.CommonAppDataPath bzw. UserAppDataPath

    Unter der Voraussetzung Du fügst Deinem Projekt die Datei als eingebettete Ressource
    bereit, könntest Du etwas machen wie:

      Const DatasetName As String = "Tabelle.xml" ' Name der Datei oder der Ressource
      Friend ReadOnly Property DatasetFileName As String
        Get
          Return System.IO.Path.Combine(Application.CommonAppDataPath, DatasetName)
        End Get
      End Property
    
      Public Function LoadDataSet() As DataSet
        Dim dataSet As New DataSet()
        Dim dataStream As System.IO.Stream = Nothing
        Try
          ' Datei verwenden, wenn vorhanden
          If File.Exists(DatasetFileName) Then
            dataStream = New FileStream(DatasetFileName, FileMode.Open, FileAccess.Read, FileShare.Read)
          Else
            ' sonst aus Ressource initialisieren
            dataStream = System.Reflection.Assembly.GetExecutingAssembly(). _
              GetManifestResourceStream(Me.GetType(), DatasetName)
          End If
    
          If dataStream IsNot Nothing Then
            dataSet.ReadXml(dataStream, XmlReadMode.ReadSchema)
          End If
    
        Catch ex As Exception
          Debug.WriteLine(String.Format("Fehler beim Einlesen: {0}", ex.Message))
        Finally
          If dataStream IsNot Nothing Then
            dataStream.Close()
          End If
        End Try
        ' Nur zum Testen
        For Each table As DataTable In dataSet.Tables
          Debug.WriteLine(String.Format("Tabelle: {0} => {1}", table.TableName, table.Rows.Count))
        Next
    
        Return dataSet
      End Function
    
      Public Sub SaveDataSet(ByVal dataset As DataSet)
        dataset.WriteXml(DatasetFileName, XmlWriteMode.WriteSchema)
      End Sub
    

    Ich habe im Beispiel ein DataSet und Xml verwendet,
    es kann sich dabei um beliebige andere "Datenbanken" und anderes handeln,
    z. B. eine Jet/Access MDB.

    Gruß Elmar

    Sunday, April 18, 2010 3:47 PM
    Answerer
  • Es gibt schon jemand, der da etwas weiß, nur kostet eine schnelle Reaktion auch etwas Geld. Kostenlos geht das nur nach der Arbeit in der Freizeit. Und das dauert etwas länger :-)

    Die einfachste variante ist, die Daten in einer Liste eigener Datenobjekte zu speichern und diese Liste dann zum Programmende zu serialisieren. Beim Programmstart wird wieder deserialisiert. Wo die serialisierten Daten abgelegt werden ist eine davon unabhängige Sache. Wenn die entsprechenden Zugriffsrechte vorliegen ist auch eine Speicherung des serialisierten Datenstromes möglich.

    --
    Peter

    Thursday, April 08, 2010 6:23 PM
  • Hier mal eine ganz einfache Demo zu deiner Frage. Datenpuffer ist ein DataTable-Objekt. Die Daten werden beim Programmstart geladen und zu Programmende abgespeichert (als XML).

    Public Class Form1
    
      Private datei As String = "c:\temp\x.xml"
      Dim dt As New DataTable("Tab1")
      Private bs As New BindingSource(dt, "")
      Private dgv As New DataGridView With {.Dock = DockStyle.Fill, _
                                            .DataSource = bs}
    
      Private Sub Form1_Load(ByVal sender As System.Object, _
                             ByVal e As System.EventArgs) _
                             Handles MyBase.Load
        ' Steuerelemente
        Me.Controls.AddRange(New Control() {dgv})
        ' Daten laden
        With dt.Columns
          .Add("Wert1", GetType(String))
          .Add("Wert2", GetType(String))
        End With
        If IO.File.Exists(datei) Then dt.ReadXml(datei)
      End Sub
    
      Private Sub Form1_FormClosing(ByVal sender As Object, _
                                    ByVal e As FormClosingEventArgs) _
                                    Handles Me.FormClosing
        dt.WriteXml(datei)
      End Sub
    
    End Class
    --
    Peter
    Monday, April 12, 2010 6:01 PM

All replies

  • Nagut, wenn da keiner was weiß, ich habe mich mal etwas schlau gemacht und kann diese nun in eine datei speichern, durch das so ganannte "DataGridView" jedoch möchte ich jetzt die Daten im Internet speichern und wieder in das Programm laden...

    Wie geht das?

    Thursday, April 08, 2010 12:12 PM
  • Es gibt schon jemand, der da etwas weiß, nur kostet eine schnelle Reaktion auch etwas Geld. Kostenlos geht das nur nach der Arbeit in der Freizeit. Und das dauert etwas länger :-)

    Die einfachste variante ist, die Daten in einer Liste eigener Datenobjekte zu speichern und diese Liste dann zum Programmende zu serialisieren. Beim Programmstart wird wieder deserialisiert. Wo die serialisierten Daten abgelegt werden ist eine davon unabhängige Sache. Wenn die entsprechenden Zugriffsrechte vorliegen ist auch eine Speicherung des serialisierten Datenstromes möglich.

    --
    Peter

    Thursday, April 08, 2010 6:23 PM
  • Hallo MaSch0212,

    Hat Dir die Antwort geholfen?

    Grüße,
    Robert

    Monday, April 12, 2010 2:19 PM
    Owner
  • Ja doch schon, aber wie funktioniert das? :-)

    Ich meine, wie man Daten speichern kann (in eine Tabelle) über eine TextBox

    Sorry, ich habe erst vor kurzem angefangen zu programmieren.

    Monday, April 12, 2010 3:30 PM
  • Hier mal eine ganz einfache Demo zu deiner Frage. Datenpuffer ist ein DataTable-Objekt. Die Daten werden beim Programmstart geladen und zu Programmende abgespeichert (als XML).

    Public Class Form1
    
      Private datei As String = "c:\temp\x.xml"
      Dim dt As New DataTable("Tab1")
      Private bs As New BindingSource(dt, "")
      Private dgv As New DataGridView With {.Dock = DockStyle.Fill, _
                                            .DataSource = bs}
    
      Private Sub Form1_Load(ByVal sender As System.Object, _
                             ByVal e As System.EventArgs) _
                             Handles MyBase.Load
        ' Steuerelemente
        Me.Controls.AddRange(New Control() {dgv})
        ' Daten laden
        With dt.Columns
          .Add("Wert1", GetType(String))
          .Add("Wert2", GetType(String))
        End With
        If IO.File.Exists(datei) Then dt.ReadXml(datei)
      End Sub
    
      Private Sub Form1_FormClosing(ByVal sender As Object, _
                                    ByVal e As FormClosingEventArgs) _
                                    Handles Me.FormClosing
        dt.WriteXml(datei)
      End Sub
    
    End Class
    --
    Peter
    Monday, April 12, 2010 6:01 PM
  • Hallo,

    schau Dir für den Anfang vielleicht mal die Videos an:
    http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#formsoverdata

    Gruß Elmar

    Tuesday, April 13, 2010 7:30 AM
    Answerer
  • Hallo MaSch0212,

    Ich gehe davon aus, dass die Antworten Dir weitergeholfen haben.

    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,

    Robert

    Tuesday, April 13, 2010 2:26 PM
    Owner
  • Hallo alle zusammen,

    eure Antworten waren wirklich klasse, aber ich glaube, dass ihr mich da falsch verstanden habt, da ich eigentlich vor hatte eine Datenbank in der EXE-Datei zu haben, also dass ich keine andere Datei brauche, sondern nur die EXE.

    Wenn das nicht geht, würde ich gerne wissen, wie man das einrichtet, dass das Programm die Datenbank immer aus dem Ordner nimmt, wo es gerade drin ist.

    Danke nochmal

    Sunday, April 18, 2010 2:25 PM
  • Hallo,

    das wird nicht funktionieren. In einem Assembly können zwar Ressourcen eingebettet werden, diese sind aber nur zum Lesen vorgesehen und können zur Laufzeit nicht ohne weiteres geändert werden. Theoretisch könntest Du hier auch eine Datenbank einbetten, jedoch müsstest Du diese zur Laufzeit zunächst im Dateisystem speichern, damit Du mit den üblichen Datenzugriffsmethoden darauf zugreifen kannst. Mit einer XML basierten Lösung könnte dieser Zwischenschritt natürlich entfallen.

    Bleibt das Problem, dass Du die Änderungen nicht speichern kannst. Dieses ist unabhängig davon, dass Du die Ressourcen im Assembly nicht ändern kannst, es hängt auch mit den Verzeichnisrechten zusammen, die normale Benutzer unter einem aktuellen Betriebssystem haben. Diese dürfen im Programmverzeichnis keine Änderungen vornehmen und somit scheidet auch Deine Alternative aus, die Datenbank in dem Programmverzeichnis abzulegen.

    Windows sieht für die Ablage von programmbezogenen Daten besondere Verzeichnisse vor, die entweder benutzerspezifisch ausgelegt sind oder für alle Benutzer des Rechners gültig sind. Bei letzteren wäre wieder die Anpassung der Datei/Verzeichnisrechte vom Ersteller notwendig, wenn alle Benutzer in die Datenbank schreiben müssen. Diese speziellen Verzeichnisse kannst Du über Environment.GetFolderPath ermitteln. Als mögliche Verzeichnisse kämen hier Environment.SpecialFolder.ApplicationData für benutzerbezogene Anwendungsdaten oder Environment.SpecialFolder.CommonApplicationData für alle Benutzer des Rechners.


    Thorsten Dörfler
    Microsoft MVP Visual Basic
    Sunday, April 18, 2010 3:17 PM
    Moderator
  • Hallo,

    durch Deine Anforderung in der Ausgangsfrage verbietet sich das eine oder andere.
    Man kann zwar Daten in einer ausführbaren Datei ablegen, und sie z. B. als Ressource
    abrufen, siehe Assembly.GetManifestResourceStream

    Was man aber nicht kann, wäre Daten in der EXE wieder zu speichern.
    Und genausowenig sollte man Daten im Anwendungsverzeichnis speichern,
    denn dort hat ein normaler Anwender in der Regel keinen Zugriff.

    Speichern solltest Du jegliche veränderlichen DAten in den vorgesehen Verzeichnissen,
    die über die SpecialFolder-Enumeration und Environment.GetFolderPath

    Für Daten, die für alle Benutzer gleich sind wäre ApplicationCommonData
    und für Daten die bei jedem Benutzer unterschiedlich sind ApplicationData.
    Für Windows Forms Anwendungen erhälst Du den Pfad + Produkt + Version
    über Application.CommonAppDataPath bzw. UserAppDataPath

    Unter der Voraussetzung Du fügst Deinem Projekt die Datei als eingebettete Ressource
    bereit, könntest Du etwas machen wie:

      Const DatasetName As String = "Tabelle.xml" ' Name der Datei oder der Ressource
      Friend ReadOnly Property DatasetFileName As String
        Get
          Return System.IO.Path.Combine(Application.CommonAppDataPath, DatasetName)
        End Get
      End Property
    
      Public Function LoadDataSet() As DataSet
        Dim dataSet As New DataSet()
        Dim dataStream As System.IO.Stream = Nothing
        Try
          ' Datei verwenden, wenn vorhanden
          If File.Exists(DatasetFileName) Then
            dataStream = New FileStream(DatasetFileName, FileMode.Open, FileAccess.Read, FileShare.Read)
          Else
            ' sonst aus Ressource initialisieren
            dataStream = System.Reflection.Assembly.GetExecutingAssembly(). _
              GetManifestResourceStream(Me.GetType(), DatasetName)
          End If
    
          If dataStream IsNot Nothing Then
            dataSet.ReadXml(dataStream, XmlReadMode.ReadSchema)
          End If
    
        Catch ex As Exception
          Debug.WriteLine(String.Format("Fehler beim Einlesen: {0}", ex.Message))
        Finally
          If dataStream IsNot Nothing Then
            dataStream.Close()
          End If
        End Try
        ' Nur zum Testen
        For Each table As DataTable In dataSet.Tables
          Debug.WriteLine(String.Format("Tabelle: {0} => {1}", table.TableName, table.Rows.Count))
        Next
    
        Return dataSet
      End Function
    
      Public Sub SaveDataSet(ByVal dataset As DataSet)
        dataset.WriteXml(DatasetFileName, XmlWriteMode.WriteSchema)
      End Sub
    

    Ich habe im Beispiel ein DataSet und Xml verwendet,
    es kann sich dabei um beliebige andere "Datenbanken" und anderes handeln,
    z. B. eine Jet/Access MDB.

    Gruß Elmar

    Sunday, April 18, 2010 3:47 PM
    Answerer
  • Hallo,

    danke für eure vielen Antworten.
    Das ist ja etwas blöd, dass das mit der internen Datenbank nicht funktioniert, aber ihr habt mir dafür eine Alternative gezeigt.

     

    Monday, April 19, 2010 5:42 PM