import pliku do bazy danych/eksport pliku z bazy danych (update)

Jest to dodatek do artykułu:

https://visualmonsters.cba.pl/index.php/import-pliku-do-bazy-danycheksport-pliku-z-bazy-danych/

Dostałem ostatnio pytanie, czy mógłbym opisać jak dane pobrane z zewnątrz wpisać do bazy danych. Będziemy bazować na projekcie z tamtego przykładu. Pobiera on dane tylko do podglądu w DatagridView. Prośba polegała na tym, aby opisać metodę dodawania danych pobranych z pliku do bazy danych. Jako iż nie mam takiej bazy danych jak na przykładzie, muszę dodać ją lokalnie i pokażę wam dwa sposoby takiej operacji.

Dodaje lokalną bazę danych:

Dodaje tabele i jej pola rozwijając zakładkę eksploratora serwerów:

Teraz utworzę tabelę taką jak na obrazku:

Uwaga, jeśli korzystacie z mojego przykładu, pamiętajcie, aby ustawić wiersz „Id” na „IDENTITY” aby automatycznie się aktualizował, w innym wypadku będziemy musieli aktualizować go ręcznie. Kiedy wypełnimy już wszystkie pola, wciskamy „Update” i gotowe. Zmieniłem trochę wygląd głównego okna programu:

Nic specjalnego, dodałem dwa przyciski i tabelę z dodanymi już kolumnami. Pierwsza kolumna wyświetli automatycznie tworzony id a druga jeden z dodanych elementów (Nr pr). Jeśli wszystko pójdzie dobrze, na początku nasza baza danych będzie pusta, a po imporcie i dodaniu do tabeli elementów będzie wypełniona danymi. Ja dodałem lokalną bazę danych, ten element może się różnić w zależności od tego, jaką bazę danych wykorzystujemy, czy to jest baza danych MSSQL, Oracle, OLEDB czy co tam macie. Należy zaimportować odpowiedni składnik. Ja korzystam z bazy danych *.mdf, czyli muszę zaimportować składnik:

Imports System.Data.SqlClient

Public Class Form1
(...)
End Class

Teraz muszę stworzyć połączenie:

Imports System.Data.SqlClient

Public Class Form1

    Private connectionSQL As New SqlConnection("Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\db.mdf;MultipleActiveResultSets=True;Integrated Security=True;Connect Timeout=180")

(...)
End Class

Gdzie (Data Source=(LocalDB)\MSSQLLocalDB) oznacza rodzaj bazy danych a (AttachDbFilename=|DataDirectory|\db.mdf) jej lokalizację, reszta elementów ma różnorakie znaczenie. Jeśli ich nie dodamy, będą ustawione automatycznie. Ja je dodałem, aby pokazać wam, że coś tam jeszcze jest co można edytować. Najpierw sprawdzimy sobie, czy nasze połączenie hula:

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'Otwieramy połączenie z bazą danych, jeśli wszystko podłączone jest prawidłowo 
        ' nie powinien pojawić się zaden komunikat
        Try
            connectionSQL.Open()
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
        connectionSQL.Close()
    End Sub

Jeśli wszystko działa, to nasza aplikacja po prostu się włączy, jeśli coś jest nie tak, wtedy dostaniemy komunikat o błędzie. Teraz gdy mamy już gotowe połączenie, należy dodać uchwyt do przycisku „Dodaj dane do bazy danych”. Doda on dane do bazy danych.

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        If DataGridView1.Rows.Count > 0 Then
            'otwieramy połączenie z bazą danych
            connectionSQL.Open()
            For i As Integer = 0 To DataGridView1.Rows.Count - 1
                'dla każdego wiersza w podglądzie
                'tworzymy zmienne
                'takie jak w tabeli
                Dim nr_pr As String = DataGridView1.Rows(i).Cells(0).Value
                Dim data As String = DataGridView1.Rows(i).Cells(1).Value
                Dim p1 As Boolean = DataGridView1.Rows(i).Cells(2).Value
                Dim p2 As Boolean = DataGridView1.Rows(i).Cells(3).Value
                Dim p3 As Boolean = DataGridView1.Rows(i).Cells(4).Value
                Dim p4 As Boolean = DataGridView1.Rows(i).Cells(5).Value
                'tworzymy komęde SQL wypełniającą dane
                Dim cmd As New SqlCommand("INSERT INTO [Table] ([Nr pr], data, p1, p2, p3, p4)  VALUES ('" & nr_pr & "','" & data & "','" & p1 & "','" & p2 & "','" & p3 & "','" & p4 & "')", connectionSQL)
                Dim da As SqlDataAdapter = New SqlDataAdapter()
                da.InsertCommand = cmd
                Try
                    'realizujemy komende
                    da.InsertCommand.ExecuteNonQuery()
                    'jeśli udałą się dodać dane wtedy pierwsza komurka podglądu podświetli się na zielono
                    DataGridView1.Rows(i).Cells(0).Style.BackColor = Color.GreenYellow
                Catch ex As Exception
                    'jeśli operacja się nie udała, bo np. druga kolumna ma więcej znaków niż przeznaczyliśmy na nie w tabeli
                    'wtedy zapali się na czerwono
                    'np data ma nchart(19), jesli pobrane dane będą miały 20 wtedy nie uda się dodać danych
                    DataGridView1.Rows(i).Cells(0).Style.BackColor = Color.Tomato
                End Try
            Next
            connectionSQL.Close()
        End If
    End Sub

Tak to będzie wyglądać:

Bez sensu dodawać coś, co nie pasuje, bez sensu również przerywać pętle, aby nie dodać pasujących elementów. Można też zmodyfikować zdarzenie tak, aby dodawać tylko zaznaczone wiersze:

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        If DataGridView1.Rows.Count > 0 Then
            'otwieramy połączenie z bazą danych
            connectionSQL.Open()
            Dim selectedRowCount As Integer = DataGridView1.Rows.GetRowCount(DataGridViewElementStates.Selected)
            Dim i As Integer
            If selectedRowCount > 0 Then
                For d As Integer = 0 To selectedRowCount - 1
                    'dla każdego wiersza w podglądzie
                    'tworzymy zmienne
                    'takie jak w tabeli
                    i = DataGridView1.SelectedRows(d).Index
                    Dim nr_pr As String = DataGridView1.Rows(i).Cells(0).Value
                    Dim data As String = DataGridView1.Rows(i).Cells(1).Value
                    Dim p1 As Boolean = DataGridView1.Rows(i).Cells(2).Value
                    Dim p2 As Boolean = DataGridView1.Rows(i).Cells(3).Value
                    Dim p3 As Boolean = DataGridView1.Rows(i).Cells(4).Value
                    Dim p4 As Boolean = DataGridView1.Rows(i).Cells(5).Value
                    'tworzymy komęde SQL wypełniającą dane
                    Dim cmd As New SqlCommand("INSERT INTO [Table] ([Nr pr], data, p1, p2, p3, p4)  VALUES ('" & nr_pr & "','" & data & "','" & p1 & "','" & p2 & "','" & p3 & "','" & p4 & "')", connectionSQL)
                    Dim da As SqlDataAdapter = New SqlDataAdapter()
                    da.InsertCommand = cmd
                    Try
                        'realizujemy komende
                        da.InsertCommand.ExecuteNonQuery()
                        'jeśli udałą się dodać dane wtedy pierwsza komurka podglądu podświetli się na zielono
                        DataGridView1.Rows(i).Cells(0).Style.BackColor = Color.GreenYellow
                    Catch ex As Exception
                        'jeśli operacja się nie udała, bo np. druga kolumna ma więcej znaków niż przeznaczyliśmy na nie w tabeli
                        'wtedy zapali się na czerwono
                        'np data ma nchart(19), jesli pobrane dane będą miały 20 wtedy nie uda się dodać danych
                        DataGridView1.Rows(i).Cells(0).Style.BackColor = Color.Tomato
                    End Try
                Next
            End If

            connectionSQL.Close()
        End If
    End Sub

Efektem będzie dodanie tylko zaznaczonych wierszy:

Dobra teraz został ostatni przycisk, który wyświetli zaimportowane elementy. Abyśmy wiedzieli, że coś tam zostało dodane do bazy danych. tak jak na obrazku powyżej. Będzie on realizował zapytanie tak jak przycisk dodający elementy:

    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        'otwieramy połączenie z bazą danych
        connectionSQL.Open()
        Dim cmd_read_id As New SqlCommand
        Dim dat As SqlDataReader
        'tworzymy zapytanie sql 
        Dim querry As String = "select Id, [Nr pr]  from [Table]"
        cmd_read_id = New SqlCommand(querry, connectionSQL)
        dat = cmd_read_id.ExecuteReader
        'realizujemy zapytanie
        If dat.HasRows Then
            While dat.Read()
                'dodajemy wiersz
                DataGridView2.Rows.Add()
                'dodajemy dane
                DataGridView2.Rows(DataGridView2.Rows.Count - 1).Cells(0).Value = dat.Item(0)
                DataGridView2.Rows(DataGridView2.Rows.Count - 1).Cells(1).Value = dat.Item(1)
            End While
        Else
            MsgBox("wystapil problem, lub twoja baza danych jest pusta.")
        End If
        'zamykamy polaczenie
        connectionSQL.Close()
    End Sub
End Class

Jeśli nie podoba nam się kolejność dodawania zaznaczonych elementów, można przekształcić pętle:

For d As Integer = selectedRowCount - 1 To 0 Step -1

 

Elementy będą dodawane wtedy prawidłowo. No i to by było na tyle, jeśli chodzi o ten sposób.

Projekt do pobrania tutaj: Import Eksport plikow (1)


Drugi sposób jest taki bardziej mechaniczny.

Teraz klikamy głównie dalej i wybieramy nazwy i elementy do dodania, wszystko powinno być opisane w kreatorze, więc nie powinno sprawić wam problemów:

Teraz gdy już mamy źródło danych, dodajemy je na formę:

Będziemy na bieżąco podglądać czy wszystko jest ok. Nasza tabela jest chwilowo pusta, ale zaraz to zmienimy. Wracamy do zdarzenia dla przycisku dodającego elementy do bazy danych. Powyższe elementy robimy po to aby pozyskać „TableBindingSource” i „TableTableAdapter” które wykorzystamy do pracy. Nie będzie to skomplikowane.

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        If DataGridView1.Rows.Count > 0 Then
            For i As Integer = 0 To DataGridView1.Rows.Count - 1
                'dla każdego wiersza w podglądzie
                'tworzymy zmienne
                'takie jak w tabeli
                Dim nr_pr As String = DataGridView1.Rows(i).Cells(0).Value
                Dim data As String = DataGridView1.Rows(i).Cells(1).Value
                Dim p1 As Boolean = DataGridView1.Rows(i).Cells(2).Value
                Dim p2 As Boolean = DataGridView1.Rows(i).Cells(3).Value
                Dim p3 As Boolean = DataGridView1.Rows(i).Cells(4).Value
                Dim p4 As Boolean = DataGridView1.Rows(i).Cells(5).Value
                'dodajemy wiersz do BindingSource
                Dim row = DirectCast(TableBindingSource.AddNew(), DataRowView)
                Try
                    'przypisujemy mu wartości
                    row.Item(1) = nr_pr
                    row.Item(2) = data
                    row.Item(3) = p1
                    row.Item(4) = p2
                    row.Item(5) = p3
                    row.Item(6) = p4
                    'kończymy edycje, jeśli coś poszlo nie tak to właśnie tutaj
                    TableBindingSource.EndEdit()
                    DataGridView1.Rows(i).Cells(0).Style.BackColor = Color.GreenYellow
                Catch ex As Exception
                    'usuwamy wiersz nad którym pracowaliśmy
                    TableBindingSource.RemoveCurrent()
                    'jeśli operacja się nie udała, bo np. druga kolumna ma więcej znaków niż przeznaczyliśmy na nie w tabeli
                    'wtedy zapali się na czerwono
                    'np data ma nchart(19), jesli pobrane dane będą miały 20 wtedy nie uda się dodać danych
                    DataGridView1.Rows(i).Cells(0).Style.BackColor = Color.Tomato
                End Try
            Next
            'jak już zaktualizujemy BindingSource wtedy wszystko zapisujemy
            TableTableAdapter.Update(Me.DbDataSet.Table)
        End If
    End Sub

Kod dodający tylko wybrane wiersze:

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        If DataGridView1.Rows.Count > 0 Then
            Dim selectedRowCount As Integer = DataGridView1.Rows.GetRowCount(DataGridViewElementStates.Selected)
            Dim i As Integer
            If selectedRowCount > 0 Then
                For d As Integer = 0 To selectedRowCount - 1
                    'dla każdego wiersza w podglądzie
                    'tworzymy zmienne
                    'takie jak w tabeli
                    i = DataGridView1.SelectedRows(d).Index
                    Dim nr_pr As String = DataGridView1.Rows(i).Cells(0).Value
                    Dim data As String = DataGridView1.Rows(i).Cells(1).Value
                    Dim p1 As Boolean = DataGridView1.Rows(i).Cells(2).Value
                    Dim p2 As Boolean = DataGridView1.Rows(i).Cells(3).Value
                    Dim p3 As Boolean = DataGridView1.Rows(i).Cells(4).Value
                    Dim p4 As Boolean = DataGridView1.Rows(i).Cells(5).Value
                    'dodajemy wiersz do BindingSource
                    Dim row = DirectCast(TableBindingSource.AddNew(), DataRowView)
                    Try
                        'przypisujemy mu wartości
                        row.Item(1) = nr_pr
                        row.Item(2) = data
                        row.Item(3) = p1
                        row.Item(4) = p2
                        row.Item(5) = p3
                        row.Item(6) = p4
                        'kończymy edycje, jeśli coś poszlo nie tak to właśnie tutaj
                        TableBindingSource.EndEdit()
                        DataGridView1.Rows(i).Cells(0).Style.BackColor = Color.GreenYellow
                    Catch ex As Exception
                        'usuwamy wiersz nad którym pracowaliśmy
                        TableBindingSource.RemoveCurrent()
                        'jeśli operacja się nie udała, bo np. druga kolumna ma więcej znaków niż przeznaczyliśmy na nie w tabeli
                        'wtedy zapali się na czerwono
                        'np data ma nchart(19), jesli pobrane dane będą miały 20 wtedy nie uda się dodać danych
                        DataGridView1.Rows(i).Cells(0).Style.BackColor = Color.Tomato
                    End Try
                Next
                'jak już zaktualizujemy BindingSource wtedy wszystko zapisujemy
                TableTableAdapter.Update(Me.DbDataSet.Table)
            End If
        End If
    End Sub

Wygląda to tak:

Jak zmienić kolejność dodawania zaznaczonych wierszy, podawałem w pierwszym przykładzie. Pełen projekt do pobrania tutaj: Import Eksport plikow (2)

Na koniec taka jeszcze uwaga dla was, podczas budowania aplikacji z lokalną bazą danych, baza będzie tworzona na nowo. Tak więc po zbudowaniu bazy danych, jeśli chcemy zachować elementy bazy danych utworzone w czasie tworzenia aplikacji, należy ją skopiować z folderu „(…)\Import Eksport plikow\WindowsApplication3\WindowsApplication3\bin” i z tego folderu uruchamiać aplikację, ponieważ będzie ona nadpisywana nową. Można również odłączyć ją po pierwszym utworzeniu w opcjach projektu (tylko jeśli już jest utworzona):

Jeśli nadal baza danych będzie się nadpisywała, skopiuj ją i plik log gdzieś w bezpieczne miejsce.

 

 

Permalink do tego artykułu: https://visualmonsters.cba.pl/import-danycheksport-update/

Dodaj komentarz

Twój adres email nie będzie publikowany.