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.













