Parikon

Użytkownik forum
  • Postów

    355
  • Dołączył

  • Ostatnia wizyta

  • Wygrane w rankingu

    19

Treść opublikowana przez Parikon

  1. PI 2019 MIT Edition składa się już z dwóch plików dll. Drugi to dll-ka startowa, której uruchomienie, ładuje także plik skala_zw.dll. Wykorzystałem tutaj wiedzę zdobytą na tym forum. Kod dll-ki startowej https://github.com/Parikon/start_zw/blob/master/start_zw/Start.cs
  2. Tutaj jest kod na licencji MIT modułu skala https://github.com/Parikon/skala_zw http://przybornik.parikon.pl/programy/2-skala
  3. Cały aktualny kod na Github. https://github.com/Parikon/projekt_forum/tree/master/proj_forum
  4. @perlon przetestowałem trochę kod i zasadniczo tak jak mówiłeś catch (Exception ex) pozostawiłem tylko w klasie MainWindow. Teraz utworzyłem taka metodę w klasie Base public DataTable PobierzDaneTabeli(string nazwa_tabeli) { var dt = new DataTable(); this.db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "select * from "+ nazwa_tabeli +""; db_cmd.ExecuteNonQuery(); SQLiteDataAdapter da = new SQLiteDataAdapter(db_cmd); da.Fill(dt); this.db_con.Close(); return dt; } W klasie MainWindow dodałem public MainWindow() { InitializeComponent(); //zamykamy pewne funkcjonalności, gdyż musielibyśmy inaczej oprogramować obiekt DataGrid, a tego nie potrafię datagrid_projekt_lista.CanUserAddRows = false; datagrid_projekt_lista.CanUserDeleteRows = false; datagrid_projekt_lista.IsReadOnly = true; } oraz private void Window_Loaded(object sender, RoutedEventArgs e) { try { //path = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath; path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location)); var baza = new Base(path); baza.AddBaseIfNotExist(); if (baza.GetBaseVersion() != 1) { // tutaj dałbym konwerter na starej bazy na nową, ale narazie nie mamy takiego konwertera więc program tego nie zrobi MessageBox.Show("Nieprawidłowa wersja bazy. Konwersja niemożliwa w tej wersji programu.Nastąpi zamknięcie programu", "Projekty-info"); this.Close(); } DataTable tablicaprojektow = baza.PobierzDaneTabeli("projekt_lista"); datagrid_projekt_lista.ItemsSource = tablicaprojektow.DefaultView; } catch (Exception ex) { MessageBox.Show(ex.Message + ". Program zostanie zamknięty.", "Projekty-info"); this.Close(); } } Jak widać AddBaseIfNotexist() nie zwraca tak jak proponowałeś żadnej wartości
  5. Mój PI tak samo się zachował. Zatem moduł sztucznej inteligencji w PI i BeStCAD działa na podobnym poziomie. 😉
  6. public partial class MainWindow : Window { string path; jeśli skasujesz to string path
  7. @Perlon, program, nie być może, a na pewno, można napisać na wiele sposobów. Coś bardziej skomplikowanego niż jedno zdanie może być niepowtarzalne. Zatem proszę o konkrety. Bo na razie podajesz inne rozwiązania robiące w zasadzie to samo. Dlaczego long a nie int? Jakie jest poważne uzasadnienie zamiany. itp. 😉 Podaję co mam: <Window x:Name="main" x:Class="projekty.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:projekty" mc:Ignorable="d" Title="Lista projektów" Height="450" Width="800" Loaded="Window_Loaded"> <Grid> <TabControl > <TabItem Header="Baza"> <TabItem.Background> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFF0F0F0" Offset="0"/> <GradientStop Color="#FF424B56" Offset="1"/> </LinearGradientBrush> </TabItem.Background> <Grid Background="#FF424B56"> <Button x:Name="button_dodaj" Content="Dodaj" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Foreground="White" BorderBrush="White"> <Button.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="White" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="button_zmien" Content="Zmień" HorizontalAlignment="Left" Margin="90,10,0,0" VerticalAlignment="Top" Width="75" Foreground="White" BorderBrush="White"> <Button.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="White" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="button_usun" Content="Usuń" HorizontalAlignment="Left" Margin="170,10,0,0" VerticalAlignment="Top" Width="75" Foreground="White" BorderBrush="White"> <Button.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="White" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="button_aktualny" Content="Aktualny" HorizontalAlignment="Left" Margin="250,10,0,0" VerticalAlignment="Top" Width="75" Foreground="White" BorderBrush="White"> <Button.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="White" Offset="1"/> </LinearGradientBrush> </Button.Background> </Button> <DataGrid x:Name="datagrid_projekt_lista" Margin="10,60,10,10"/> <Label Content="Tabela :" HorizontalAlignment="Left" Margin="10,35,0,0" VerticalAlignment="Top" Foreground="White"/> </Grid> </TabItem> <TabItem Header="INFO"> <TabItem.Background> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFF0F0F0" Offset="0"/> <GradientStop Color="#FF424B56" Offset="1"/> </LinearGradientBrush> </TabItem.Background> <Grid Background="#FF424B56"> <Label Content="Program oparto na silniku bazy danych SQLite - www.sqlite.org. " HorizontalAlignment="Left" Margin="8,7,0,0" VerticalAlignment="Top" Foreground="White"/> </Grid> </TabItem> </TabControl> </Grid> </Window> namespace projekty { class Base { // zmienna path nie jest potrzebna w zadnej z metod // można ją spokojnie przenieść do konstruktora jako zmienną prywatną // ale może się przyda więc zostaje private string path; // do połączenia wystarczy db_con ustawiony raz w konstruktorze private SQLiteConnection db_con; /// <summary> /// Konstruktor klasy. Pobiera ścieżkę do bazy. /// </summary> /// <param name="_path"></param> public Base(string _path) { this.path = _path + "\\Bazy"; string sciezkaBaza = this.path + "\\projekty.sqlite"; this.db_con = new SQLiteConnection($"Data Source = {sciezkaBaza}; Version = 3"); } public interface IBase { bool AddBaseIfNotExist(); int GetBaseVersion(); } /// <summary> /// Tworzy bazę jeśli nie istnieje i tabelę projekt_lista, jesli coś się nie powiodło zwraca false /// </summary> public bool AddBaseIfNotExist() { bool ok; try { if (!Directory.Exists(this.path)) { Directory.CreateDirectory(this.path); } this.db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS projekt_lista ([Numer projektu] INT, [Nazwa projektu] TEXT, [Data dodania] TEXT, [Data zakończenia] TEXT, [Ścieżka] TEXT)"; db_cmd.ExecuteNonQuery(); db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS wersja_bazy ([Numer wersji] INT)"; db_cmd.ExecuteNonQuery(); this.db_con.Close(); ok = true; } catch (Exception ex) { MessageBox.Show(ex.Message + " 0001", "Projekty-info"); ok = false; } return ok; } public int GetBaseVersion() { int wersja = 1; this.db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "select * from wersja_bazy"; db_cmd.ExecuteNonQuery(); var dt = new DataTable(); SQLiteDataAdapter da = new SQLiteDataAdapter(db_cmd); da.Fill(dt); int wierszy = dt.Rows.Count; if (wierszy == 0) { db_cmd.CommandText = "INSERT INTO wersja_bazy VALUES ('"+ wersja +"')"; db_cmd.ExecuteNonQuery(); this.db_con.Close(); } else { this.db_con.Close(); DataRow dtr = dt.Rows[0]; wersja = Convert.ToInt16(dtr[0]); } return wersja; // metoda zwróci wersję } } } namespace projekty { /// <summary> /// Logika interakcji dla klasy MainWindow.xaml /// </summary> public partial class MainWindow : Window { string path; public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { try { path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location)); var baza = new Base(path); bool results = baza.AddBaseIfNotExist(); if (baza.GetBaseVersion() != 1) { // tutaj dałbym konwerter na starej bazy na nową, ale narazie nie mamy takiego konwertera więc program tego nie zrobi MessageBox.Show("Nieprawidłowa wersja bazy. Konwersja niemożliwa w tej wersji programu.Nastąpi zamknięcie programu", "Projekty-info"); this.Close(); } } catch (Exception ex) { MessageBox.Show(ex.Message + " 0002", "Projekty-info"); this.Close(); } } } }
  8. No właśnie o to mi chodzi. Wyskoczy pierwszy komunikat po kliknięciu ok co? Wywali program zamiast zamknąć bezpiecznie okno. Być może to nie nastąpi, ale nie mam tu pewności. Jeśli chodzi o catch(Exception ex) to przecież właśnie ująłem to co proponowałeś w kodzie zamiast własnego komunikatu.
  9. Czy gdy nie powstanie z jakiś powodów połączenie z bazą, gdyż program jak jej nie będzie, nie będzie jej mógł także utworzyć to po komunikacie Błąd zakładania katalogu z bazą Program wyświetli następny komunikat. MessageBox.Show(ex.Message, "Projekty-info"); Czyli będziemy mieli dwa okna z komunikatami, które trzeba zamknąć. A przecież wystąpienie pierwszego komunikatu powinno już być przesłaniem do zamknięcia programu. public Base(string _path) { this.path = _path + "\\Bazy"; string sciezkaBaza = this.path + "\\projekty.sqlite"; this.db_con = new SQLiteConnection($"Data Source = {sciezkaBaza}; Version = 3"); } public bool AddBaseIfNotExist() { bool ok; try { if (!Directory.Exists(this.path)) { Directory.CreateDirectory(this.path); } this.db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS projekt_lista ([Numer projektu] INT, [Nazwa projektu] TEXT, [Data dodania] TEXT, [Data zakończenia] TEXT, [Ścieżka] TEXT)"; db_cmd.ExecuteNonQuery(); db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS wersja_bazy ([Numer wersji] INT)"; db_cmd.ExecuteNonQuery(); this.db_con.Close(); ok = true; } catch (Exception ex) { MessageBox.Show(ex.Message, "Projekty-info"); ok = false; } return ok; }
  10. W mojej ocenie Twój kod spowoduje to, że za każdym uruchomieniem programu tablica wersja_bazy będzie się rozrastać o jeden dodatkowy rekord. Nie uważasz, że moje obawy są słuszne?
  11. Propozycja dokończenia metody GetBaseVersion(). public int GetBaseVersion() { int wersja = 1; // nasz program tworzy taką wersję string sciezka = this.path + "\\Bazy" + "\\projekty.sqlite"; SQLiteConnection db_con = new SQLiteConnection("Data Source = " + sciezka + "; Version = 3"); db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "select * from wersja_bazy"; db_cmd.ExecuteNonQuery(); var dt = new DataTable(); SQLiteDataAdapter da = new SQLiteDataAdapter(db_cmd); da.Fill(dt); int wierszy = dt.Rows.Count; if (wierszy == 0) { db_cmd.CommandText = "INSERT INTO wersja_bazy VALUES ('1')"; db_cmd.ExecuteNonQuery(); db_con.Close(); } else { DataRow dtr = dt.Rows[0]; wersja = Convert.ToInt16(dtr[0]); db_con.Close(); } return wersja; // metoda zwróci wersję }
  12. Aby było wykorzystane więcej możliwości jakie daje język to skorzystamy z konstruktora tak jak radzi @perlon. Z tego co poczytałem metoda konstruktora musi mieć nazwę identyczną jak nazwa klasy, w której ją tworzymy. namespace projekty { /// <summary> /// Logika interakcji dla klasy MainWindow.xaml /// </summary> public partial class MainWindow : Window { string path; public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location)); var baza = new Base(path); bool results = baza.AddBaseIfNotExist(); if (results != true) { Window.GetWindow(this).Close(); } else if (baza.GetBaseVersion() != 1) { // tutaj dałbym konwerter na starej bazy na nową, ale narazie nie mamy takiego konwertera więc program tego nie zrobi MessageBox.Show("Nieprawidłowa wersja bazy. Konwersja niemożliwa w tej wersji programu.Nastąpi zamknięcie programu", "Projekty-info"); Window.GetWindow(this).Close(); } } } } namespace projekty { class Base { string path; /// <summary> /// Konstruktor klasy. Pobiera ścieżkę do bazy. /// </summary> /// <param name="_path"></param> public Base(string _path) { this.path = _path; } public interface IBase { bool AddBaseIfNotExist(); int GetBaseVersion(); } /// <summary> /// Tworzy bazę jeśli nie istnieje i tabelę projekt_lista, jesli coś się nie powiodło zwraca false /// </summary> public bool AddBaseIfNotExist() { bool ok; try { //wyodrębniamy ściężkę do katalogu i jesli nie istnieje tworzymy katalog Bazy string sciezkaBaza = this.path + "\\Bazy"; if (!Directory.Exists(sciezkaBaza)){Directory.CreateDirectory(sciezkaBaza);} //scieżka do bazy string sciezka = sciezkaBaza + "\\projekty.sqlite"; SQLiteConnection db_con = new SQLiteConnection("Data Source = " + sciezka + "; Version = 3"); //utworzenie tabeli db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS projekt_lista ([Numer projektu] INT, [Nazwa projektu] TEXT, [Data dodania] TEXT, [Data zakończenia] TEXT, [Ścieżka] TEXT)"; db_cmd.ExecuteNonQuery(); db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS wersja_bazy ([Numer wersji] INT)"; db_cmd.ExecuteNonQuery(); db_con.Close(); ok = true; } catch { MessageBox.Show("Nie utworzono bazy. Prawdopodobnie brak możliwości zapisu w katalogu z programem lub brak katalogu Bazy. Program zostanie zamknięty", "Projekty-info"); ok = false; } return ok; } public int GetBaseVersion() { int wersja = 1; // nasz program tworzy taką wersję // tutaj kod, który sprawdzi czy jest rekord, wpisze wersje jesli nie ma rekordu lub odczyta jeśli wersja jest już wpisana (baza już istnieje) return wersja; // metoda zwróci wersję } } }
  13. Nowy kod powinien rozwiązać problem.Chociaż wolałbym stałą path mieć dostępną w klasie Base, ale nie wiem jak to zrobić using System; using System.Collections.Generic; using System.Data; using System.Data.SQLite; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Windows; namespace projekty { class Base { public interface IBase { bool AddBaseIfNotExist(); int GetBaseVersion(); } /// <summary> /// Tworzy bazę jeśli nie istnieje i tabelę projekt_lista, jesli coś się nie powiodło zwraca false /// </summary> public static bool AddBaseIfNotExist(string path) { bool ok; try { //wyodrębniamy ściężkę do katalogu i jesli nie istnieje tworzymy katalog Bazy string sciezkaBaza = path + "\\Bazy"; if (!Directory.Exists(sciezkaBaza)){Directory.CreateDirectory(sciezkaBaza);} //scieżka do bazy string sciezka = sciezkaBaza + "\\projekty.sqlite"; SQLiteConnection db_con = new SQLiteConnection("Data Source = " + sciezka + "; Version = 3"); //utworzenie tabeli db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS projekt_lista ([Numer projektu] INT, [Nazwa projektu] TEXT, [Data dodania] TEXT, [Data zakończenia] TEXT, [Ścieżka] TEXT)"; db_cmd.ExecuteNonQuery(); db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS wersja_bazy ([Numer wersji] INT)"; db_cmd.ExecuteNonQuery(); db_con.Close(); ok = true; } catch { MessageBox.Show("Nie utworzono bazy. Prawdopodobnie brak możliwości zapisu w katalogu z programem lub brak katalogu Bazy. Program zostanie zamknięty", "Projekty-info"); ok = false; } return ok; } public static int GetBaseVersion() { int wersja = 1; // nasz program tworzy taką wersję // tutaj kod, który sprawdzi czy jest rekord, wpisze wersje jesli nie ma rekordu lub odczyta jeśli wersja jest już wpisana (baza już istnieje) return wersja; // metoda zwróci wersję } } } Pobieramy ścieżkę zgodnie z tym co podał @s1016 using System.Data.SQLite; using System.Linq; using System.Reflection; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace projekty { /// <summary> /// Logika interakcji dla klasy MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location)); bool results = Base.AddBaseIfNotExist(path); if (results != true) { Window.GetWindow(this).Close(); } else if (Base.GetBaseVersion() != 1) { // tutaj dałbym konwerter na starej bazy na nową, ale narazie nie mamy takiego konwertera więc program tego nie zrobi MessageBox.Show("Nieprawidłowa wersja bazy. Konwersja niemożliwa w tej wersji programu.Nastąpi zamknięcie programu", "Projekty-info"); Window.GetWindow(this).Close(); } } } } @Perlon już tworzymy całkiem inny kod i jestem z tego bardzo ucieszony. No i jesteśmy w domu. Teraz możemy debugować bezpośrednio w Visual Studio, gdyż to był problem, że debugger nie mógł utworzyć bazy w katalogu bin.
  14. Problem jest prosty do zdiagnozowania: W przypadku gdy jakikolwiek folder w ścieżce będzie miał nazwę ze spacją to program pobiera taki np string jak u mnie: D:/Projekty%20baza/projekty.exe, a w rzeczywistości ścieżka to D:/Projekty baza/projekty.exe. Co się zatem dzieje, że jednak program nie wysypuje się. Ano u mnie po dodaniu kodu sprawdzającego czy jest katalog baza i jeśli nie to utwórz program utworzył bazę i całą ścieżkę D:/Projekty%20baza/Bazy 😉
  15. Musimy wytłumaczyć sobie jedno. Ja tutaj nie chcę, aby kojarzono mnie z jakimś nauczycielem. Chcę tylko pokazać jak ja to zrobiłem, co pokazałem na początku. Ale w zasadzie już odszedłem od schematu, którego musiałbym się trzymać aby dojść do efektu końcowego. Projekt zatem już żyje swoim własnym życiem. Nie korzystałem z interfejsów, a nawet jak gdzieś korzystałem to nie tworzyłem ich w klasach i zapewne jeszcze nie rozumiem ich działania. Ale ok, dodałem to co proponuje kolega. Zasadniczo ten interfejs jest do wyboru. Wygląda to tak: using System.Data.SQLite; using System.Linq; using System.Reflection; using System.Text; using System.Windows; namespace projekty { class Base { public interface IBase { bool AddBaseIfNotExist(); int GetBaseVersion(); } /// <summary> /// Tworzy bazę jeśli nie istnieje i tabelę projekt_lista, jesli coś się nie powiodło zwraca false /// </summary> public static bool AddBaseIfNotExist() { bool ok; try { string path = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath; //wyodrębniamy ściężkę do katalogu i jesli nie istnieje tworzymy naszą bazę string sciezka = System.IO.Path.GetDirectoryName(path) + "\\Bazy" + "\\projekty.sqlite"; SQLiteConnection db_con = new SQLiteConnection("Data Source = " + sciezka + "; Version = 3"); //utworzenie tabeli db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS projekt_lista ([Numer projektu] INT, [Nazwa projektu] TEXT, [Data dodania] TEXT, [Data zakończenia] TEXT, [Ścieżka] TEXT)"; db_cmd.ExecuteNonQuery(); db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS wersja_bazy ([Numer wersji] INT)"; db_cmd.ExecuteNonQuery(); db_con.Close(); ok = true; } catch { MessageBox.Show("Nie utworzono bazy. Prawdopodobnie brak możliwości zapisu w katalogu z programem lub brak katalogu Bazy. Program zostanie zamknięty", "Projekty-info"); ok = false; } return ok; } public static int GetBaseVersion() { int wersja = 1; // nasz program tworzy taką wersję // tutaj kod, który sprawdzi czy jest rekord, wpisze wersje jesli nie ma rekordu lub odczyta jeśli wersja jest już wpisana (baza już istnieje) //przydałoby sie go w końcu napisać return wersja; // metoda zwróci wersję } } } a tutaj MainWindow using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace projekty { /// <summary> /// Logika interakcji dla klasy MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { bool results = Base.AddBaseIfNotExist(); if (results != true) { Window.GetWindow(this).Close(); } else if (Base.GetBaseVersion() != 1) { // tutaj dałbym konwerter ze starej bazy na nową, ale narazie nie mamy takiego konwertera więc program tego nie zrobi oraz nawet nie wiem jakmiałby wyglądać kod MessageBox.Show("Nieprawidłowa wersja bazy. Konwersja niemożliwa w tej wersji programu.Nastąpi zamknięcie programu", "Projekty-info"); Window.GetWindow(this).Close(); } } } }
  16. To chyba już przyda się nowa metoda w klasie Base. Base.CheckBaseVersion(). Sprawdza czy w tabeli wersja_bazy znajduje się rekord. Jeśli nie, to go tworzy w wpisując wartość 1 do kolumny 0, gdyż nasz program tworzy taką wersję bazy. Jeśli rekord się znajduje, to metoda odczytuje wersję bazy jaka tam jest wpisana i ostatecznie zwraca numer wersji.
  17. Trochę inaczej podchodzę do zagadnienia. Nie interesuje mnie wersja programu, gdyż wiele wersji programu może tworzyć tę samą strukturę bazy, czyli inaczej, tę samą wersję bazy. Dlatego jak napisałem wyżej, nasz program oprócz tabeli projekt_lista będzie tworzył tabelę wersja_bazy. Dodatkowo zmieniam naszą własną metodę o nazwie Addbaseifnotexit() w taki sposób, że w przypadku gdy tworzenie się nie powiedzie i program uzna, że nie ma bazy o podanej nazwie lub brak interesujących tabel to metoda zwróci wartość false (fałsz) lub true (prawda). using System; using System.Collections.Generic; using System.Data; using System.Data.SQLite; using System.Linq; using System.Reflection; using System.Text; using System.Windows; namespace projekty { class Base { /// <summary> /// Tworzy bazę jeśli nie istnieje i tabelę projekt_lista, jesli coś się nie powiodło zwraca false /// </summary> public static bool AddBaseifnotexists() { bool ok; try { string path = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath; //wyodrębniamy ściężkę do katalogu i jesli nie istnieje tworzymy naszą bazę string sciezka = System.IO.Path.GetDirectoryName(path) + "\\Bazy" + "\\projekty.sqlite"; SQLiteConnection db_con = new SQLiteConnection("Data Source = " + sciezka + "; Version = 3"); //utworzenie tabeli db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS projekt_lista ([Numer projektu] INT, [Nazwa projektu] TEXT, [Data dodania] TEXT, [Data zakończenia] TEXT, [Ścieżka] TEXT)"; db_cmd.ExecuteNonQuery(); db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS wersja_bazy ([Numer wersji] INT)"; db_cmd.ExecuteNonQuery(); db_con.Close(); ok = true; } catch { MessageBox.Show("Nie utworzono bazy. Prawdopodobnie brak możliwości zapisu w katalogu z programem lub brak katalogu Bazy. Program zostanie zamknięty", "Projekty-info"); ok = false; } return ok; } } } Gdy ten kod się nie powiedzie wyświetli się komunikat i program się nie otworzy. using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace projekty { /// <summary> /// Logika interakcji dla klasy MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { bool results = Base.AddBaseifnotexists(); if (results != true) { Window.GetWindow(this).Close(); } } } }
  18. Wyobrażam sobie, że pierwsza wersja programu ma te kolumny, które będzie tworzyć. Więc nie widzę powodu aby program dodawał kolumny i sprawdzał ile kolumn ma baza i jakie. Co najwyżej możemy dodać tabele o nazwie wersja i w niej jedną kolumnę o nazwie wersja i jeden wiersz z liczbą 1. W przypadku gdybyśmy wypełnili taką prostą bazę, a potem zrobili wersję programu, w której program się rozwinął do większej ilości kolumn i tabel można by robić konwertery danych z danej wersji bazy do wersji jaka tworzy aktualnie program. Natomiast teraz spróbowałem udolnie lub nie wprowadzić inną klasę niż klasę typu Window w której działają wszystkie zdarzenia jakie automatycznie tworzy mi Visul Studio.
  19. Chodziło mi o coś prostszego. Poza tym, nie widzę sensu wrzucać do oddzielnej biblioteki klas class klasy lub metody, która nam będzie tworzyła taką a nie inną tabelę. Musi to być coś bardziej uniwersalnego. Krótkie wyjaśnienie do filmu, który dodam poniżej. Robimy to co pokazałem, ale uwaga, nie debugujemy programu, tylko go na koniec ponownie kompilujemy. Gdybyśmy go debugowali to program w trybie debugowania, nie będzie mógł utworzyć tabeli w ścieżce, którą sam sobie określi jako jego położenie. Widocznie nie ma uprawnień do tego katalogu. Trzeba zatem skopiować całą zawartość katalogu debug do innego katalogu oraz dodać tam folder Bazy, gdyż nasza metoda nie umie tworzyć tego folderu jak go nie ma.
  20. Dzięki za uwagę. Wczoraj właśnie zmieniłem rozszerzenie bazy *.wgb jak to miałem w PI na sql po właczeniu DB Brows... Ale teraz zauważyłem, ze wyświetliło się skrótowo sql, gdyż kontrolka była za krótka, a po jej rozwinięciu jest sqlite. Także ustawmy na sqlite, gdyż w innym przypadku przy otwieraniu bazy tym programem trzeba wyłączyć ustawiony tam filtr wyboru. Co do nazw kolumn to pozostawmy jak jest, będzie bardziej "profesjonalnie" o ile nasz projekt będzie można nazwać profesjonalnym. string path = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath; //wyodrębniamy ściężkę do katalogu i jesli nie istnieje tworzymy naszą bazę string sciezka = System.IO.Path.GetDirectoryName(path) + "\\Bazy" + "\\projekty.sqlite"; SQLiteConnection db_con = new SQLiteConnection("Data Source = " + sciezka + "; Version = 3"); //utworzenie kolumn db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS projekt_lista ([Numer projektu] INT, [Nazwa projektu] TEXT, [Data dodania] TEXT, [Data zakończenia] TEXT, [Ścieżka] TEXT)"; db_cmd.ExecuteNonQuery(); db_con.Close(); Teraz mam pomysł, aby cały ten kod zamknąć w jednej metodzie, przy czym nazwę bazy ustalajmy w metodzie: czyli Metoda (string nazwabazy) {}. Ktoś to ogarnie?
  21. Do tej pory w celu poznania ścieżki do programu używałem takiego kodu using System.Reflection; string path = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath; //wyodrębniamy ściężkę do katalogu i jesli nie istnieje tworzymy naszą bazę string sciezka = System.IO.Path.GetDirectoryName(path) + "\\Bazy" + "\\projekty.sql"; SQLiteConnection db_con = new SQLiteConnection("Data Source = " + sciezka + "; Version = 3"); //utworzenie kolumn db_con.Open(); SQLiteCommand db_cmd = db_con.CreateCommand(); db_cmd.CommandType = CommandType.Text; db_cmd.CommandText = "CREATE TABLE IF NOT EXISTS projekt_lista ([Numer projektu] INT, [Nazwa projektu] TEXT, [Data dodania] TEXT, [Data zakończenia] TEXT, [Ścieżka] TEXT)"; db_cmd.ExecuteNonQuery(); db_con.Close();
  22. Chciałem w tym temacie pokazać jak tworzę własną bazę danych projektów jako aplikację opartą o system bazodanowy SQLite. Wszelkie uwagi są mile widziane oraz pomocne, ale nie chciałbym za bardzo zagłębiać się w szczegóły techniczne, których mogę jako amator nie do końca rozumieć, a bardziej rozwiązywać konkretne zadania. Zróbmy więc może najpierw aplikację WPF, która będzie tworzyć i obsługiwać naszą bazę, a potem, to co uznamy za słuszne przerzucimy do biblioteki klas, którą będzie można używać w rożnych programach. Sprawdzanie działania kodu będzie szybsze.
  23. Nie wiem co się stało, ale po ostatnim poście nie mogę połączyć się z https://forum.cad.info.pl pakiety wysyłane przez moją przeglądarkę grzęzną na serwerach SPRINT-DC-HAWE.net.hawetelecom.pl (77.242.225.94). Zainstalowałem więc operę i po włączeniu vpn problem zniknął.
  24. wstawiłem ten kod do private void UserControl_Loaded(object sender, RoutedEventArgs e) { string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location)); MessageBox.Show(path); } przy czym ponieważ Visual studio podkreślało element Path twierdząc, że nie zna jego rozwinięcia w ten sposób podanego dobrze będzie dodać System.IO przed słowem Path, gdyż Path jest także w innej bibliotece. Teraz gdy skompilujemy naszą dll i uruchomimy w Zwcad otrzymamy komunikat z podaną ścieżką do naszej dll-ki. Scieżka pozwoli na utworzyć bazę właśnie w katalogu z naszym programem a nie w katalogu wpisanym na sztywno do programu. Architektura naszego programu zakłada, że baza będzie tworzono w katalogu zawierającym nasz program. Po sprawdzeniu, że nasz kod zwraca nam string o jaki nam chodzi możemy wyłączyć wyświetlanie wiadomości private void UserControl_Loaded(object sender, RoutedEventArgs e) { string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location)); //MessageBox.Show(path); }
  25. To mały projekt, który mam nadzieję doprowadzimy do końca. Piszę doprowadzimy bo zależy mi na tym abym to nie ja podawał gotowe rozwiązania, tylko abyśmy szukali tych rozwiązań w sieci i dodawali kod do tego projektu. Oczywiście posiadam swoje rozwiązania, które już przetestowałem ale z doświadczenia wiem, że rozwiązań jest wiele a niektóre tak banalne, że co dwie głowy to nie jedna. Dodałem zdarzenie ładowania kontrolki użytkownika Usercontorl1 i teraz potrzebujemy metody, która utworzy bazę danych w katalogu gdzie znajduje się nasza dll-ka. Jak w C# sprawdzić ścieżkę do katalogu gdzie znajduje się dll-ka.? Architektura naszej aplikacji jest prosta jak budowa cepa. Dll-ka z programem znajduje się w jakimś katalogu na dysku. Nasz program musi na początku się zlokalizować.