Pino pozdrava svima. Drago mi je da stari programi rade. Siguran sam da si ih unapredio od tada,pozdravljam i to. Pazi samo da jos uvek rade sa novijim verzijama Accessa.
Vodomeri, dakle. Ja godinama se kanim da napravim sam to, onako iz fazona, ali nema se vremena ni volje vise kao pre. Ovo je zato sjajna prilika da me nesto natera da se pomerim s mesta :-)
Da se razumemo, svi saveti koji su ti kolege dali ranije vaze i dalje. Ja cu da probam da razresim onaj dinamicki deo. Ako to uspe, onda ce verovatno neki saveti biti zastareli, ali to ne umanjuje njihovu vrednost ni malo. U ovom trenutku, to su najbolji saveti koje mozes dobiti, tacka.
Da predjemo na posao. Ovaj paragraf iz tcvog poslednjeg posat je skolski primer kako se projektni zadatak objasnjava u dve-tri recenice. Pomaze malo sto sam i ja proveo 10 godina u vodovodu, u dva, po pet godina i tamo sam naucio osnove o prikupljanju, upravljanju obradi podataka. Kad sam dosao u Kanadu, naucio sam MS Access, pa psle malo i SQL (verzija 6.5!) i onda su se kockice slozile...
Zahtev i opis problema: "Prvenstveno moja je želja u onom tehničkom djelu (to je moj sektor) da imam uvid u sve - koliko imamo kakvih vodomjera, koji su na servisima, koliko ih ima da im je prošao rok i moraju u zamjenu. Baždarnicu više nemamo jjer je nerentabilna nego kupujemo dvije vrste vodomjera i to nove sa modulima i servisirane. Servisiran je onaj vodomjer koji ja dobijem sa ovjernim žigom i ugrađujem ga kao novog jedino uz malo novaca vodomjer kojem je prošao rok ja ga šaljem dobavljaču u zamjenu za servisirani. Broj vodomjera koji ja vratim i onaj koji dobijem nazad nemaju skoro nikakvu šansu da budu istog broja. Tako da sam čak razmišljao da kada mu dam status da je razdužen da ga brišem iz baze, ali mi problem radi arhiva izmjena jer ga tamo moram imati. "
Odgovor:
-- koliko imamo kakvih vodomjera, => to ide u master tabelu Vodomeri (serijski (fabricki) broj, precnik, opseg merenja, rok trajanja, proizvodjac itd.)
-- koji su na servisima => za ovo ide potpuno nova tablica, PromenaStanjaVodomera, ili "Gde je moj vodomer" ((serijski (fabricki) broj, gde je/kod koga je, kad je otisao tamo gde je, koliko mu je bilo citanje u momentu promene mesta ili osobe koja zaduzuje vodomer)
-- koliko ih ima da im je prošao rok i moraju u zamjenu => odgovor leziu gledanju u master tabelu Vodomeri (rok trajanja?) i "Gde je moj vodomer", qury "Svi vodomeri koji su negde (bilo gde) i danasnji datum je veci ili jednak datumu 'Rok Trajanja' u master tabeli)
-- Baždarnicu više nemamo jer je nerentabilna => dobro je znati, inace bi to bilo jedno od mesta gde moze biti vodomer u nekom trenutku
-- Servisiran je onaj vodomjer koji ja dobijem sa ovjernim žigom i ugrađujem ga kao novog jedino uz malo novaca => to je tabela "Gde je moj vodomer". Kad ga kupis prvi put, lokacija/status je "dobijen od dobavljaca" na neki datum, cutanje brojila = xxxx. Kad ga ugradis negde, stanje/lokacija je "Neka Adresa", ne neki datum, citanje u tom trenutku. Kad mu dodje vreme za popravku/vracanje/bazdarenje, to su sve moguca stanja/lokacije, na neki datum, i imaju neko citanje.
-- Broj vodomjera koji ja vratim i onaj koji dobijem nazad nemaju skoro nikakvu šansu da budu istog broja => to nas ne sekira ni malo. Jednostavno ce neki vodomeri imati poslednje stanje/lokaciju "Vraceni dobavljacu". Ako se vrati bas isti taj nekad, dobice status "Dobavljac vratio popravljen vodomer" i odatle ponovo u upotrebu, i veliki ciklus zivota vodomera se nastavlja :-).
-- Tako da sam čak razmišljao da kada mu dam status da je razdužen da ga brišem iz baze, ali mi problem radi arhiva izmjena jer ga tamo moram imati. => nista ne smeta da vodovod ustane zauvek u statusu "Rzaduzen" il "Otpisan" ili "Izgubljen", "Unisten","Ukraden". Bar ce u bazi biti trag, kada se sta od toga desilo. Ne brisemo nista i sve se zna - svi srecni na kraju.
-- Naplata. Naka naplatu radi knjigovodstvo, tako i treba. Medjutim, ti i dalje moras da ocitavas stanja. Ne moras mozda da racunas i potrosnju kao razliku dva uzastopna stanja, ali da ih ocitas, to se mora. Tu ce opet pomoci tablica "Gde je moj vodomer". Upisaces nesto ovako "Vodomer [SerijskBroj", ocitan dana "NedkiDan", na lokaciji [NekaAdresa], procitana vrednost je [CitanjeVodomera]. Ako sva citanja upises u tabelu "Gde je moj vodomer", imas sve sto ti treba da izracunas i potrosnju, ili da staro inovo citanje posaljes u knjigovodstva, pa neka oni racunaju :-) jedino moras da vodis racuna da korisnik kome naplacujes vodu bude tacan. To mozes da vodis u tabeli "Gde je moj vodomer" ali je prekomplikovano, pa cemo to ostaviti van ove price.
-- Interesantni su slucajevi:
1) kad se promeni korisnik, a vodomer ostane isti => ocitas stanje u momentu promene i duzis prvok korisnika za naplatu razlike, a novom korisniku to je pocetno stanje
2) korisnik ostaje isti, ali se menja vodomer => opet ocitas staje starog vodomera, razliku od proslog citanja duzis na korisnika. Novo stanje starog vodomera = "Skinut" ili "Razduzen korisnik" ili "Vracen u magacin", pa odatle dalje kako bude. Korisniku (nije se promenio) se daje novi vodomer - stanje "Ugradjen na lokaciju..", pocetno stanje ono sto pise na vodomeru u momentu ugradnje.
Sve sto smo ispricali, stanja, lokacije, promene, zaduzenja vodi se u tabeli "Gde je moj vodomer". Jedan isti kod upravlja svim promenama. Stos je napraviti listu mogucih stanja i lokacija, tako da mozemo da pratimo sta se desava. Lista ne mora iz prve da bude kompletna i perfektna. Vremenom se mogu dodavati nova stanja (stara se ne mogu brisati, ali se mogu ignorisati kad vise nemaju svrhu) Pored liste mogucih stanja, potrebno je definisati dozvoljene promene stanja. To radimo sa dve tabele "Moguca Stanja" i "Dozvoljene Promene Stanja". Te dve tabele kontrolisu sta se i kako moze upisati u "Gde je moj vodomer". ZBog zakona relacione teorija, prvo moraju da se naprave "Moguca Stanja" i "Dozvoljene Promene".
Moguca stanja. Za pocetak, mozemo definisati nekoliko ociglednih stanja: Stigao od dobavljaca, Postavljen kod korisnika, Ocitan, Skinut, Poslat Dobavljacu, Otpisan. Stanja nisu izlistana ni u kakvom redoledu jer njihov odnos nije linearan niti jednosmeran. Tokom zivota, vodomer prolazi kroz razna stanja. Neki prelzi imaju smisla, a neki ne. Na primer,
Neki vodomer moze da ima sledeci zivotni put:
Put 1: (Stigao od dobavljaca -> Postavljen kod korisnika -> Ocitan -> Ocitan...-> Ocitan -> Skinut -> poslat Dobavljacu.)
Neki drugi moze da ima drugaciji put:
Put 2: (Stigao od dobavljaca -> Postavljen kod korisnika -> Ocitan -> Ocitan...-> Ocitan -> Doelejn nom korisniku" -> Ocitan..Ocitan-> Otpisan
Broj kombinacija je veliki, ali ne i beskonacan. Neki ljudi razumeju promene stanja bolje ako se to - nacrta. rtez predstavlja graf, matematicki objekat koji se satoji od cvorova i linija koj povezuu cvorove (grane grafa). Cvorovi grafa su stanja, a grane su linije koje spajaju stanja. Nas graf bi mogao da izgleda ovako:
Svaka strelica je prelaz iz stanja u stanje. Mozda neke ne trebaju, ili neka stanja ne trebaju, slobodno ih se moze ukloniti. Potrebne su dve tabele:
DozvoljenaStanja : {Stanje text(25) UNIQUE (Stanje) }
DozvoljenePromeneStanja: {StaroStanje text(25), NovoSTanje text(25)
, UNIQUE (StaroStanje,NovoStanje)
, FK_1 (StaroStanje) REFERENCES DozvoljenaStanja(Stanje)
, FK2_(NovoStanje) REFERENCES DozvoljenaStanja(Stanje)
}
Tabela GdeJeVodomer za pocetak neka izgleda ovako:
ZivotVodomera { Vodomertext (50) StaroStanje text(25), NovoStanje text(25)
, DatumStarogStanja DateTime, DatumNovogStanja DateTime
,StaroCitanje long integer,, NovoCitanje longI nteger,
, KoJeZaduzen text 255 -- ovde se upisuje ko duzi vdodmer posle ove promene
sva polja su NUY MULL - Required = Yes,
UNIQUE_1 (Vodomer, DatunNovogStanja),
FK1 (StaroStanje, NovoStanje) REFERENCES DozvoljenePromeneStanje (StaroStanje,NovoStanje)
}
Za pocetak, napravite ove tri tabele. Dodajte relationships za svaki FK koji smo naveli. Unesite neke podatke ovim redom: DozvoljenaStanja
, DozvoljenePromeneStanja (svaka strelica na dijagramu je promena stanja. Pocetni kar = StaroStanje, vrh strelice = NovoStanje.
Onda pazljivo pokusajte da unsete dv-tri reda za jedn vodomer. Primetite da je u svakom redu StaroStanje on sto je u prethodnom redu bilo novo stanje Isto vazi za DatumStarog i NovogStanja, i StaoCitanje -NovoCitanje. Za prvi rekord, stavite StaroStanje = NovoStanje, DatumStarogStanja = DatumNovogStanja, StaroCitanje = NovoCitanje. Logicno bi bilo da sve Staro.. za prvired bude NULL ali Access to ne dozvoljava. MS SQL dozvoljava i to donekle olaksava posao u T-SQL. Ali samo T-SQL, sve ostale variante SQL se ponasaju kao Access.
Dakle, unesete prvi red, gde je sve Staro jednako sve Novo. U sledeci red u kolone Staro.. prepisujete ono sto je u prethodnom redu bio u kolonama Novo. Pazite, lako se gresi. Dobra stvar je sto cemo za tu operaciju napisati tri linije koda i zaboraviti na to. Posle nekoliko redova, primeticete sistem koji se ponavlja, podaci iz rda u red isu u cik-cak. lep izgleda, ali sta to nama koristi? Prvo, ako iamma StaroCitanje i Novo u istom redu, mozemo lako da izracunamo potrosnju. drugo, Staro I NovoStanje mozemo da uporedimo sa dozvoljnim promenama i sprecimo nekoraktan unos. Ako je vodomer "Otpisan" on ne moze da se pojavi vise nigde, jer iz cvora "Otpisan" ne izlazi ni jedna strelica. Iz cbora "Citanje" moze se ici nazad u taj cvor. To je ono sto se ocekuje u normalnim uslovima - vodomer sedi u mestu i cita se svako malo. Zgodno, zar ne?
Zgodno, ali nje sigurno 100%. Zato nam trebaju jos neke constraints, da bi podaci bili uvek logicni, bez duplikata, bez besmislenih promena i bez nelogicnih citanja. Datum novog citanja mora biti veci nego datum starog citanja, ili bar jednak. KAd vodovod ide na opravku, ocitamo stanje kad smo ga skinuli. Kad se vrati, bice neko drugo citanje, jer su u radionici pomerili tockice i zupcanike. I niko nece tu razliku sda plati jer ce se iz tabele videti da se ta promena na brojcaniku desila u radionic.NovoCitanje ne moze nikako biti manje od starog. Obicno je novo citanje vece, ali ne pri svakoj promeni. Kad skinete vodomer, citanje ce biti isto. Kad se vodomer preokrene (br0jac predje odnekih 999,999,999 i postane 1,000,000,000 kazaljka stoji na nuli, 000,000,000 sto je daleko manje nego prethodno citanje. To se moze dozvoliti samo ako je prethodno citanje bilo - 999,999,999, cak i ako ga nismo zaista procitali. Skor sve situacije koje mozete zamisliti mogu se registrovati tacno i jednoznacno. menja se korisnik a vodomer stoji na mestu. "skinete" vodomer , i ponovo ga postavite sa novim "
To cemo psole vikenda. Za sada napravite tri tabele i unesite malo podataka, da steknete osecaj sta se stvarno desava.