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:
1 2 3 4 5 |
Imports System.Data.SqlClient Public Class Form1 (...) End Class |
Teraz muszę stworzyć połączenie:
1 2 3 4 5 6 7 8 |
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:
1 2 3 4 5 6 7 8 9 10 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
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:
1 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
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.