Dzisiejszy tutorial jest specjalnie dla osoby która napisała do mnie ostatnio maila o treści:
Witam serdecznie,
Mam prośbę, czy była by możliwość stworzenia turtiala z małym
programikiem? Bo ja znam tylko podstawy VB i próbowałem coś takiego
stworzyć, ale nie za bardzo mi się udało 🙁 A taki turtial pomoże mi to
ogarnąć.Chodzi mi o taki projekt:
Są dwa przyciski przycisk pierwszy „pobierz dane” i przycisk drugi
zapisz dane.
Pierwszy przycisk łączy się z bazą danych SQL (rozszerzenie MDF) pobiera
dane z tabeli np.”ARTYKUŁ” i tabele którą pobierze, żeby podsumowało w
tabeli przestawnej i wybrało kolumny np. „Numer produktu” i „Dostępność”
(Działanie takie jak w Excelu w Menu „Projektowanie” „Podsumuj w tabeli
przest.”).
Natomiast drugi przycisk, żeby zapisał podsumowaną tabele przestawną do
pliku CSV (kodowanie UTF-8, separator teksu średnik).Proszę o pomoc
Czekam na szybą odpowiedź
Pozdrawiam
po krótkiej wymianie maili okazało się, że programik jest bardzo prosty (jak dla mnie) a jeśli ktoś coś ciekawego nauczy się z mojego tutoriala to będę naprawdę zadowolony. Postaram się opisać co i jak.
Zaczynamy standardowo od rozpoczęcia nowego projektu, ja wrzuciłem do niego trzy elementy „Button” jeden element „Label” i jeden element „DataGridView” (tam jest jeszcze textbox ale prosze go zignorować).
Wszystko nazwałem i ładnie poukładałem.
Nasz program będzie działał następująco:
1. Przyciskamy przycisk „Połącz”.
2.Dostajemy informacje o udanym bądź nieudanym połączeniu a nasz Panel (lampka) zmienia kolor na zielony co oznacza, że połączenie jest otwarte.
3. Przyciskamy przycisk opcjonalnie:
a). „Pokaż” nasza tabela będzie ukazana w DatagridView.
b). „Eksportuj” nasza tabela o konkretnym kodzie SQL będzie zapisana.
Zaczynamy od połączenia. Przechodzimy do kodu nasze głównej formy ( Ctrl+Alt+0) i wpisujemy powyżej „Public Class Form1”
1 2 3 |
Imports System.Data.SqlClient Public Class Form1 |
Jeśli nasz „System.Data.SqlClient” świeci się na zielono to trzeba będzie dodać Odwołanie. Robimy to następująco: Po prawej stronie wybieramy „My Project”
Z lewej strony wybieramy „Odwołanie” i „Dodaj”
Potrzebny plik *.dll znajduje się w folderze
C:\Program Files\MySQL\MySQL Connector Net 6.6.2\Assemblies\v4.0
tak jak na obrazku poniżej:
Przyciskamy „OK” i zielony kolor powinien zniknąć. Następnym etapem będzie ustawienie danych do połączenia, u mnie wyglądało to tak:
1 2 3 4 |
Public Class Form1 Dim ServerString As String = "Data Source=BP2\SQLEXPRESS2;Initial Catalog=Artykuly;Persist Security Info=True;User ID=sa;Password=123456" Dim SQLConnection As SqlConnection = New SqlConnection |
Jeśli nie znamy danych służących do połączenia z bazą danych przechodzimy do „Eksporator bazy danych” po lewej stronie:
Wybieramy na górze „Łączenie z bazą danych” (taka wtyczka z plusikiem) pojawi nam się okno konfiguracji:
Wypełniamy ją Wybierając Od góry rodzaj połączenia, bazę danych, login, hasło i tabele. Testujemy połączenie, jeśli wszystko zostało dobrze wypełnione powinien pojawić się komunikat o udanym teście jeśli nie to cóż trzeba coś poprawić. Jeśli wszystko poszło dobrze wciskamy „OK” i wybieramy naszą bazę w „Eksplorator baz danych” w prawym dolnym rogu powinny znajdować się właściwości naszej bazy danych i formuła do połączenia:
Wystarczy ja skopiować i zastąpić moją swoją. Wracamy do projektora i dwukrotnie przyciskamy przycisk „Połącz”, program powinien przejść do kodu i utworzyć nam łączenie z naszym przyciskiem:
1 2 3 4 5 6 7 8 9 10 11 12 |
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click SQLConnection.ConnectionString = ServerString Try If SQLConnection.State = ConnectionState.Closed Then SQLConnection.Open() MsgBox("udalo sie polaczyc") Panel1.BackColor = Color.Green End If Catch ex As Exception MsgBox(ex.ToString) End Try End Sub |
Co tu dużo pisać inicjujemy połączenie do naszego obiektu „ServerString” wcześniej utworzonego a potem program sprawdza, jeśli połączenie jest zamknięte wtedy je otwiera (czyli łączy sie z bazą danych) wywala wiadomość, że wszystko się udało i zmienia kolor panel1 na zielony jeśli nie wywali komunikat, o błędzie.
Wygląda to mniej więcej tak
Teraz możemy odpalić nasz program i zobaczyć czy działa łączenie.
Teraz wprowadzimy sobie opcje przerzutu tabeli do „DataGridView”. W naszym DataGridView dodajemy cztery kolumny (Moja baza danych ma Pięć elementów:
ale wyświetlić chce tylko cztery):
Mamy przygotowane podłoże na naszą tabele. Teraz należy skomponować formułę SQL. Jeśli nie mamy pojęcia jak to zrobić, kierujemy wzrok na lewą stronę monitora i otwieramy „Źródła Danych” i wybieramy „Dodaj nowe źródło danych” podłączamy naszą bazę danych. Po podłączeniu wracamy do „Źródła Danych” i wybieramy „Edytuj obiekty Dataset przy pomocy projektanta”:
Jeśli ktoś będzie miał wielkie z tym problemy zapraszam do przeczytania jakiegoś wcześniejszego tutoriala. Wybieramy konfiguruj:
Konstruktor zapytań:
Następnie otworzy nam się okno w którym możemy testować swoje zapytania:
Na potrzeby tego tutoriala moje zapytanieSql będzie takie:
1 2 3 |
SELECT Nazwa, IndeksKatalogowy, SUM(StanDostepny) AS StanDostepny, SUM(Zamowiono) AS Zamowiono FROM Table_Artykuly GROUP BY IndeksKatalogowy, Nazwa |
Kopiujemy sobie tą formułe. Wracamy do projektanta. Przyciskamy dwukrotnie przycisk „Pokaż” na naszej Formie co powoduje przejście do kodu i utworzenie Suba Button2.
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 |
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim cmd1 As New SqlCommand Dim ada As SqlDataAdapter Dim table As DataTable Try cmd1.Connection = SqlConnection ada = New SqlDataAdapter("SELECT Nazwa, IndeksKatalogowy, SUM(StanDostepny) AS StanDostepny, SUM(Zamowiono) AS Zamowiono FROM Table_Artykuly GROUP BY IndeksKatalogowy, Nazwa", SQLConnection) table = New DataTable ada.Fill(table) DataGridView1.AutoGenerateColumns = False DataGridView1.Columns(0).Name = "Nazwa" DataGridView1.Columns(0).HeaderText = "Nazwa" DataGridView1.Columns(0).DataPropertyName = "Nazwa" DataGridView1.Columns(1).Name = "IndeksKatalogowy" DataGridView1.Columns(1).HeaderText = "IndeksKatalogowy" DataGridView1.Columns(1).DataPropertyName = "IndeksKatalogowy" DataGridView1.Columns(2).Name = "StanDostepny" DataGridView1.Columns(2).HeaderText = "StanDostepny" DataGridView1.Columns(2).DataPropertyName = "StanDostepny" DataGridView1.Columns(3).Name = "Zamowiono" DataGridView1.Columns(3).HeaderText = "Zamowiono" DataGridView1.Columns(3).DataPropertyName = "Zamowiono" DataGridView1.DataSource = table Catch ex As Exception MsgBox(ex.ToString) End Try End Sub |
Najpierw inicjujemy potrzebne na zmienne:
1 2 3 |
Dim cmd1 As New SqlCommand 'rodzaj połączenia Dim ada As SqlDataAdapter 'nasza formuła sql Dim table As DataTable 'tabela potrzebna do wypełnienia danymi |
następnie jeśli połączenie jest otwarte:
1 |
cmd1.Connection = SqlConnection |
formuła powinna nawiązać z nią połączenie
1 2 |
table = New DataTable ada.Fill(table) |
wypełniamy tabele.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
DataGridView1.AutoGenerateColumns = False DataGridView1.Columns(0).Name = "Nazwa" DataGridView1.Columns(0).HeaderText = "Nazwa" DataGridView1.Columns(0).DataPropertyName = "Nazwa" DataGridView1.Columns(1).Name = "IndeksKatalogowy" DataGridView1.Columns(1).HeaderText = "IndeksKatalogowy" DataGridView1.Columns(1).DataPropertyName = "IndeksKatalogowy" DataGridView1.Columns(2).Name = "StanDostepny" DataGridView1.Columns(2).HeaderText = "StanDostepny" DataGridView1.Columns(2).DataPropertyName = "StanDostepny" DataGridView1.Columns(3).Name = "Zamowiono" DataGridView1.Columns(3).HeaderText = "Zamowiono" DataGridView1.Columns(3).DataPropertyName = "Zamowiono" DataGridView1.DataSource = table |
Wypełniamy nasz DataGridView. Najistotniejsza formuła w kodzie powyżej to:
1 |
DataGridView1.Columns().DataPropertyName = "" |
Ponieważ przenosi nam nasze dane do DatagridView na podstawie ich nazwy, tzn jeśli w formuleSql mam nazwę kolumny „Zamowiono” to najpierw określam do której kolumny chce te dane przesłać a potem jak nazywa się ta kolumna. trzeba pamiętać, że kolumny liczone są od 0 i, że taka forma przeniesienia danych nie utworzy nam nowych kolumn tak więc jeśli w formule Sql mamy cztery kolumny a w DataGridView tylko trzy może to powodować wystąpienie błędu więc najlepiej pisać zapytanieSql z głową ale jeśli jakieś dane jak „ID” są wymagane a nie potrzebne można je zaimportować do kolumny a „visible” kolumny ustawić na „false”. u mnie wyglądało to tak:
Jeśli wpisaliście kod i pozmienialiście go prawidłowo czyli dodaliście nowe kolumny tak aby pasowały do waszej bazy danych wszystko jest cacy odpalamy program i testujemy.
Teraz czas na eksport bazy do *.csv
Wracamy do projektanta i dodajemy „Open File dialog”:
Przenosimy go na naszą forme.
W lewym dolnym rogu pojawi się ikonka „OpenFileDialog1”.
Teraz przechodzimy do kodowania. Musimy napisać funkcje która będzie naszą tabele zamieniała na plik tekstowy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Private Sub data_to_txt(ByVal dt As DataTable, ByVal filename As String) Dim sw As New IO.StreamWriter(filename, False) If dt.Columns.Count < 0 OrElse dt.Rows.Count < 0 Then 'Pętla na wypadek przedwczesnego przyciśnięcia eksportu MsgBox("Sprawdź połączenie") Exit Sub End If For row As Integer = 0 To dt.Rows.Count - 1 For col As Integer = 0 To dt.Columns.Count - 1 sw.Write(dt.Rows(row).Item(col).ToString & ",") Next sw.Write(Environment.NewLine) Next sw.Close() End Sub |
W miejscu:
1 |
sw.Write(dt.Rows(row).Item(col).ToString & ",") |
Mamy opcje separatora, w tym wypadku naszym separatorem jest „,” jeśli chcemy aby to była jakaś specjalna formuła np: Tab wpisujemy w tym miejscu „ControlChars.Tab” więcej danych można znaleść w internecie. Jeśli chcecie zobaczyć przykład zapraszam tutaj.
Teraz wystarczy wrócić do naszego projektanta i przycisnąć dwukrotnie przycisk „Eksportuj” a jego Suba wypelniamy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Dim cmd1 As New SqlCommand Dim ada As SqlDataAdapter Dim table As DataTable Dim sfd As New SaveFileDialog With sfd .FileName = "nowa" .Filter = "Text File|*.csv" End With If sfd.ShowDialog = Windows.Forms.DialogResult.OK Then cmd1.Connection = SQLConnection ada = New SqlDataAdapter("SELECT Nazwa, IndeksKatalogowy, SUM(StanDostepny) AS StanDostepny, SUM(Zamowiono) AS Zamowiono FROM Table_Artykuly GROUP BY IndeksKatalogowy, Nazwa", SQLConnection) table = New DataTable ada.Fill(table) Call data_to_txt(table, sfd.FileName) End If |
Robimy to samo co wcześniej z importem do DatagridView, inicjujemy takie same zmienne i wypełniamy je danymi. Używamy OpenFileDialog aby określić lokalizacje zapisu pliku, jego nazwę i rozszerzenie wypełniamy tabele danymi a następnie tą tabele wykorzystujemy w funkcji „data_to_txt” Wygląda to tak:
Na podstawie tego napisałem program dodając Textboxy aby każdy kto go odpali mógł połączyć się ze swoją bazą danych i wpisać własne zapytanie SQL wygląda to tak:
Odwolania do textboxów są proste więc każdy powinien skapnąć się co jest grane.
Jeśli chcemy dodać nagłówki kolumn należy do naszej funkcji data_to_txt dodać pętle
1 2 3 4 5 |
For Each col As DataColumn In dt.Columns sw.Write(col.Caption + ",") Next sw.WriteLine() |
Całość będzie wyglądać tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Private Sub data_to_txt(ByVal dt As DataTable, ByVal filename As String) Dim sw As New IO.StreamWriter(filename, False) If dt.Columns.Count < 0 OrElse dt.Rows.Count < 0 Then 'Pętla na wypadek przedwczesnego przyciśnięcia eksportu MsgBox("Sprawdź połączenie") Exit Sub End If For Each col As DataColumn In dt.Columns sw.Write(col.Caption + ",") Next sw.WriteLine() For row As Integer = 0 To dt.Rows.Count - 1 For col As Integer = 0 To dt.Columns.Count - 1 sw.Write(dt.Rows(row).Item(col).ToString & ",") Next sw.Write(Environment.NewLine) Next sw.Close() End Sub |
Do pobrania tutaj: GrupowanieTabeli