Filtrowanie liczb z uzyciem 'like'...?

0

Witam
Slowo wstepu: jest baza MSSQL 2008 Express, a w niej tabela ARCH_Archiwum, zawierajaca m.in. kolumne ARCHPESEL typu numeric(11).
Moj progs pokazuje w DataGridView zawartosc tej tabeli, potrafi nawet przyjac zmiany i je do bazy zapisac. Chce dolozyc filtrowanie, wymyslilem sobie ze zrobie to na TextBoxach. I tu przechodzimy do meritum: o ile pieknie to dziala na kolumnach tekstowych, o tyle w przypdaku tej ARCHPESEL - juz nie... Jak zaczynam wpisywac liczbe do TextBoxa - znikaja wszystkie wiersze z DataGridView i dopiero jak wpisany ciag znakow pasuje idealnie do jakiegos rekordu - ten sie pojawia. A ja bym chcial zeby po wpisaniu pierwszej cyfry ilosc wierszy zostala wyfiltrowana tylko do tych ktora ta cyfre zawieraja, jak wpisze kolejna - znow ma sie zawezic ilosc wierszy, itd. (no w ostatecznosci moze byc tak ze program sprawdza od lewej).
Obecnie filtr generuje takie zapytanie:

aRCHArchiwumBindingSource.Filter = "ARCHPESEL = (" + System.Int64.Parse(tBPESEL.Text)+")" ;

Bede wdzieczny za podpowiedz jak powinno to wygladac aby zadzialalo tak jak sobie wymysliem.

P.S. JEstem praktycznie zielony z C#, zaczalem sie nim bawic w zeszly weekend, wiec prosze o wyrozumialosc i mozliwie 'lopatologiczne' wyjasnienie :)

0

Czy PESEL musisz sumować, obliczać średnio lub robić inne operacje matematyczne? Nie! Więc po co masz numeric(11)? Jak przechowujesz PESEL '00210100001'?

0

Typ numeric(11) nadalem aby ograniczyc ilosc cyfr wpisywanych do 11, ale widze teraz ze to tak nie dziala... Natomiast co do sumowania, sredniej czy innych operacji matematycznych - na tym etapie nie, ale zamierzam dolozyc sprawdzanie cyfry kontrolnej.

0
Bushman napisał(a):

Typ numeric(11) nadalem aby ograniczyc ilosc cyfr wpisywanych do 11

To użyj char(11).

Natomiast co do sumowania, sredniej czy innych operacji matematycznych - na tym etapie nie, ale zamierzam dolozyc sprawdzanie cyfry kontrolnej.

I przechowywanie PESELu w postaci liczbowej Ci w tym pomoże?

0

Po pierwsze PESEL powinien skladac sie z cyfr. Definiujac kolumne jako numeric nie musze juz sprawdzac czy to co user wpisal jest liczba, robi sie to automatcznie. Zalozylem tez, ze skoro w przyszlosci bede wykonywal operacje matematyczne, to latwiej bedzie zrobic to na liczbach niz na stringu :) Chcialem uniknac konwersji stringa na liczbe, ale jak widac zakopalem sie w innym miejscu. Na chwile obecna przebudowalem baze i faktycznie zrobilem kolumne PESEL jako char(11). Pozostaje dorobic kwestie sprawdzania czy to co wpisane jest liczba, no i obliczanie cyfry kontrolnej... Nie wiem tylko jak odwolac sie do zmiany w datagridview, w tej konkretnej komorce... ale szukam, szukam :)

0

Litera 'a' to tez znak, ale jak znajdzie sie w PESELu to troche namiesza... prawda? nie wiem z jakiego 'rodzaju' userami Ty masz do czynienia, ale ja sie nauczylem juz dawno ze trzeba ich non stop sprawdzac, patrzec im na rece, a programy pisac mozliwie 'idiotoodporne' bo zawsze znajdzie sie agent co w pole z definicji liczbowe (jak np. nr PESEL) zechce wpisac 'aaa'. Tak wiec moze dajmy spokoj przepychankom slownym, nie twierdze ze to co sobie zalozylem na poczatku jest super-duper i sztywno bede sie tego trzymal (zreszta jak juz pisalem wczesniej, zmienilem juz typ tej kolumny). Pozostaje mi rozwiazac kwestie sprawdzania dlugosci wpisanego PESELa (user moze przeciez zechciec wpisac tylko 10 znakow), czy sklada sie tylko z cyfr, no i tej cyfry kontrolnej... Jesli wiesz jak odwolac sie do zmiany w okreslonej komorce w DataGridView to chetnie wysucham podpowiedzi.

0

Jeśli chodzi o walidację PESELu tak, aby zawierał jedynie cyfry, to naprawdę niepotrzebnie wałkujesz problem, który rozwiązuje się w trzy minuty banalnym wyrażeniem regularnym.

Natomiast jeśli chodzi o zmianę sposobu filtrowania Twojego BindingSource, to zamiast operatora = się użyj operatora like, coś na zasadzie:

aRCHArchiwumBindingSource.Filter = "ARCHPESEL LIKE '" + tBPESEL.Text +"%'";
0
somekind napisał(a):

Jeśli chodzi o walidację PESELu tak, aby zawierał jedynie cyfry, to naprawdę niepotrzebnie wałkujesz problem, który rozwiązuje się w trzy minuty banalnym wyrażeniem regularnym.

Nie mam pojecia co to 'wyrazenie regularne' :) ale oczwiscie pogooglam, skoro to proste, to pewnie gdzies znajde uzyteczny przyklad.

somekind napisał(a):

Natomiast jeśli chodzi o zmianę sposobu filtrowania Twojego BindingSource, to zamiast operatora = się użyj operatora like, coś na zasadzie:

aRCHArchiwumBindingSource.Filter = "ARCHPESEL LIKE '" + tBPESEL.Text +"%'";

Wyobraz sobie ze wpadlem na to :) Ale niestety nie jest to takie proste... Co ciekawe, tak zbudowane zapytanie w SQL Management - dziala. JEdnak tu w kodzie - nie, pojawia sie blad:

System.Data.EvaluateException was unhandled
Message="Nie można wykonać operacji 'Like' na System.Decimal i System.Int32."

Dzieki na dzis za dyskusje, kulam do wyra, jutro rano do pracy... I jak pisalem wczesniej, prosze o wyrozumialosc bo C# zaczynam dopiero poznawac, a idzie mi opornie bo programista nie jestem (mam niewielkie podstawy, znam troche c++, troche vba, o pascalu czy asemblerze nawet nie mowie bo to totalne archaizmy :) )

0

Nadal jednak nie odpowiedziałeś na pytane : Jak przechowujesz PESEL '00210100001'? W kontekście typu numeric(11)

0
Bushman napisał(a):

Wyobraz sobie ze wpadlem na to :) Ale niestety nie jest to takie proste... Co ciekawe, tak zbudowane zapytanie w SQL Management - dziala. JEdnak tu w kodzie - nie, pojawia sie blad:

System.Data.EvaluateException was unhandled
Message="Nie można wykonać operacji 'Like' na System.Decimal i System.Int32."

Twoja kolumna ARCHPESEL musi być typu tekstowego, żeby like zadziałało.

0
Marcin.Miga napisał(a):

Nadal jednak nie odpowiedziałeś na pytane : Jak przechowujesz PESEL '00210100001'? W kontekście typu numeric(11)

Slusznie, tu sie tez sprawa komplikuje, bo obcinane sa dwa poczatkowe zera. I jak pisalem wczesniej - nie upieram sie przy tym typie kolumny, zmienilem na char.

0

Podsumowanie i solucja:

Wychodzi na to ze czasami liczb nie oplaca sie przechowywac jako liczby :) Zwlaszcza gdy zamierzamy uzywac filtra stopniowo zawezajacego wyswietlanie wynikow (tzn. po wpisaniu '5' filtr pokazuje wszystkie rekordy z cyfra 5, po dopisaniu cyfry 2, a wiec mamy '52' - pokazuje wszystkie rekorty z ciagiem cyfr '52', itd.). W takim wypadku pozostaje nam tylko typ znakowy.

Jesli zas trafi tu jakis 'zielony' jak ja, moze zaoszczedze mu dluuugich godzin googlowaniai i znajdzie tu to czego ja nie znalazlem, czyli wyjasnienie co trzeba zrobic aby obsluzyc wyjatek pt. CellValueChanged (bo o to tez pytalem, ale jakos dyskusja sie nie rozwinela...) w projekcie opartym o Windows Form Applications:

  1. na zakladce <Form1.Designer.cs>, czyli tam gdzie znajduje sie taki kod:
        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();

trzeba dopisac linijke:

this.dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(this.dataGridView1_CellValueChanged);

(oczywiscie nazwy 'Form1', 'dataGridView1' oraz 'dataGridView1_CellValueChanged' moga byc w Twoim projekcie inne).

  1. na zakladce <Form1.cs>, czyli tam gdzie znajduje sie taki kod:
namespace Twoja_nazwa_obszaru //zgodna z nazwa projektu
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

trzeba dopisac:

        private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (dataGridView1.Columns[e.ColumnIndex].Name == "Twoja_nazwa_kolumny")
            {                                          
               MessageBox.Show("Test");//tu w przkladzie po jakiejkolwiek zmianie w komorce wybranej kolumny wyswietla sie komunikat TEST, ale oczywiscie to tylko przyklad,
            }                                        
        }

i tu uwaga: 'Twoja_nazwa_kolumny' to NIE nazwa kolumny w tabeli w bazie, znajdziesz ja po p-klik na BindingSource->Edit Columns->l-klik na wybranej kolumnie i po prawej stronie, tam gdzie Design i (Name) znajduje sie ta wlasciwa nazwa.

I to mialem na mysli piszac o 'lopatologicznym wyjasnieniu' :D

2

Bushman napisał

Wychodzi na to ze czasami liczb nie oplaca sie przechowywac jako liczby

Bardzo dyskusyjny pogląd, rozpatrywany przykład nie jest dobrym uzasadnieniem bowiem numer pesel nie jest liczbą.

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