Visual S. Forms. Praca z plikami CSV. Dodanie wpisu (sprawdzenie czy istnieje)

1

Cześć,

Uczę się sam i robię mały programik na swoje potrzeby.
Poszukuję rozwiązanie (bo moje nie działa) które usprawni mi dodawanie nowych wpisów do pliku csv. Obecnie wpis dodaje się, jednak jeśli już taki jest to powiela mimo wszystko.
Stworzyłem Class Serwery_Model
wczytuję do listy i chciałbym aby aplikacja przed dodaniem wpisu sprawdziła czy np SN jest już na liście czy nie. Jeśli jest to komunikat, jeśli nie to dodaje.

Mój kod wygląda tak:

private void Dodaj_Click(object sender, EventArgs e)
        {
            using (var reader = new StreamReader("Serwery.csv", true))
            using (var csvread = new CsvReader(reader, CultureInfo.InvariantCulture))
            
            {

                var records = csvread.GetRecords<Serwery_Model>().ToList();
                reader.Close();

                bool zawiera = records.Contains(new Serwery_Model { SN = SnAdd.Text });
                if (zawiera)
                {
                    MessageBox.Show("Serwer jest już w bazie");
                }
                else
                {
                    var records4 = new List<Serwery_Model>
                      {
                          new Serwery_Model {  Szafa = SzafaAdd.Text, Nazwa = NazwaAdd.Text, Model = ModelAdd.Text, SN = SnAdd.Text, U = UAdd.Text, Odcinek = OdcinekAdd.Text },

                      };

                    CsvConfiguration config = new CsvConfiguration(CultureInfo.InvariantCulture)
                    {
                        HasHeaderRecord = false
                    };

                    using (var writer = new StreamWriter("Serwery.csv", true))
                    using (var csv = new CsvWriter(writer, config))
                    {
                        csv.WriteRecords(records4);
                    }                       
                }

            }
     
            button3_Click(sender, e);


        }

Czy ktoś mógłby jakoś pomóc?

Ta funkcja mimo wszystko dodaje nowy wpis do pliku.

2

@Licznasiebie KM:

Już od samego tytułu mi sie nie podoba. Musisz nauczyć się dzielić problemy, wydzielać. Odczyt i przetwarzanie CSV nie ma nic wspólnego z Windows Forms.

Drugie, to ten fragment jest w (najgorszym sensie) w stylu proceduralnym. Dwa otwarcia, skutki uboczne, przynajmniej dwa razy powoływany kontener .... ... brrr... nawet nie chce mi się analizować. Cokolwiek się tu dzieje pozytywnie, jest niemal przypadkiem.
Nazwy zmiennych są absolutnie przypadkowe, nie ułatwiają czytania.

MSZ powinieneś założyć czystą klasę - kontener na Serwery_Model, z której w metodzie add/dodaj nie będzie wyskakiwał Messagebox a throw new Exception("Komunikat"), tam zapewnisz reguły unikalności itd

1

Nie działa ci bo to co masz w tej liście i to co tworzysz przez new to są dwa różne obiekty. Coś takiego może:

bool zawiera = records.FirstOrDefault(o=> o.SN == SnAdd.Text) ?? false : true;
0

@ZrobieDobrze:

Przepraszam za złe sformułowanie tematu.

Przepraszam za tak fatalny kod.

Widzę że lepiej nie brać się za coś, o czym nie ma się pojęcia. Nie dla mnie :)

Ps. @kzkzg

Ta propozycja niestety nie działa, ale tak jak napisał @ZrobieDobrze cały kod jest fatalny.

Dzięki za dobre chęci.

3

@Licznasiebie KM:

Wymyśl klasę "kontener na Server_model", określ jakich metod będzie potrzebował (add() już ci podpowiedziałem), zaimplementuj.
nawet naiwne programowanie obiektowe raczej będzie lepsze od tego.

A druga , to sposób myślenia. Myślowe wydzielanie zagadnień węższych z ogólnych jest wiodące. To nie przyjdzie od ręki, ale trzeba dążyć.

0
ZrobieDobrze napisał(a):

@Licznasiebie KM:

Wymyśl klasę "kontener na Server_model", określ jakich metod będzie potrzebował (add() już ci podpowiedziałem), zaimplementuj.
nawet naiwne programowanie obiektowe raczej będzie lepsze od tego.

A druga , to sposób myślenia. Myślowe wydzielanie zagadnień węższych z ogólnych jest wiodące. To nie przyjdzie od ręki, ale trzeba dążyć.

Dziękuję, będę próbował. Nie jestem orłem z tego co widać po moim kodzie.

Musiałem to przegryźć i w sumie nie wiem do końca czy dobrze myślę jak to zrobić, bo przyznam się nie wiem.

Zrozumiałem że mam stworzyć 2 klasy. Tzn jedną już mam która odczytuje dane czyli Serwery_Model, druga klasa to np. Serwery_Model_add (w której określę metody dodania nowego wpisu)

Później daję if (serwery_Model{SN} == Serwery_Model_add{SN}) { }?? tzn coś takiego podobnego? czy źle myślę?

serio nie znam się i wszystko co pisałem, robiłem na poradnikach czy przykładach znalezionych w necie, nie wszystko jestem w stanie znaleźć i kombinuję (jak widać troszkę źle :))

1
Licznasiebie KM napisał(a):

Zrozumiałem że mam stworzyć 2 klasy. Tzn jedną już mam która odczytuje dane czyli Serwery_Model, druga klasa to np. Serwery_Model_add (w której określę metody dodania nowego wpisu)

Nieeee ....

Klasa danych Serwery_model ok, tu nie ma długiej dyskusji (pasuje rzeczownik liczby pojedynczej)
Ale druga to pojemnik, kontener NA w/w. Nazwa (gdyby po polsku, co nie ejst oczywiste, ale podaję dla wyobrażenia sobie) SpisSerwerów, ListaSerwerów, InwentaryzacjaSerwerów
I nazwa klasy nie kończy się na "add", tylko add / dodaj to metoda. Niestey bez doczytania teorii się nie uda,

nazwa jest ważna, jak się wlezie w programowanie obiektowe. Ma oddawać co to naprawdę jest. NA tym etapie możesz myśleć o klasach jako o rzeczownikach, a o metodach jako czasownikach.
I ma uwierać jak wrzód, jeśli będzie naginana poza pierwotny projekt, np KoszykJabłek gdyby do niego dodawać Pomarańcze

Drugie, to klasa ma enkapsulować, zamykać to, co jest wewnątz. Np jednym z pomysłów na metodę add() jest pozwolenie jej zadecydować autonomicznie, czy już ma, czy nie ma ...

PojemnijNaSerwery pns = new PojemnijNaSerwery();
...
bool rezultat = pns.add(serwer);
if(rezultat ) ... pozytywne, dodano
1
Licznasiebie KM napisał(a):

serio nie znam się i wszystko co pisałem, robiłem na poradnikach czy przykładach znalezionych w necie, nie wszystko jestem w stanie znaleźć i kombinuję (jak widać troszkę źle :))

Nie wiem, jakiego kursu / poradnika używasz.
Ale coś nie gra.
Zaskakująco dobra znajomość kodowania C# w skali mikro *) i ja jestem zaskoczony, zupełny bak kontaktu z zarysem, elementarzem OOP.

*) chyba że kopia fragment po fragmencie każde z przypadkowego żródła.

.. robiłem na poradnikach czy przykładach znalezionych w necie, nie wszystko jestem w stanie znaleźć

bardzo dziwne, wiedza o programowaniu obiektowym jest powszechnie dostępna, wszędzie. Tylko trzeba ją przejść pod jednym patronatem od początku do końca, a nie skakać (np: kopiując z SO przypadkowe fragmenty). Wg mnie dlatego lepsze są książki, bo mają plan, co więcej, mają wynajętego przez inwestora recenzenta, który powinien odstzrelić najgorsze byki.

0

Czesc,

Czy mogę zrobić tak, że za pomocą listbox ładuje tylko SN z pliku
Listbox.displaymember = "SN"
Tak więc SN mam w listboxie.

Teraz chciałbym porównać czy listbox.displaymember.contains(textbox.text) ?

Tzn Wim że to nie działa, jednak jeśli dodam itemy do listboxa to oczywiście działa.

Nie wiem jak porównać, jeśli dane wczytuje przez datasource.

Znów źle?

Dodatkowo jeśli zrobię:

string seryjne = numerySeryjne.GetItemText(numerySeryjne.SelectedValue);
                bool zawiera = seryjne.Contains(SnAdd.Text);

                    if (zawiera)
                    {
                        MessageBox.Show("Serwer jest juz na liscie");
                    }
                    else
                    {
                        using (var writer = new StreamWriter("Serwery.csv", true))
                        using (var csv = new CsvWriter(writer, config))
                        {
                            csv.WriteRecords(nowy);
                        }
                            
                    }

Działa, jednak tylko jeśli zaznaczę coś w listboxie.

Chciałbym aby porównało mi ze wszystkimi elementami jakie się tam znajdują bez ich zaznaczenia.

0

Jako że w sumie nie umiem, a chciałbym umieć... to zrobiłem po swojemu. Udało się to rozwiązać w nieco inny sposób. Dodałem do listboxa tylko numery seryjne.

w przycisku dałem jak niżej:

private void Dodaj_Click(object sender, EventArgs e)
        {
            List<Serwery_Model> nowy = new List<Serwery_Model>();
            nowy.Add(new Serwery_Model { Szafa = SzafaAdd.Text, Model = ModelAdd.Text, Nazwa = NazwaAdd.Text, Odcinek = OdcinekAdd.Text, SN = SnAdd.Text, U = UAdd.Text });

            CsvConfiguration config = new CsvConfiguration(CultureInfo.InvariantCulture)
              {
                   HasHeaderRecord = false
              };

                if (SnAdd.Text.Length > 0 && ModelAdd.Text.Length > 0 && NazwaAdd.Text.Length > 0 && SzafaAdd.Text.Length > 0)
                {
                
                int FindSeryjny = numerySeryjne.FindString(SnAdd.Text);
                    numerySeryjne.SelectedIndex = FindSeryjny;

                if (FindSeryjny > 0)
                    {
                        MessageBox.Show("Serwer jest juz na liscie");
                    }
                    else
                    {
                        using (var writer = new StreamWriter("Serwery.csv", true))
                        using (var csv = new CsvWriter(writer, config))
                        {
                            csv.WriteRecords(nowy);
                        }
                            
                    }
                }
                else
                {
                    MessageBox.Show("Podaj Wszystkie dane serwera");
                }

        }

teraz sprawdza czy jest zaznacza na liście i jeśli jest zaznaczony to pokazuje komunikat. Oczywiście nazwa jaką chcę znaleźć musi być wpisana 1:1.

Jeśli bardzo źle to proszę o pomoc i uwagi, ale jak już mówiłem jestem całkiem zielony.

1

FindSeryjny ? A What is Twoje name? Brzmi co najmniej dziwnie prawda? :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1