83
RĪGAS TEHNISKĀ UNIVERSITĀTE Datorzinātnes un informācijas tehnoloģijas fakultāte Lietišķo datorsistēmu institūts Sistēmu teorijas un projektēšanas katedra Praktiskais darbs mācību priekšmetā “Datu bāzu vadības sistēmas” “Formas” Izstrādāja: Aleksis Liekna Pārbaudīja: prof. Jānis Eiduks

Formu veidošana - Web viewAutoForm: Datasheet – dati tiek attēloti formā, kas ļoti līdzīga parastai datu tabulai. Izmanto pie neliela lauku skaita un saistītajās formās

Embed Size (px)

Citation preview

RĪGAS TEHNISKĀ UNIVERSITĀTE

Datorzinātnes un informācijas tehnoloģijas fakultāte

Lietišķo datorsistēmu institūts

Sistēmu teorijas un projektēšanas katedra

Praktiskais darbs mācību priekšmetā “Datu bāzu vadības sistēmas”

“Formas”

Izstrādāja: Aleksis LieknaPārbaudīja: prof. Jānis Eiduks

2006./2007.m.g.

Saturs1. Formu veidošana......................................................................................................................32. Datu avots................................................................................................................................63. Formas.....................................................................................................................................9

3.1. Galvenā forma...............................................................................................................103.2. Vienkārša forma datu ievadei........................................................................................123.3. Pakārtota forma..............................................................................................................243.4. Forma ar ieliktnīšiem.....................................................................................................393.5. Meklēšanas forma..........................................................................................................463.6. Meklēšanas forma ar pārskatu.......................................................................................51

Secinājumi.....................................................................................................................................61Literatūras saraksts........................................................................................................................63

1. Formu veidošanaDarbībām ar formām Access ir paredzēta datubāzes galvenā loga sadaļa „Forms” (sk. Att.

1.1).

Att. 1.1 – sadaļa “Forms”

Šeit iespējams aplūkot esošās formas, un veikt darbības ar tām (tādas kā dzēšana, kopēšana pārsaukšana), kā arī iespējams veidot jaunas formas. Pēdējo darbību iespējams realizēt vairākos veidos. Šeit apskatīsim formu veidošanas iespēju, izmantojot datubāzes galvenā loga sadaļas „Forms” pogu „New” (sk. Att. 1.2).

Att. 1.2 – poga “New”

Nospiežot šo pogu, ekrānā parādās jaunas formas veidošanas dialoglogs (sk. Att. 1.3).

3

Att. 1.3 - formas veidošanas dialoglogs

Šajā logā redzami iespējamie paņēmieni jaunas formas veidošanai. Tātad šeit jāizvēlas nepieciešamo variantu no saraksta, kā arī laukā „Choose the table or query where the object’s data comes from” jāizvēlas nepieciešamais datu avots (tā var būt tabula vai arī vaicājums). Ja izvēlamies paņēmienu „Design view”, tad nekāda lielā bēda arī nebūs, ja datu avotu šeit nenorādīsim, jo to pēc tam var norādīt vai nomainīt, izmantojot formas īpašību sadaļas „Data” īpašību „Record Source”. Izvēloties „Form wizard” vai „PivotTable wizard” datu avots jānorāda veidņa izpildes gaitā, taču, ja vēlamies izmantot kādu no nepieminētajiem paņēmieniem, tad šajā laukā datu avotu tomēr nāksies norādīt. Lai iegūtu priekšstatu par pieejamajiem paņēmieniem formu veidošanā, aplūkosim tos nedaudz tuvāk:

Design View – formas patstāvīga veidošana. Visbiežāk izmanto vadības formu veidošanai, kā jau iepriekš minēts, var nenorādīt izejas datu tabulu vai vaicājumu.

Form Wizard – formu veidošanas veidnis. Access piedāvā vienu vai vairākas tabulas un formā attēlojamos laukus Lieto vienkāršās datu formās, kā arī pielieto veidojot saliktās (Main/Sub) formas (galvenā/apakšformas). Šādas formas izmanto, lai ievadītu datus vairākās (līdz trim) saistītās tabulās.

AutoForm: Columnar – automātiski tiek izveidota datu ievada vai attēlojuma forma norādītajai tabulai vai vaicājumam. Formā katrs lauks atrodas atsevišķā lapā. Parasti lieto ierakstiem, kuri sastāv no liela lauku skaita.

AutoForm: Tabular – dati tiek attēloti speciālas tabulas veidā. Ērta, ja neliels lauku skaits. Par datu avotu var izmantot tikai vienu tabulu vai vaicājumu.

AutoForm: Datasheet – dati tiek attēloti formā, kas ļoti līdzīga parastai datu tabulai. Izmanto pie neliela lauku skaita un saistītajās formās.

Chart Wizard – diagrammu veidošanas meistars. Izmanto datu ievadam grafiskā veidā. Izveidoto formu var iekļaut citā formā kā saistīto.

Pivot table Wizard – izmantojot Access tabulas un vaicājumus, var veidot „Excel Pivot” tabulas.

Šajā darbā tuvāk apskatīsim formu veidošanu ar „Design view” un „Form Wizard” palīdzību. Ļoti svarīgs elements saistībā ar formām ir formu īpašības. Aplūkosim svarīgākās no tām:Format grupas īpašības:

Caption – formas virsraksts Default view – režīms pēc noklusējuma – nosaka formas režīmu to atverot Views Allowed – pieļaujamie atvēršanas režīmi: formas, tabulas vai abi Scroll Bars – norāda, vai vajadzīgas pārvietošanās joslas Record Selectors – norāda, vai vajadzīga ierakstu iezīmēšanas josla formas kreisajā malā Navigation Buttons – norāda vai vajadzīgas navigācijas pogas Dividing Lines – norāda vai vajadzīgas formas apgabalu atdalītājlīnijas

4

Auto Resize – automātiskais izmērs, lai būtu redzami visi lauki Auto Center – pie atvēršanas forma tiek novietota ekrāna centrā Border style – nosaka formas rāmja izskatu Control Box – nosaka, vai pieejama (redzama) formas izvēlnes karte (formas kreisā

augšējā stūrī) Min Max Buttons – nosaka vai formu var minimizēt vai maksimizēt Close Button – nosaka vai pieejama formas slēgšanas poga Width – formas platums (cm) Picture – formas fona zīmējums Picture Aligment – zīmējuma izvietojums Picture Tilling – norāda vai formas fomu aizpildīt, zīmējumu atkārojot

Data grupas īpašības Allow Edits – nosaka vai ieraksti ir rediģējami vai tikai lasāmi Allow Deletions – nosaka vai ierakstus var dzēst Allow Aditions – nosaka vai ierakstus var pievienot Record Lock – nosaka ierakstu bloķēšanu, strādājot vairākiem lietotājiem

Other grupas īpašības Pop Up – formu atverot, tā parādās priekšplānā attiecībā pret citām formām Modal – nevar pāriet uz citu formu, kamēr šī nav slēgta Cycle – nosaka vai ar Tab taustiņu var pāriet uz nākošo ierakstu, vai tikai cikliski apiet

visus formas laukus

Esam virspusēji aplūkojuši formu veidošanas uzsākšanu un to galvenās īpašības, sīkāk formu veidošanu aplūkosim darba izstrādes gaitā. Tagad nepieciešams datu avots (datu tabulas ar datiem), lai būtu iespējams realizēt nepieciešamo uzdevumu.

5

2. Datu avotsŠī darba veidošanā izmantosim iepriekšējam darbam izveidotās datu tabulas un to datus.

Tā kā to veidošana ir sīki aprakstīta iepriekšējā darbā, tad to šeit sīkāk neapskatīsim. Tomēr, lai būtu priekšstats par notiekošo, aplūkosim tabulas un saites starp tām (sk. Att. 2.4), kā arī datus, kas tabulās tika ievadīti (sk. Att. 2.5 - Att. 2.10).

Att. 2.4 – tabula “manufacturers”, aizpildīta ar datiem

Att. 2.5 – tabula “manufacturers”, aizpildīta ar datiem

6

Att. 2.6 – tabula “product_types”, aizpildīta ar datiem

Att. 2.7 – tabula “products”, aizpildīta ar datiem

7

Att. 2.8 – tabula “products_sales_linked”, aizpildīta ar datiem

Att. 2.9 – tabula “sales”, aizpildīta ar datiem

Att. 2.10 – tabula “workers”, aizpildīta ar datiem

8

3. FormasTagad mūsu rīcībā ir datu avots un būtu tā kā īstais laiks ķerties klāt pie formu

veidošanas. Loģiski būtu pirms kaut kā veidošanas ieskicēt vismaz aptuvenu plānu, kā tam visam vajadzētu izskatīties un darboties. Tā arī rīkosimies un uzskicēsim formu darbības shēmu (sk. Att. 3.11)

Att. 3.11 – formu darbības shēma

Darbības centrā paredzēsim galveno formu, no kuras iespējams izsaukt visas pārējās formas. Formu izsaucot galveno formu neaizvērsim, bet izmantosim formas īpašību „Modal” (lietotājam vienā laika momentā būs pieejama tikai viena vienīga forma – ar to pašu jau pietiek, lai rastos problēmas, kur nu vēl ļaut viņam piekļūt visām formām uzreiz). Aizverot kādu no formām, fokuss automātiski tiks atgriezts galvenajai formai un jautrība varēs turpināties. Vienīgais izņēmums šeit būtu veidojamais pārskats, to varēs izsaukt tikai no atbilstošas formas (kaut kāda iemesla dēļ mēs taču viņu veidojam, vai ne?).

Turpmākajā darba gaitā centīsimies šo shēmu realizēt. Realizāciju sāksim ar galveno formu.

9

3.1. Galvenā formaGalveno formu, kā jau iepriekš vienojāmies, veidosim tā, lai būtu iespējams no tās

izsaukt visas pārējās formas. Sāksim tās veidošanu projektēšanas režīmā, proti, no datu bāzes galvenā loga sadaļas „Forms”, izvēloties „Create form in Design view” (sk. Att. 3.12).

Att. 3.12 – projektēšanas režīma izsaukšana

Izpildot šo darbību, ekrānā parādās tukša forma projektēšanas režīmā (sk. Att. 3.13).

Att. 3.13 – forma projektēšanas režīmā

Varam formu uzreiz saglabāt. Šoreiz izvēlamies nosaukumu „main” (sk. Att. 3.14).

10

Att. 3.14 – formas saglabāšana

Tagad ievietosim šajā formā pogas, ar kuru palīdzību tad arī izsauksim attiecīgās formas. Pogas veidosim, izvēloties no standarta izvēlnes „Tool Box” elementu „Command Button” (sk. Att.3.15) un novietojot to vēlamajā formas vietā.

Att. 3.15 – pogas veidošana no standarta izvēlnes “Tool Box”

Šādi izveidosim visas pogas, kuras nepieciešamas attiecīgo formu atvēršanai. Šajā brīdī, tā kā mums vēl nav nevienas citas formas, izņemot galveno, minētajām pogām nekādas darbības nepiešķirsim (piešķirsim tās formu veidošanas gaitā). Tagad izveidosim vēl vienu pogu, ar kuras palīdzību realizēsim galvenās formas aizvēršanu. Šai pogai principā darbību varētu piekārtot jau tagad, taču darīsim visus darbus vienā reizē, un, mirklī, kad piešķirsim darbības pārējām pogām, piešķirsim darbību arī šai.

Pēc visu pogu izveidošanas varam aplūkot iegūto rezultātu (sk. Att. 3.16).

Att. 3.16 – galvenā forma

Tagad galvenā forma ir izveidota, varam ķerties klāt pie pārējo formu viedošanas.

11

3.2. Vienkārša forma datu ievadeiIzveidosim vienkāršu datu ievades formu, informācijas par produktiem ievadīšanai. Šeit

paredzēsim informācijas ievadi visos nepieciešamajos attiecīgās tabulas laukos. Šīs formas izveidošanai izmantosim formu izveidošanas veidni. Lai to izsauktu, datu bāzes galvenajā logā sadaļā „Forms” izvēlamies „Create form by using wizard” (sk. Att. 3.17).

Att. 3.17 – formu izveidošanas veidņa izsaukšana

Izpildot šo darbību, ekrānā parādās formu izveidošanas veidnis (sk. Att. 3.18)

Att. 3.18 – formu uzveidošanas veidnis

12

Šeit laukā „Tables/Queries” nepieciešams norādīt attiecīgo tabulu vai vaicājumu, kas kalpos par veidojamās formas datu avotu. Mūsu gadījumā tā ir tabula „products”. Tālāk no sadaļas „Available fields” nepieciešams vajadzīgos laukus pārvietot un sadaļu „Selected fields”. Tā kā veidojam datu ievades formu, tad šajā gadījumā nepieciešams visus laukus pārvietot uz sadaļu „Selected fields”. Pēc šo darbību izpildīšanas, spiežam pogu „Next”, un ekrānā parādās formas izkārtojuma izvēlne(sk. Att. 3.19).

Att. 3.19 – formas izkārtojuma izvēlne

Šeit no visiem piedāvātajiem variantiem izvēlamies „Columnar”, jo, pēc autora domām, tas ir optimālākais variants datu ievades formai, un tad spiežam „Next”. Pēc šo darbību izpildīšanas ekrānā parādās formas stila izvēlne (sk. Att. 3.20)

Att. 3.20 – formas stila izvēlne

13

Šeit izvēlamies „Standart”, kas, pēc autora domām, ir visdraudzīgākais stils lietotājam. Protams, gaumes ir dažādas, un ir arī cilvēki, kuriem patīk ar sarkaniem burtiem rakstīti uzraksti uz melna fona, taču ir arī tādi cilvēki, kuriem minēto krāsu kombinācija neiet pie sirds. Krāsu kombinācijas izvēle lietotāja formu veidošanā ir ļoti svarīga, jo nepareizi izdarītas izvēles gadījumā (piemēram, izvēloties pārāk spilgtas krāsas), lietotājam ātri nogurst acis vai arī rodas nepareizs priekšstats par izmantojamo lietotni. Tādēļ autors pieturas pie klasiskā stila, jo tas ir savu produktivitāti pierādījis gadu gaitā un cilvēki pie tā ir pieraduši, līdz ar to šāda stila lietotnes ir vieglāk uztveramas lietotājam. Tātad, pēc stila izvēles, nepieciešams izvēlēties formas vārdu (sk. Att. 3.21)

Att. 3.21 – formas vārda izvēle

Nosauksim šo formu par „products”, līdzīgi kā tabulu, uz kuras tā balstīta. Lai atvērtu formu lietotāja režīmā un būtu iespējams aplūkot veidņa darba rezultātu atzīmējam „Open the form to view or enter information”. Tagad nospiežam „Finish” un varam aplūkot sava darba augļus (sk. Att. 3.22).

Att. 3.22 – forma “products” tikko pēc izveidošanas

14

Aplūkojot iegūto formu, var secināt, ka būs nepieciešams veikt dažas modifikācijas, pirms to varētu rādīt lietotājam. Viegli pamanīt, ka lauku apraksti ņemti no tabulas lauku nosaukumiem (kas mūsu gadījumā nav pieļaujams – lietotāja saskarnei ar datu bāzi jānotiek latviešu valodā), lauku izmēri un vērtību izvietojumi tajos ir dažādi (izskatās pēc šaha lauciņa, nevis kārtīgas lietotnes), formas kreisajā pusē ir redzams nevienam nevajadzīgs ierakstu selektors, formai ir maināms, nepatstāvīgs izmērs, kā arī navigācija pa formas ierakstiem ir angliski (arī tas nav savietojams ar vienotas saskarnes pamatideju). Visas šīs nepilnības iespējams novērst, atverot formu projektēšanas režīmā un veikt manuālas modifikācijas, kā arī darīsim. Lai pārietu no lietotāja uz projektēšanas režīmu, izpildīsim „View->Design View” (sk. Att. 3.23).

Att. 3.23 – pārslēgšanās uz projektēšanas režīmu

Pēc augstākminētās darbības izpildīšanas, ekrānā parādās forma „products” projektēšanas režīmā (sk. Att. 3.24).

Att. 3.24 – forma “products” projektēšanas režīmā

15

Šeit arī veiksim visas nepieciešamās modifikācijas. Lai nomainītu lauku aprakstu nosaukumus, izvēlamies attiecīgo lauka aprakstu un vai nu izpildām labo peles klikšķi, izvēlamies sadaļu „Properties” un šeit sadaļā „Format” īpašībā „Caption” iestādām vēlamo vērtību (sk. Att. 3.25),

Att. 3.25 – īpašības “Caption” vērtības maiņa

vai arī vienkārši nospiežam uz klaviatūras „F2” un tad ievadām attiecīgo vērtību. Lai mainītu lauku izvietojumu, izmērus un to satura izvietojuma novietojumu, jārīkojas līdzīgi kā ar jebkuru Microsoft Office objektu, tādēļ to sīkāk neaplūkosim. Lai forma iegūtu baudāmāku izskatu, pievienosim pāris „Rectangle” tipa objektus, no standarta izvēlnes „Toolbox” izvēloties „Rectangle”. Tagad nepieciešams nedaudz modificēt formas īpašības. Lai to izdarītu, sākumā nepieciešams izsaukt formas īpašību rediģēšanas logu. Viens no paņēmieniem kā to izsaukt ir izpildīt labo peles klikšķi vietā, kas Att. 3.26 atzīmēta ar melnu apli un no saraksta izvēlēties „Properties”.

Att. 3.26 – formas īpašību rediģēšanas loga izsaukšana

Lai panāktu vēlamo rezultātu, mainīsim šādu īpašību vērtības:

Tabula 3.2.1 – formas “products” uzstādāmās īpašībasĪpašība Vēlamā vērtība MērķisCaption Preces Nosaukums, ko lietotājs redzēs

formu atverot.Scroll Bars Neither Formu veidosim tā, lai ritjoslas

nebūtu nepieciešamas.Navigation Buttons No Veidosim paši savu ierakstu

navigācijas sistēmu ar paskaidrojumiem latviski.

Record Selectors No Noņemam nevajadzīgo ieraksta selektoru.

Dividing Lines No Nevajag mums nekādas bezjēdzīgas

16

līnijasBorder Style Thin Nevajag nevienam to formu staipīt

un gorīt - lai paliek konkrēts izmērs un miers.

Modal Yes Lietotājs nevarēs atvērt citu formu, neaizvēris šo (nevienam nav vajadzīgs, lai lietotājs būtu vienlaicīgi atvēris 10 formas un tad brīnītos kāpēc nekas nestrādā).

Kad esam minētās īpašības nomainījuši, forma jau sāk iegūt daudzmaz jēdzīgu paskatu. Tā kā atslēdzām iebūvēto ierakstu navigācijas sistēmu, tad tagad būtu īstais laiks izveidot savu. Sākumā izveidosim vienkāršas navigācijas pogas, lai būtu iespējams pāriet uz pirmo, iepriekšējo, nākošo, pēdējo un jaunu ierakstu, kā arī dzēst ierakstu. Šīs pogas veidosim ar veidņa palīdzību. Lai šo veidni izmantotu, nepieciešams iestatīt uz standarta izvēlnes „Toolbox” īpašību „Control Wizards” (sk. )

Att. 3.27 – īpašības “Control Wizards” iestatīšana

Pēc šīs īpašības iestatīšanas, veidojam jaunu pogu, izmantojot jau pieminēto izvēlni „Toolbox”, izvēloties no tās „Command button” un izvietojot pogu ar peles palīdzību nepieciešamajā formas vietā. Izpildot šīs darbības, ekrānā parādās komandu pogas veidošanas veidnis (sk. Att. 3.28).

Att. 3.28 – komandu pogas veidošanas veidnis

Šeit nepieciešams norādīt kādu darbību dotajai pogai jāpilda to nospiežot. Izvēlamies nepieciešamo darbību (vispirms veidosim pogu nonākšanai uz pirmo ierakstu, tātad izvēlamies kategorijas „Record Navigation” darbību „Go To First Record” un spiežam „Next”. Tagad nepieciešams izvēlēties kā dotā poga tiks attēlota (sk. Att. 3.29), proti, vai tai virsu būs uzrakstīts teksts vai arī uz tās būs zīmējums.

17

Att. 3.29 – pogas attēlojuma izvēle

Pieturēsimies pie klasiskā ierakstu navigācijas stila (melnām bultiņām) un šajā gadījumā izvēlēsimies no „Picture” sadaļas „Go To First 1” un nospiedīsim „Next”. Pēdējais ko palicis izdarīt, ir izvēlēties pogas vārdu (sk. Att. 3.30).

Att. 3.30 – pogas vārda izvēle

Nosauksim šo pogu par „first_rec” un nospiedīsim „Finish”, lai pabeigtu tās veidošanu. Pēc analoģijas izveidojam arī pogas pāriešanai uz iepriekšējo, nākošo, pēdējo un jaunu ierakstu, kā arī ieraksta dzēšanai (sk. Att. 3.31).

Att. 3.31 – izveidotās navigācijas pogas

18

Novērtējot iegūto rezultātu, var secināt, ka pietrūkst vienas lietas – informācijas par to cik ierakstu ir pavisam un kurš ir pašreizējais ieraksts. Šim nolūkam izveidosim formā divus standarta objektus „Label”, kurus nosauksim attiecīgi „curr_rec” un „rec_count”. Šiem laukiem ar VBA skripta palīdzību dinamiski mainīsim vērtības atkarībā no formas stāvokļa. Tā kā ir pilnīgi skaidrs, ka šī nebūs vienīgā forma, kurai nepieciešama šī funkcija, tad izveidosim moduli ar procedūru, kurai kā parametru varēs nodot formu, kurai būs nepieciešams mainīt attiecīgo lauku vērtības. Vēl nebūtu slikti, ja pogas, kas nodrošina pāreju uz iepriekšējo un nākošo ierakstu tiktu padarītas darba nespējīgas (disabled), ja ir sasniegts attiecīgi pirmais vai pēdējais ieraksts (kas zina, kas ir pirms pirmā ieraksta? Vai lietotājs sapratīs, kāpēc pēc pēdējā ieraksta seko jauns?).

Tātad, kā jau vienojāmies, lai būtu iespējams realizēt augstākminētās funkcijas, nepieciešams izveidot vienkāršu moduli ar vienu procedūru, kuru tad varētu izsaukt no jebkuras formas. Lai izveidotu moduli, nepieciešams datu bāzes galvenajā logā sadaļā „Modules” izvēlēties „New” (sk. Att. 3.32).

Att. 3.32 – jauna moduļa veidošanas izsaukšana

Izpildot šo darbību atveras moduļa rediģēšanas logs. Šeit uzrakstīsim nepieciešamo procedūru, kuru nosauksim par „handleNavigation” un saglabāsim moduli ar nosaukumu „public_functions” (sk, Att. 3.33), pieļaujot domu, ka darba izstrādes gaitā šeit varētu pievienot vēl kādu funkciju vai procedūru.

19

Att. 3.33 – modulis “public_functions”

Tagad nedaudz tuvāk aplūkosim uzrakstīto procedūru:

Public Sub handleNavigation _(f As Form, Optional rec_count As Label, Optional curr_rec As Label, _ Optional prev_rec As CommandButton, Optional next_rec As CommandButton)

Dim res As Recordset On Error Resume Next If (rec_count Is Nothing) Then Set rec_count = f.rec_count If (curr_rec Is Nothing) Then Set curr_rec = f.curr_rec If (prev_rec Is Nothing) Then Set prev_rec = f.prev_rec If (next_rec Is Nothing) Then Set next_rec = f.next_rec Set res = f.RecordsetClone Dim last As Integer, current As Integer res.MoveLast last = res.RecordCount current = f.CurrentRecord If (current = 1) Then prev_rec.Enabled = False Else: prev_rec.Enabled = True End If If (current >= last) Then

20

next_rec.Enabled = False Else: next_rec.Enabled = True End If rec_count.Caption = last curr_rec.Caption = current

End Sub

Šai procedūrai ir viens obligātais parametrs „f”, caur kuru tiek nodota forma, pa kuras ierakstiem notiek navigācija, kā arī četri neobligātie parametri, proti, „rec_count”, caur kuru var tikt nodots formas elements „Label”, kuram jāsatur informācija par kopējo ierakstu skaitu, „curr_rec”, caur kuru var tikt nodots formas elements „Label”, kuram jāsatur informācija par pašreizējo ierakstu (ieraksta numurs), „prev_rec”, caur kuru var tikt nodota formas poga, ar kuras palīdzību realizē pārvietošanos uz iepriekšējo ierakstu, un kuru nepieciešams padarīt darba nespējīgu, ja sasniegts pirmais ieraksts, „next_rec”, caur kuru var tikt nodota formas poga, ar kuras palīdzību realizē pārvietošanos uz nākošo ierakstu, un kuru nepieciešams padarīt darba nespējīgu, ja sasniegts pēdējais ieraksts. Caur obligātajiem parametriem nododami minētie formas elementi tikai tādā gadījumā, ja to nosaukumi atšķiras no predefinētejiem (ierakstu skaitam – „rec_count”, pašreizējam ierakstam – „curr_rec”, nākošajam ierakstam – „next_rec” un iepriekšējam ierakstam – „prev_rec”), kurus izmanto, lai katru reizi nebūtu jānodod procedūrai kaudzi ar parametriem, vai arī tie neatrodas formā, kuras navigāciju nepieciešams organizēt (piemēram, ja no galvenās formas jārealizē apakšformas navigāciju). Formas algoritms ir sekojošs, proti, ja nav nodots kāds no neobligātajiem parametriem, tad to aizstāj ar noklusēto, tālāk tiek iegūts formas, kuras navigāciju nepieciešams realizēt, ierakstu kopuma dublikāts, un tad to pārliek uz pēdējo ierakstu un pēc tam nosaka ierakstu skaitu (pārlikšana uz pēdējo ierakstu notiek tādēļ, ka varenais Bils Geits vēl līdz šim brīdim nav izlabojis šo kukaini Access(ā), proti, ja nosaka ierakstu skaitu ierakstu kopumam, kad tas nav novietots uz pēdējo ierakstu, rezultāti ir neprognozējami – 50%, ka darbosies pareizi, 50%, ka būs visādi brīnumi tur, piemēram, „debug” režīmā ejot cauri šai vietai viss būs kārtībā, bet normālā darba režīmā uz rezultātu skatoties var matus sākt plēst ārā no galvas). Formas pašreizējo ierakstu nolasa tieši no caur parametru padotās formas. Tālāk notiek pārbaude vai nav sasniegts pirmais vai pēdējais ieraksts un, atkarībā no šo pārbaužu rezultātiem tiek padarītas darba nespējīgas attiecīgās pogas. Pēc tam formas „Label” elementi, kuri atbild par informācijas par pašreizējā ieraksta un kopējā ierakstu skaita atspoguļošanu saņem attiecīgās vērtības un līdz ar to procedūras darbība beidzas.

Tagad tikai nepieciešams izsaukt tikko uzrakstīto procedūru vēlamajā brīdī un būsim ieguvuši atrisinājumu. Lai to panāktu, atvērsim formas „products” īpašību rediģēšanas logu un sadaļā „Events”, notikumam „On Current” (kad notiks pārvietošanās pa ierakstiem) pievienojam notikumu procedūru, kurai vajadzētu izskatīties sekojoši:

Private Sub Form_Current() handleNavigation MeEnd Sub

Šeit tiek izsaukta procedūra „handleNavigation” un tai kā parametrs tiek nodots mainīgais „Me”, kas ir rādītājs uz pašreizējo formu.

Vēl derētu izveidot pogu „Aizvērt”, ar kuras palīdzību tad varētu aizvērt pašreizējo formu un atgriezties uz galveno formu. Tā kā galvenā forma tika projektēta tā, ka, izsaucot kādu formu no formu saraksta, tā netiek aizvērta (kāda jēga to vērt ciet, ja nākošā forma tiek izsaukta ar īpašību „modal”?), tad jāparedz sekojošas situācijas:

Lietotājs ir atvēris formu „products”, izmantojot galveno formu. Šajā gadījumā nepieciešams aizvērt pašreizējo formu un pārlikt fokusu uz galveno formu.

21

Lietotājs ir atvēris formu „products” „pa tiešo”, neizmantojot galveno formu. Šajā gadījumā nepieciešams aizvērt pašreizējo formu, atvērt galveno formu un pārlikt fokusu uz galveno formu.

No šejienes var secināt, ka vispirms nepieciešams pārbaudīt, vai galvenā forma ir atvērta vai nav, un tikai tad veikt atbilstošās darbības. Visu šo darbību realizēšanai izmantosim VBA skriptu (tīri teorētiski minētās darbības varētu realizēt arī ar makrokomandu palīdzību, bet tad būtu katras formas aizvēršanas pogai jāveido sava makrokomanda, turklāt, kā gan ar makrokomandu palīdzību varētu pārbaudīt vai galvenā forma ir atvērta (metode „IsLoaded” ir pieejama tikai no VBA, nu vismaz tā rakstīts Access heplā)? Protams, var mēģināt to atvērt jebkurā gadījumā, bet, kas notiks, ja izpildīs atvēršanas darbību formai, kura jau ir atvērta? Var, protams, izsaucot formu no galvenās formas pēdējo aizvērt ciet, taču, kas notiks, ja lietotājs iemanīsies to atvērt?). Tātad papildināsim mūsu moduli „public_functions” ar divām jaunām funkcijām (precīzāk, vienu procedūru un vienu funkciju).Pirmā funkcija:

Public Function formIsLoaded(name As String) As Boolean Dim i As Integer, is_loaded As Boolean is_loaded = False For i = 0 To Forms.Count - 1 If (Forms(i).name = name) Then is_loaded = True Next i formIsLoaded = is_loadedEnd Function

Šai funkcijai kā vienīgo parametru padod vēlamās formas vārdu kā simbolu virkni un funkcija caur savu vārdu atgriež „True” (patiess), ja forma, kuras vārds tai padots caur parametru ir atvērta vai „False” (nepatiess) pretējā gadījumā. Funkcijas darbības algoritms ir gaužām vienkāršs – notiek visu atvērto formu vārdu salīdzināšana ar uzdoto, tad arī sakritības gadījumā uzdotā forma būs atvērta. Loģiski, vai ne? Šeit cilvēkam, kurš kaut nedaudz orientējas MS Access uzreiz rodas jautājums: „Kādēļ gan neizmantot iebūvēto metodi „IsLoaded”?”. Tādam cilvēkam autors varētu atbildēt – „Nezinu kāda velna pēc šī metode tur atrodas, jo, vismaz uz formām, tā noteikti nedarbojas, jo kā gan var izsaukt metodi kādam elementam, kurš nemaz nav? No uzrakstītās funkcijas skaidri redzams, ka formu masīvā ir tikai ielādētās formas, tātad, kā gan es varētu pārbaudīt masīva elementa eksistenci izsaucot to no masīva, kurā minētā elementa nemaz nav?”Otrā funkcija (nu labi, procedūra):

Public Sub handleClose(f As Form) DoCmd.Close acForm, f.name If (Not formIsLoaded("main")) Then DoCmd.OpenForm "main" Forms!main.SetFocusEnd Sub

Šai procedūrai kā vienīgo parametru padod aizveramo formu (varētu padot vienkārši tikai formas vārdu, taču, varbūt nākotnē būs nepieciešams pirms aizvēršamas izpildīt kādas darbības ar šo formu, piemēram, saglabāt pašreizējo ierakstu vai tml., un tad būtu jāveic korekcijas gan šajā procedūrā, gan visās tās izsaukuma vietās, tādēļ šeit atstāsim „rezervi”). Šādi tiek realizēts tas, ka procedūra ir universāla un piemērojama jebkurai formai (vienkārši nepieciešams šo formu nodot kā parametru). Procedūras darbības algoritms ir gaužām vienkāršs, proti, tiek aizvērta forma, kura padota uz šo procedūru, kā parametrs, tad tiek pārbaudīts (izsaucot iepriekš aprakstīto funkciju), vai galvenā forma ir atvērta, ja nē, tad to atver, un visbeidzot tiek pārlikts fokuss uz galveno formu.

22

Tagad nepieciešams izveidot jaunu pogu formā „products”. Šo pogu nosauksim par „close_form” un tās uzrakstā (caption) norādīsim „Aizvērt”. Lai piesaistītu šo pogu pie iepriekš izveidotajām funkcijām, atvērsim šīs pogas īpašību modificēšanas logu un tā sadaļā „Events” īpašībā „On Click” norādīsim „Event procedure”, tādejādi pogas nospiešanai piekārtojot atbilstošās funkcijas (nu labi, procedūras) izsaukumu, kurai vajadzētu izskatīties sekojoši:

Private Sub close_form_Click() handleClose MeEnd Sub

Šeit vienkārši tiek izsaukta iepriekš aprakstītā procedūra „handleClose”, kurai kā parametrs tiek nodots mainīgais „Me”, kas ir rādītājs uz pašreizējo formu.

Līdz ar visu augstāk minēto darbību izpildi, esam ieguvuši vēlamo rezultātu un beidzot varam aplūkot sava darba augļus (sk. Att. 3.34) un pārliecināties formas darbības korektumu.

Att. 3.34 – forma “products” lietotāja režīmā

Kad esam pārliecinājušies par formas darbības korektumu, varam pāriet pie nākošās formas izstrādes.

23

3.3. Pakārtota formaŠo formu veidosim informācijas par pirkumiem ievadei un nosauksim šo formu par

„sales”. Forma sastāvēs no divām daļām, proti, galvenās un apakšformas. Galvenajā formas daļā paredzēsim informācijas ievadi par pirkumiem (dati tabulā „sales”), bet apakšformā paredzēsim datu ievadi par pirkumos pārdotajām precēm un to skaitu, kā arī kopējo summu, kas būs vienāda ar preču skaita un to cenas reizinājumu. Galvenajā formā vēl paredzēsim informācijas izvadi par kopējo pirkuma summu. Vēl viens nepieciešamais nosacījums – ja kopējā pirkuma summa ir 500 vai vairāk latu, tad, gadījumā, ja pircējs norēķinās ar kredītkarti, klientam nepieciešams uzrādīt personu apliecinošu dokumentu. Pārdevēji šo niansi bieži vien aizmirst, tādēļ paredzēsim galvenajā formā vēl vienu lauku, kura vērtība būs ar melniem burtiem uz zaļa fona „Dokumentus nevajag!”, ja kopējā pirkuma summa būs mazāka par 500LS, bet ar melniem burtiem uz sarkana fona „DOKUMENTUS VAJAG!” pretējā gadījumā.

Sāksim ar galvenās formas izveidi. Šoreiz izmantosim formu veidošanas veidni un sākumā izveidosim vienkāršu formu datu ievadei par pirkumiem, līdzīgu formai „products” kā tas aprakstīts iepriekš. Aplūkojam iegūto rezultātu (sk. Att. 3.35).

Att. 3.35 – formas “sales” galvenā daļa

Tagad ķersimies pie apakšformas izveides. Šo formu balstīsim uz sekojošu vaicājumu, kuru nosauksim par „sales_subform_src”:

SELECT psl.sale_id, psl.product_id, psl.psl_product_count, psl.psl_product_count * p.product_price AS total, psl.id_pslFROM products AS p INNER JOIN products_sales_linked AS psl ON p.id_product=psl.product_idORDER BY psl.sale_id;

Šeit iegūstam datus par pirkuma identifikatoru, produktu (īstenībā gan produkta identifikatoru, bet tā kā tabulas „products_sales_linked” lauka „product_id” īpašību sadaļa „Lookup” ir atbilstoši aizpildīta (šī aizpildīšana sīki un smalki aprakstīta iepriekšējos darbos, tādēļ to šeit neaplūkosim), tad šajā laukā redzēsim nevis plikus skaitļus, bet gan mūs interesējošo informāciju par produktu), attiecīgā produkta skaitu pirkumā, kā arī kopējo cenu katram produktam, kā tas bija ieplānots jau iepriekš.

Tagad pienācis laiks izveidot un ievietot formā „sales” nepieciešamo apakšformu. Šo apakšformu veidosim, izmantojot apakšformu ievietošanas veidni. Lai to izsauktu, nepieciešams

24

izvēlēties „Subform/Subreport” no standarta rīkjoslas „Toolbox” (sk. Att. 3.36) un izvietot veidojamo apakšformu nepieciešamajā formas vietā.

Att. 3.36 – apakšformas ievietošanas veidņa izsaukšana

Pēc minēto darbību izpildes, ekrānā parādās apakšformas ievietošanas veidnis (sk. Att. 3.37)

Att. 3.37 – apakšformas ievietošanas veidnis

Šeit norādīsim, ka vēlamies izmantot eksistējošu vaicājumu, izvēloties „Use existing Tables and Queries” (principā varēja vispirms izveidot apakšformu un tad tās vārdu norādīt šeit, taču, pēc autora domām, izvēlētais variants ir vienkāršāks un vieglāk saprotams) un nospiežot „Next”. Tagad nepieciešams norādīt vajadzīgo vaicājumu vai tabulu, kura kalpos par apakšformas datu avotu (sk. Att. 3.38), kā arī atbilstošos datu laukus. Šeit autors vēlas atzīmēt, ka datu avots var sastāvēt no vairāku tabulu vai vaicājumu laukiem un tātad var tikt noģenerēts automātiski, un iepriekš uzrakstītais vaicājums varētu arī nebūt nepieciešams, taču, pēc autora domām, labi pārdomātā sistēmā būtu jāsāk ar vaicājumu un tad uz tā bāzēt formu, nevis visādos veidņos uz labu laimi saklikšķināties visādas pogas un tad brīnīties par iegūtā rezultāta neatbilstību vēlamajam. Tātad, atgriežoties pie mūsu veidojamās apakšformas, norādām laukā „Tables/Queries” iepriekš izveidoto vaicājumu „sales_subform_src”, ievietojam no sadaļas „Available fields” sadaļā „Selected fields” visus nepieciešamos laukus (mūsu gadījumā visus laukus) un spiežam „Next”

25

Att. 3.38 – veidojamās apakšformas datu avota izvēle

Tagad nepieciešams izvēlēties kādā veidā apakšforma tiks saistīta ar galveno formu (sk. Att.3.39).

Att. 3.39 – formu sasaistes definēšana

Ja datu bāzes struktūra ir izveidota kā nākas, tad vairumā gadījumu veidnis pats piedāvās pareizo risinājumu kā noklusēto. Šoreiz pieņemsim, ka tā nav, un izvēlēsimies „Define my own”, kas atļaus mums pašiem definēt nepieciešamo sasaisti, ko realizēsim sasaistot galvenās formas lauku „id_sale” ar pakārtotās formas lauku „sale_id”, tātad laukā „Form/report” norādām „id_sale” un „Subform/subreport fields” attiecīgi „sale_id”. Pēc šo darbību izpildīšanas spiežam „Next”. Pēdējais ko atlicis padarīt, ir apakšformas nosaukuma izvēle un norādīšana (sk. Att. 3.40).

26

Att. 3.40 – apalšformas nosaukuma norādīšana

Nosauksim šo formu par „subform_sales” un nospiežam „Finish”, lai beigtu darbu pie apakšformas izveidošanas. Tagad modificēsim jaunizveidotās formas īpašības. Īpašībā „Default view” norādām „Datasheet”, lai šī forma pēc noklusējuma atvērtos režīmā, kas līdzīgs tabulārajam, un īpašībā „Navigation buttons” norādām „No”, jo veidosim paši savas navigācijas pogas, kā tas jau aprakstīts iepriekš.

Ķersimies klāt pie navigācijas pogu veidošanas apakšformai. Tā kā apakšforma tiks aplūkota „Datasheet” režīmā, tad navigācijas pogas ievietosim galvenajā formā. Tā kā autoram nav zināms neviens veids, kā būtu iespējams realizēt navigāciju apakšformā no galvenās formas izmantojot makrokomandas (ja, piemēram, ieliktu galvenajā formā pogu, kuras notikumam „On click” piekārtotu makrokomandu, kurā tiktu realizēta darbība „GotoRecord” un laukā „Object Type” būtu vērtība „Form”, „Object name” būtu „subform_sales”, bet „Record” būtu „Next”, tad nospiežot šo pogu, lietotājs saņemtu „laipnu” kļūdas paziņojumu ar paskaidrojumu, kurā teikts, ka attiecīgā forma nav atvērta – pamēģiniet paši – nekas nestrādās un vēlamais rezultāts netiks iegūts. Šeit prātā nāk tehnikuma datu bāzu pasniedzēja zelta vārdi „nekad neizmantojiet makrosus – tādos erroros iedzīvosieties”), tad šī mērķa realizācijai izmantosim VBA skriptu. Papildināsim moduli „public_functions” ar šādu procedūru:

Public Sub gotoSubRec(sub_f As Form, rec As Integer) Dim res As Recordset Set res = sub_f.Recordset On Error Resume Next Select Case rec Case acNext res.MoveNext Case acPrevious res.MovePrevious Case acLast res.MoveLast Case acFirst

27

res.MoveFirst Case acNewRec res.AddNew End Select End Sub

Šai procedūrai kā parametrus nodod vēlamo formu (mūsu gadījumā apakšformu) un vēlamo ierakstu, uz kuru nepieciešams pārvietoties, kā veselu skaitli. Vēlamā ieraksta norādīšanai izmantosim iebūvētās Access konstantes „acNext”, „acPrevious”, „acLast”, „acFirst”, „acNewRec”, jo pēc autora domām tās pilnībā atbilst nospraustā mērķa sasniegšanai (kāpēc gan velosipēds būtu jāizgudro no jauna?), kurām piešķirsim nozīmi attiecīgi – „pāriet uz nākošo ierakstu”, „pāriet uz iepriekšējo ierakstu”, „pāriet uz pēdējo ierakstu”, „pāriet uz pirmo ierakstu” un „pāriet uz jaunu ierakstu”. Procedūras darbības algoritms ir šāds, proti, noteikt, kura no minētajām konstantēm tai ir nodota un tad izpildīt attiecīgo darbību (pārvietoties pa ierakstiem). Lai realizētu pārvietošanos pa ierakstiem tiek izmantots formas objekts „recordset”, kura metodes izsaucot, tad arī tiek sasniegts vēlamais rezultāts. Šeit autors vēlas atzīmēt rindiņu „On Error Resume Next”, ar kuras palīdzību tiek „novērstas” dažas kļūdas. Proti, šī rindiņa definē, ka, ja kādas no tālāk sekojošām darbībām rezultātā rodas kļūda, tad to ignorē un pāriet uz nākošo darbību, it kā nekas nebūtu noticis. Šī rindiņa nepieciešama, lai pasargātu lietotāju no kļūdām, kas saistītas ar jauna ieraksta pievienošanu (ja fokuss dotajā brīdī neatrodas formā vai jau atrodas uz jauna ieraksta, bet, kā mēs visi zinām, tad lietotājam neinteresē nekas cits kā bezjēdzīga klikšķināšanās nevajadzīgajās vietās, pat tad, ja veicot šādas darbības rodas neparedzētas situācijas).

Tātad ar navigācijas pogu kodēšanu daudzmaz skaidrībā esam tikuši. Paliek ierakstu dzēšana apakšformā. Protams, to tīri teorētiski varētu vienkārši realizēt ar makrokomandu „RunCommand acCmdDeleteRecord”, kā arī sākumā tika plānots, taču ikviens normāls cilvēks 50-to reizi ekrānā aplūkojot paziņojumu „NO CURRENT RECORD” ne pa jokam pārskaitīsies un sapratīs, ka makrokomandas nekam neder un izveidos vienkāršu universālu procedūru, izmantojot SQL vaicājumu, ar kuras palīdzību šo darbību var realizēt bez problēmām un galvenais – bez kļūdām. Tā rīkosimies arī mēs un papildināsim mūsu moduli „public_functions” ar vēl vienu procedūru:

Public Sub handleDelete(f As Form, table As String, id As String, id_field As TextBox) Dim q As String If (id_field.Value) Then q = "delete from " & table & " where " & id & " = " & id_field.Value DoCmd.RunSQL q f.Requery End If

End Sub

Šai procedūrai kā parametri tiek nodota forma, no kuras ierakstu nepieciešams dzēst, tabula, kurā šis ieraksts fiziski atrodas, minētās tabulas id lauka nosaukums, kā arī tas formas lauks, kurš sevī glabā pašreizējā ieraksta identifikatoru. Procedūras darbības algoritms ir sekojošs, proti, ja attiecīgās formas laukā, kurš glabā pašreizējā ieraksta identifikatoru ir ievadīta kāda vērtība (parasti tas notiek automātiski, tātad, ja vērtība tajā ievadīta nebūs, tad lietotājs mēģinās izdzēst tukšu ierakstu – vot āpsis), tad tiks izdzēsti visi ieraksti ar atbilstošo vērtību attiecīgajā laukā, taču, tā kā minētais lauks ir atslēgas lauks (vismaz tā ir paredzēts), tad tiks izdzēsts tikai viens, proti, pašreizējais ieraksts. Praktiski tas tiek realizēts dinamiski izveidojot vaicājumu un to

28

izpildot, izmantojot makrokomandu „RunSQL”. Vēl jāatzīmē, ka nepieciešams „atjaunināt” apakšformu pēc šādas ieraksta dzēšanas, jo šajā gadījumā tas nenotiek automātiski. Šī mērķa realizēšanai izpildām formas metodi „Requery”.

Tagad, kad esam uzrakstījuši atbilstošās procedūras, nepieciešams veikt šo procedūru izsaukumu piesaisti attiecīgajām formas darbībām. Pogai „close_form”, kura paredzēta formas aizvēršanai un fokusa nodošanai galvenajai formai notikumam „On Click”, līdzīgi kā iepriekš aprakstītajai formai, piekārtojam procedūras „handleClose” izsaukšanu, kā parametru nododot rādītāju uz pašreizējo formu ar mainīgā „Me” palīdzību:

Private Sub close_form_Click() handleClose MeEnd Sub

Šeit viegli pamanīt VBA priekšrocību pār makrokomandām, jo, ja šī mērķa sasniegšanai tiktu izmantota makrokomanda, tad šajā brīdī vajadzētu nevis vienkārši izsaukt jau uzrakstītu funkciju, bet gan veidot jaunu makrokomandu, un tad to piekārtot attiecīgajam notikumam, kas tikai visu sarežģītu. Tālāk pievienojam apakšformas ieraksta dzēšanas pogas notikumam „On Click” sekojošas rindiņas:

Private Sub sub_del_rec_Click()

Me.subform_sales.Form.product_id.SetFocus handleDelete Me.subform_sales.Form, "products_sales_linked", "id_psl", Me.subform_sales.Form.id_psl End Sub

Šeit no sākuma tiek iestatīts fokuss uz apakšformu „subform_sales” (nepieciešams, lai pilnīgi noteikti nodrošinātu pašreizējā ieraksta esamību un izvairītos no kļūdām, kas ar to saistītas. Gadījumā ar makrokomandu šis paņēmiens neko nedeva, taču šajā gadījumā viss ir kedā), pēc tam tiek izsaukta procedūra „handleDelete”, kurai kā parametri tiek padota apakšforma, tabulas „products_sales_linked” nosaukums (jo tā ir tabula, no kuras fiziski dzēšams ieraksts), kā arī tikko pieminētās tabulas identifikācijas lauka nosaukums „id_psl” un apakšformas lauks, kurš satur dzēšamā ieraksta identifikatoru.

Tagad piekārtojam galvenās formas pogām, kuras domātas apakšformas navigācijai, notikumiem „On Click” procedūras „gotoSubRec” izsaukumu, kā parametru nododot apakšformu un konstanti, ar kuras palīdzību iespējams norādīt uz kuru ierakstu nepieciešams pārvietoties:

Private Sub sub_first_rec_Click() gotoSubRec Me.subform_sales.Form, acFirstEnd Sub

Private Sub sub_last_rec_Click() gotoSubRec Me.subform_sales.Form, acLastEnd Sub

Private Sub sub_new_rec_Click() gotoSubRec Me.subform_sales.Form, acNewRecEnd Sub

Private Sub sub_next_rec_Click()

29

gotoSubRec Me.subform_sales.Form, acNextEnd Sub

Private Sub sub_prev_rec_Click() gotoSubRec Me.subform_sales.Form, acPreviousEnd Sub

Pēdējais ko atlicis izdarīt ir apakšformas notikumam „On Current” pakārtot šādu procedūru:

Private Sub Form_Current() Me.Parent.id_sale.SetFocus handleNavigation Me, Me.Parent.sub_rec_count, Me.Parent.sub_curr_rec, Me.Parent.sub_prev_rec, Me.Parent.sub_next_recEnd Sub

Šeit sākumā fokuss tiek pārslēgts uz galvenās formas lauku „id_sale”. Tas nepieciešams tādēļ, lai novirzītu fokusu no nospiestās navigācijas pogas, jo kā zināms, procedūra „handleNavigation” pie noteiktiem apstākļiem (pirmā vai pēdējā ieraksta sasniegšanas) var padarīt darba nespējīgu (disable) vienu vai abas navigācijas pogas, kuras atbild par pārvietošanos uz nākošo un iepriekšējo ierakstu, taču nav iespējams padarīt darba nespējīgu formas elementu un kura dotajā laika momentā ir uzstādīts fokuss, tādēļ, lai izvairītos no iespējamajām kļūdām, fokuss tiek novirzīts. Šeit fokusu varētu pārstādīt pilnīgi uz jebkuru galvenās formas elementu (atskatot minētās navigācijas pogas, protams), tā kā lauks „id_sale” ir izvēlēts uz labu laimi un tam nav nekādas nozīmes tālākā procedūras darbībā. Nākošajā rindiņā tiek izsaukta jau pieminētā procedūra „handleNavigation”, kurai kā parametrus nodod apakšformu, kas mūsu gadījumā ir pašreizējā forma, tad lauku, kurā glabājas ierakstu skaits un lauku, kurā glabājas pašreizējais ieraksts, kā arī attiecīgās pogas, kuras, kā jau iepriekš minēts, pie noteiktiem apstākļiem nepieciešams padarīt darba nespējīgas.

Ja viss augstāk minētais izpildīts pareizi, tad esam veiksmīgi tikuši galā ar ierakstu navigāciju, kā arī jauna ieraksta pievienošanu apakšformā. Tagad nepieciešams izveidot galvenajā formā lauku, kurā būs redzama visa pirkuma kopējā summa. Lai realizētu šo uzdevumu, sākumā apakšformā „subform_sales”, sadaļā „Form footer” ievietosim jaunu teksta lauku, kuru nosauksim „total_sum” un kura īpašībā „Control Source” ierakstām „=Sum([total])”. Tas nozīmē, ka šajā laukā tiks atspoguļota informācija par kopējo lauka „total”, kurā savukārt tiek atspoguļota produkta cena, pareizināta ar pārdoto produktu daudzumu, summu no visiem atbilstošajiem ierakstiem. Tagad arī galvenajā formā ievietosim jaunu teksta lauku, kuru arī nosauksim „total_sum”. Šim laukam īpašībā „Control Source” norādām „=subform_sales.Form!total_sum”, kas nozīmē, ka tā vērtība atspoguļos apakšformas lauka „total_sum” vērtību. Šeit varētu rasties jautājums – kāpēc gan izmantot divus laukus, ja varētu iztikt ar vienu. Lūk, arī skaidrojums, proti, šāda pieeja nepieciešama tādēļ, ka galvenās formas laukā, kas ievietots tās „Detail” sekcijā, pa tiešo nekādi nevar norādīt agregātfunkciju, kas kā parametru izmanto kādu apakšformas lauku, taču jau pieminētajā galvenās formas laukā var norādīt kādu apakšformas lauka vērtību, kuram šī agregātfunkcija ir piesaistīta, ko mūsu gadījumā arī izmantojām.

Tagad realizēsim ideju, par lauku, kura vērtība un fona krāsa mainās atkarībā no pirkuma kopējās cenas. Vispirms formā „sales” ievietosim jaunu standarta elementu (kura vērtību un fona krāsu tad arī mainīsim), „Label”, kuru nosauksim par „is_id_needed”. Tagad nepieciešams realizēt ar šo lauku paredzēto darbību izpildi. Šim mērķim mēģināsim izveidot makrokomandu (protams, ērtāk to ir realizēt ar VBA skriptu, bet tā kā viens no šī darba noteikumiem ir makrokomandu pielietošana, tad mēģināsim izveidot vismaz vienu). Tātad, lai izveidotu makrokomandu, nepieciešams izvēlēties galvenā datu bāzes loga sadaļā „Macros” komandu „New” (sk. Att. 3.41).

30

Att. 3.41 – jaunas makrokomandas veidošana

Izpildot šo darbību, ekrānā parādās jaunas makrokomandas veidošanas logs (sk. Att. 3.42).

Att. 3.42 – jaunas makrokomandas veidošanas logs

Vienkāršākajā gadījumā šeit parādās divas kolonnas, proti, „Action”, kas paredzēta izvēlētās darbības norādīšanai un „Comment”, kurā iespējams ierakstīt komentārus. Šeit tad arī var „plosīties”, norādot nepieciešamo darbību un komentējot to. Mēs veidosim nedaudz sarežģītāku makrokomandu, tādēļ ieslēgsim vēl divas kolonnas, proti, „Macro name” un „Condition”, ko iespējams izdarīt nospiežot attiecīgās standarta rīkjoslas pogas (sk. Att. 3.43).

Att. 3.43 – attiecīgo kolonnu ieslēgšana ar rīkjoslas palīdzību

31

Izpildot šīs darbības ekrānā redzams, pēc autora domām, pilnvērtīgs makrokomandas veidošanas logs (sk. Att. 3.44).

Att. 3.44 – “pilnvērtīgs” makrokomandas veidošanas logs

Nedaudz pakomentēsim minēto divu papildus kolonnu ieslēgšanas mērķi. Tātad, kolonā „Macro name” iespējams norādīt tekošo makrokomandas nosaukumu. Varētu rasties jautājums: „Kādēļ gan norādīt makrokomandas nosaukumu šajā laukā, ka to norāda jau pie makrokomandas saglabāšanas?”. Lūk, arī atbilde, proti, ar šīs komandas palīdzību iespējams vienā makrokomandas failā glabāt vairākas (vairāk par vienu) makrokomandas. Izmanto, piemēram, gadījumā, kad vienai formai nepieciešams izmantot vairākas makrokomandas, tad iespējams izveidot makrokomandu un nosaukt to kaut vai formas vārdā, bet iekšā nodefinēt vairākas makrokomandas. Piekļuvi pie šādi izveidotām makrokomandām realizē izmantojot sekojošu principu: makrokomandas_nosaukums.makrokomanda_no_kolonnas „macro_name”, piemēram, „mans_makro.pirma_komanda”. Kolonnā „Condition”, savukārt, iespējams norādīt nosacījumu, kuram obligāti jāizpildās, lai tiktu izpildīta kolonnā „Action” norādītā darbība. Lai būtu iespējams nodrošināt vairāku darbību izpildīšanos, gadījumā, ja minētais nosacījums ir patiess, bet katru reizi kolonnā „Condition” nebūtu jāraksta viena un tā pati izteiksme, tad, lai norādītu to, ka pašreizējā izteiksme ir tāda pati, kā iepriekšējā, kolonnā norāda „...”.

Tagad, kad makrokomandu veidošanas vide iestatīta kā nākas, varam ķerties klāt pie pašas makrokomandas izstrādes. Šo makrokomandu nosauksim par „is_id_needed” (tieši tā iepriekš tika nosaukts formas lauks, ar kuru veiksim nepieciešamās operācijas, tādēļ arī izvēlamies tieši tādu pašu nosaukumu, lai nejauktu galvu), un tā arī norādām laukā „Macro Name”. Tagad nepieciešams izvēlēties attiecīgos nosacījumus un darbības, kuras veicamas to izpildīšanās gadījumā. Atcerēsimies, ka ja kopējā pirkuma cena ir mazāka par 500 latiem, tad formas „sales” laukā „is_id_needed” jāieraksta vērtība „Dokumentus nevajag” un tā fons jānomaina uz zaļu. Tātad, šeit būtu jāpārbauda vai formas „sales” lauka vērtība ir mazāka par 500 un tad izpildīt attiecīgas darbības. Šī mērķa sasniegšanai, laukā „Condition” rakstām „[Forms]![sales]![total_sum]<500”. Tagad jānorāda atbilstošā darbība, kura tiks veikta, izpildoties šim nosacījumam. Kā pirmo aplūkosim lauka vērtības maiņu, tātad laukā „Action”, kurš atrodas pretī (vienā rindā) iepriekš uzrakstītajam nosacījumam, iestādām „SetValue” un veicam atbilstošo parametru uzstādīšanu, proti, parametrā „Item” norādām „[Forms]![sales]![is_id_needed].[Caption]”, kas apzīmē attiecīgā formas elementa īpašību, kuru nepieciešams mainīt, kā arī parametrā „Expression” norādām „"Dokumentus nevajag!"”, kas arī būs mūsu

32

iestatāmā vērtība. Tā kā gadījumā, ja izpildās iepriekšējais nosacījums, nepieciešams izpildīt vēl vienu darbību, tad nākošajā rindiņā, laukā „Condition” norādām „...”. Kā nākamo aplūkosim fona krāsas maiņu. Šim nolūkam laukā „Action” iestatām „SetValue” un tā parametrā „Item” norādām „[Forms]![sales]![is_id_needed].[BackColor]”. Tagad jānorāda nepieciešamā krāsa, jeb precīzāk, tās kods. Šajā brīdī var aizdomāties, hmm., kāds gan varētu izskatīties zaļās krāsas kods MS Access. Kas gan to labāk varētu zināt par tanti Gūgli, tādēļ uzjautājam viņai (sk. Att.3.17).

Att. 3.45 – nepieciešamā krāsu koda meklējumi

Šeit, pēc autora domām, pietiekami zaļš izskatās tonis ar nosaukumu „chartreuse 4” un atbilstošo MS Access krāsas kodu „35653”, kuru tad arī norādām parametrā „Expression”. Līdz ar to esam apstrādājuši gadījumu, kad kopējā pirkuma summa ir mazāka par 500 latiem. Tagad nepieciešams apstrādāt pretējo gadījumu, proti, kad kopējā pirkuma summa ir lielāka vai vienāda ar 500 latiem. Šo gadījumu apstrādāsim analoģiski kā iepriekšējo, papildinot veidojamo makrokomandu ar divām rindiņām. Pirmajā no kurām norādīsim nosacījumu „[Forms]![sales]![total_sum]>=500” un atbilstošo darbību „SetValue”, kuras parametros „Item” un „Expression” norādīsim attiecīgi „[Forms]![sales]![is_id_needed].[Caption]” un „DOKUMENTUS VAJAG!”. Otrajā rindiņā laukā „Condition” norādām „...”, „Action” norādām „SetValue” ar parametriem „Item” - „[Forms]![sales]![is_id_needed].[BackColor]” un „Expression” – „858083” (pēc autora domām pietiekoši sarkans tonis, ņemts no iepriekšējā attēlā redzamās tabulas).

Tagad esam pabeiguši darbu pie makrokomandas izveides, saglabājam to ar nosaukumu „sales”, līdzīgi kā formu, kurai to grasāmies piesaistīt, lai vēlāk to būtu vienkārši papildināt ar

33

jaunām makrokomandām, nešauboties par to piederību („sales” tikai makrokomandām, kas domātas formai „sales”). Izveidotā makrokomanda redzama Att. 3.46.

Att. 3.46 – izveidotā makrokomanda

Tagad nepieciešams piekārtot šo makrokomandu vēlamajam formas notikumam. Tā kā makrokomanda balstās uz galvenās formas lauku „total_sum”, kura vērtība dinamiski manās, kaut vai pārejot no viena ieraksta uz otru galvenajā formā, tad, lai pārbaudītu izveidotās makrokomandas darbības korektumu, piekārtojam to sākumā tikai formas „sales” notikumam „On Current” (reāli, ja viss strādās kā nākas, pieķēdēsim makrokomandu vēl šur tur, bet pagaidām tikai pārbaidīsim iegūto rezultātu). Tā kā šim notikumam jau ir piekārtota procedūra, ar kuras palīdzību tiek izsaukta procedūra „handleNavigation” (sk. augstākminēto), tad papildināsim šo procedūru ar vēl vienu rindiņu, proti:

DoCmd.RunMacro "sales.is_id_needed"

Šeit tiek izsaukta makrokomanda „RunMacro”, kurai kā parametrs tiek padots jaunizveidotās makrokomandas vārds, tādejādi realizējot tās izpildi. Varam aplūkot iegūto rezultātu (sk. Att.3.47).

Att. 3.47 – iegūtais rezultāts

Pēc rezultāta aplūkošanas rupji nolamājamies un mēģinām sevi savaldīt lai nesasistu monitoru lupatu lēveros. Kaut kāda iemesla dēļ vērtības ierakstīšanās galvenās formas laukā „total_sum” tiek aizkavēta par apmēram ½ sekundi (sk. Att. 3.48, Att. 3.49), īpaši tas pamanāms, kad pārvietojas starp ierakstiem – minēto laika sprīdi šis lauks ir tukšs un tikai pēc tam tajā parādās vēlamā vērtība, taču tā kā tieši šajā laika sprīdī tā vērtība tiek nolasīta un padota uz tikko izveidoto makrokomandu, tad tā vienmēr būs mazāka par 500 (jo tā ir nulle) un smejies vai raudi, lauka „is_id_needed” vērtība visu laiku būs ar melniem burtiem uz zaļa fona „Dokumentus nevajag!”.

34

Att. 3.48 – lauks “total_sum” uzreiz pēc ieraksta pārslēgšanas

Att. 3.49 – lauks “total_sum” apmēram ½ sekundi pēc ieraksta pērslēgšanas

Tagad dzēšam ārā izveidoto makrokomandu, nozvēramies nekad mūžā vairs neveidot makrokomandas (kurš teica, ka ar tām varot ātri un ērti veikt darbības un tādejādi izvairīties no kodēšanas? Pēc autora domām tikko veiktā darbība, proti, makrokomandas veidošana, bija tikai un vienīgi lieka laika izšķiešana, jo, kā redzams, vēlamais rezultāts nav sasniegts, tad vēl tā nervu bojāšana ar šīs makrokomandas kabināšanu klāt visiem notikumiem pēc kārtas, cerībā, ka kaut ko autors ir aizmirsis un, ka tūliņ viss strādās.) un atveram VBA redaktoru. Šeit formai „sales” pakārtoto moduli papildinām ar sekojošu procedūru:

35

Public Sub handleIdNeeded() On Error Resume Next If (Me.id_sale.Value) Then Dim db As Database Dim res As Recordset Dim q As String Dim i As Integer Set db = CurrentDb i = 0 Dim vals(0 To 1) As String Dim colors(0 To 1) As Long vals(0) = "Dokumentus nevajag!" vals(1) = "DOKUMENTUS VAJAG!" colors(0) = 35653 'zaljsh colors(1) = 858083 'sarkans q = "SELECT sum(psl.psl_product_count*p.product_price) AS total " q = q & "FROM products AS p INNER JOIN products_sales_linked AS psl ON p.id_product=psl.product_id " q = q & "WHERE psl.sale_id = " & Me.id_sale & " " q = q & "GROUP BY psl.sale_id " Set res = db.OpenRecordset(q) If (res(0) >= 500) Then i = 1 Me.is_id_needed.Caption = vals(i) Me.is_id_needed.BackColor = colors(i) End IfEnd Sub

Šīs procedūras izsaukumu piekārtojam formas notikumam „On Current”, papildinot jau esošo procedūru ar rindiņu:

Me.handleIdNeeded

Pārbaudām iegūto rezultātu (sk. Att. 3.50).

Att. 3.50 – iegūtais rezultāts, dublis divi

36

Kā redzams, iegūtais rezultāts ir pareizs, pie tam parādās ievērojami ātrāk nekā atjauninās lauka „total_sum” vērtība. Tagad piekabināsim šo procedūru vēl dažiem notikumiem, lai nodrošinātu lauka „is_id_needed” atjaunināšanu jebkurā gadījumā. Tātad, piesaistām to apakšformas notikumiem „On Current” un „After Insert”, papildinot tiem piesaistītās procedūras ar sekojošu rindiņu:

Me.Parent.handleIdNeeded

Tagad veicam iegūtā rezultāta pārbaudi. Var secināt, ka vairumā gadījumu lauka „is_id_needed” vērtība un fona krāsa tiek norādīta pareizi. Izņēmums ir jauna ieraksta pievienošana apakšformā, kad nezināmu iemeslu dēļ (īstenībā jau iemesls tā kā būtu – procedūras „handleIdNeeded” izsaukums nenotiek tā kā tam būtu jānotiek, proti, pēc jauna ieraksta ievietošanas, jo tās izsaukšana tika piesaistīta notikumam „After Insert” un pēc loģikas, veicot jauna ieraksta ievietošanu tai vajadzētu tikt izsauktai, bet ko lai dara, ja Access domā savādāk?), lauka „is_id_needed” parametri netiek atjaunināti, turklāt lauka „total_sum” vērtība tiek atjaunināta tikai pēc pāriešanas uz galveno formu. Tātad, lai nesarežģītu dzīvi ne sev, ne lietotājam, ievietosim galvenajā formā vēl vienu pogu „Pārrēķināt” un piesaistīsim tās notikumam „On Click” procedūras „handleIdNeeded” izsaukumu. Tagad tikai jāpiekodina lietotājam, lai pēc kādām darbībām apakšformā, tiktu nospiesta pieminētā poga un formas darbības korektums būs nodrošināts. Kā pēdējo formā ievietosim pogu „Aizvērt”, kuras notikumam „On Click” piekārtosim procedūras „handleClose” izsaukšanu, kā parametru nododot rādītāju uz pašreizējo formu, izmantojot mainīgo „Me”.

Līdz ar visu augstākminēto darbību korektu izpildi, mūsu rīcībā tagad vajadzētu būt pilnīgi pabeigtai pirkumu ievades formai (sk Att. 3.51). Tagad varam ķerties pie nākošās formas izstrādes.

37

Att. 3.51 – pilnībā pabeigta pirkumu ievades forma

38

3.4. Forma ar ieliktnīšiemŠo formu veidosim no četrām daļām, proti, pamatdaļas un trīs ieliktnīšiem. Kā datu avotu

izvēlēsimies informāciju par darbiniekiem. Šī būs informatīva forma ar vairākiem kopsavilkumiem, tādēļ datu ievadi un rediģēšanu šeit neiekļausim. Pamatdaļā būs redzams darbinieka identifikators, vārds uzvārds un personas kods. Pirmajā ieliktnītī tiks attēlota pārējā informācija par darbinieku (adrese, e-pasts, mobilā un stacionārā telefona numuri, kā arī alga, izteikta latos). Otro ieliktnīti paredzēsim informācijas par darbinieka pārdotajām precēm izvadīšanai. Šeit būs redzams kādas preces kādā daudzumā un par kādu summu darbinieks ir pārdevis, kā arī tiks attēlots kopējais pārdoto preču skaits un to kopējā summa. Trešajā ieliktnītī attēlosim informāciju par darbinieka apkalpotajiem pirkumiem pa datumiem. Šeit paredzēsim iespēju aplūkot informāciju par apkalpoto pirkumu skaitu attiecīgajos datumos un ienākumus no tiem, kā arī to kopējo skaitu un kopējo ienākumu summu.

Sāksim darbu pie formas izveides. Vispirms izveidosim formas pamatdaļu. To realizēsim, veidojot vienkāršu datu ievades formu, kas balstīta uz tabulu „workers”, izmantojot formu veidošanas veidni, kā tas aprakstīts iepriekš. Iegūto formu nosauksim „tabs”. Pēc tam iegūtajā formā ievietosim ieliktnīšu kontroles elementu (Tab Control), izvēloties no standarta rīkjoslas „Toolbox” elementu „Tab Control” (sk. Att. 3.52) un novietojot to nepieciešamajā formas vietā.

Att. 3.52 – ieliktnīšu kontroles elementa izvēlne

Pēc noklusējuma formā tiks ievietoto divi ieliktnīši, taču mums nepieciešami trīs, tātad nepieciešams pievienot vēl vienu. Lai to realizētu, nepieciešams nospiest labo peles ausi uz ieliktnīšu kontroles elementa un no saraksta izvēlēties „Insert page” (sk. Att. 3.53)

Att. 3.53 – ieliktnīša pievienošana

Nomainīsim ieliktnīšu īpašību „Caption” vērtības, proti, pirmajam no tiem minētajā īpašībā uzstādīsim „Detaļas”, otrajam - „Pārdotās preces”, trešajam – „Apkalpotie pirkumi”. Tagad visus formas laukus, izņemot tos, kuri satur informāciju par darbinieka vārdu, uzvārdu, personas kodu

39

un identifikatoru, pārvietojam uz pirmo ieliktnīti. Dažreiz to izdarīt varētu būt grūtības, un lauki gluži vienkārši tiks uzlikti virsū ieliktnīšu kontroles elementam, nevis ievietoti kādā konkrētā ieliktnīti. Lai no tā izvairītos, iespējams izmantot izgriešanas un ievietošanas (cut – paste) stratēģiju, proti, uz laukiem, kurus nepieciešams ievietot attiecīgajā ieliktnīti, izpildām komandu „Edit->Cut”, tad izvēlamies vajadzīgo ieliktnīti un izpildām komandu „Edit->Paste”. Tagad nedaudz piestrādājam pie noformējuma un aplūkojam iegūto rezultātu (sk. Att. 3.54)

Att. 3.54 – iegūtais rezultāts

Aplūkojot iegūto rezultātu, var secināt, ka esam veiksmīgi izveidojuši pirmo no trim ieliktnīšiem. Pārejam pie otrā ieliktnīša, kurā nepieciešams atspoguļot informāciju par pašreizējā darbinieka pārdotajām precēm. Šī uzdevuma realizācijai izmantosim apakšformu, kuru tad arī ievietosim atbilstošajā ieliktnītī. Lai izveidotu apakšformu, vispirms izveidosim vaicājumu, kurš kalpos par tās datu avotu. Tātad, veram vaļā vaicājumu veidošanas logu un tajā iedrukājam sekojošu vaicājumu:

SELECT s.worker_id, ( prt.product_type_title + ' ' + m.manufacturer_title + ' (' + pr.product_model + ')') AS product, sum(psl.psl_product_count) AS sold, sum(psl.psl_product_count) * pr.product_price AS incomeFROM sales s INNER JOIN ( ( product_types prt INNER JOIN ( manufacturers m INNER JOIN products pr ON m.id_manufacturer = pr.manufacturer_id ) ON prt.id_product_type = pr.product_type_id ) INNER JOIN products_sales_linked psl ON pr.id_product = psl.product_id ) ON s.id_sale = psl.sale_idGROUP BY s.worker_id, ( prt.product_type_title + ' ' + m.manufacturer_title + ' (' + pr.product_model + ')'), pr.product_price;

40

Saglabāsim šo vaicājumu ar nosaukumu „tabs_products_sold_src” un aplūkosim tā darbības rezultātu (sk. Att. 3.55).

Att. 3.55 – vaicājuma „tabs_products_sold_src” darbības rezultāts

Tagad ievietojam formas „tabs” ieliktnītī „Pārdotās preces” apakšformu, kuru nosauksim „subforms_tabs_products_sold”, un kurai kā datu avotu norādām tikko izveidoto vaicājumu. Tā kā apakšformu ievietošana jau aprakstīta iepriekš (sk. augstākminēto), tad to tagad sīkāk neapskatīsim, vienīgais, ko autors vēlas pieminēt šajā sakarā, ir galvenās un apakšformas sasaiste, kas tiek realizēta, sasaistot galvenās formas lauku „id_worker” ar apakšformas lauku „worker_id”.

Tagad esam ieguvuši informāciju par darbinieka pārdotajām precēm, to skaitu un summu. Šeit trūkst tikai kopējais pārdoto preču skaits un to kopējā summa. Lai pievienotu šo informāciju, sākumā ievietosim apakšformā atbilstošus laukus, kuros glabāsies nepieciešamo agregātfunkciju darbību rezultāti un tad galvenajā formā ievietosim laukus, kuru vērtības piesaistīsim jaunizveidotajiem apakšformas laukiem, kā tas aprakstīts iepriekš. Tātad, apakšformas sadaļā „Form Footer” ievietojam laukus ar nosaukumiem „total_sold” un „total_income”, kuru īpašībās „Control Source” norādām attiecīgi „=Sum([sold])” un „=Sum([income])”. Pēc tam pārejam pie galvenās formas, kurā ievietojam laukus „total_sold” un „total_sum”, kuru īpašībās „Control Source” norādām attiecīgi „=subform_workers_products_sold.Form!total_sold” un „=subform_workers_products_sold.Form!total_income”. Tagad esam veiksmīgi beiguši darbu pie otrā no trim ieliktnīšiem izstrādes un varam aplūkot iegūto rezultātu (sk. Att. 3.56)

41

Att. 3.56 – ieliktnītis “Pārdotās preces”

Tagad ķeramies klāt pie pēdējā no trim, proti, ieliktnīša „Apkalpotie pirkumi” izstrādes. Arī šeit ievietosim apakšformu, kas balstīta uz vaicājuma. Vispirms izveidosim sekojošu vaicājumu:

SELECT DISTINCT s.worker_id, s.sale_date, sr.served, SUM (pr.product_price * psl.psl_product_count) AS earnedFROM ( SELECT s2.sale_date, s2.worker_id, COUNT(s2.worker_id) AS served FROM sales s2 GROUP BY s2.sale_date, s2.worker_id AS sr, products AS pr INNER JOIN ( sales AS s INNER JOIN products_sales_linked AS psl ON s.id_sale = psl.sale_id) ON pr.id_product = psl.product_idWHERE sr.worker_id = s.worker_id and sr.sale_date = s.sale_dateGROUP BY s.worker_id, s.sale_date, sr.served, sr.worker_id;

Saglabāsim šo vaicājumu ar nosaukumu „tabs_sales_served_src” un aplūkosim tā darbības rezultātu (sk. Att. 3.57).

42

Att. 3.57 – vaicājuma „tabs_sales_served_src” darbības rezultāts

Tagad, līdzīgi kā ieliktnītī „Pārdotās preces”, arī šeit ievietojam apakšformu, kurai kā datu avotu norādām tikko izveidoto vaicājumu. Nosauksim šo apakšformu „subform_tabs_sales_served” un sasaistīsim to ar galveno formu, piekārtojot galvenās formas laukam „id_worker” apakšformas lauku „worker_id”. Tātad esam veiksmīgi ieguvuši informāciju par darbinieku apkalpoto pirkumu skaitu un to kopējo summu pa dienām. Tagad nepieciešams galvenajā formā izvietot vēl divus laukus, kuros glabātos informācija par darbinieka apkalpoto pirkumu skaitu, kā arī šo pirkumu kopējo summu. Lai to realizētu, rīkosimies līdzīgi kā iepriekšējā gadījumā, proti, ievietosim apakšformā divus laukus, kuros norādīsim atbilstošās agregātfunkcijas, un tad galvenajā formā ievietotajiem laukiem piekārtosim šo apakšformas lauku vērtības. Tātad apakšformas „subform_tabs_sales_served” sadaļā „Form Footer” ievietojam laukus „total_served” un „total_earned”, kuru īpašībās „Control Source” norādām attiecīgi „=Sum([served])” un „=Sum([earned])”. Tagad ievietojam divus laukus, proti, „total_served” un „total_sum_served”, arī galvenajā formā un norādām to īpašībās „Control Source” attiecīgi „=subform_tabs_sales_served.Form!total_served” un „=subform_tabs_sales_served.Form!total_earned”. Tagad pabeigts darbs arī pie šī ieliktnīša izveidošanas un varam aplūkot iegūto rezultātu (sk. Att. 3.58).

Tagad varam ķerties klāt ierakstu navigācijai. Tā kā mūsu rīcībā ir jau izveidota procedūra „handleNavigation”, tad viss, ko atliek izdarīt, ir piekārtot tās izsaukumu galvenās formas notikumam „On Current”. Pašas ierakstu navigācijas pogas veidojam kā aprakstīts iepriekš (sk. augstākminēto), tādēļ to veidošanu šeit sīkāk neapskatīsim. Pēdējais, ko palicis izdarīt, ir izveidot pogu „Aizvērt”, kuru veidojam identiski kā iepriekšējā formā.

Ja visas iepriekš aprakstītās darbības izpildītas pareizi, formai vajadzētu būt pabeigtai, un tagad iespējams aplūkot iegūto rezultātu (sk. Att. 3.59).

43

Att. 3.58 – ieliktnītis “Apkalpotie pirkumi”

44

Att. 3.59 – forma ar ieliktnīšiem

45

3.5. Meklēšanas formaMeklēšanas formu veidosim informācijas par darbiniekiem meklēšanai, proti, šad tad

firmas direktors vēlas iegūt informāciju par darbinieka paveikto, lai tādējādi spriestu par pēdējā saņemamās algas atbilstību padarītajam. Šī uzdevuma veikšanā tad arī firmas direktoram izlīdzēsim. Izveidosim formu, kurā tiks atspoguļota informācija par darbiniekiem, kas sastāvēs no darbinieku vārdiem, uzvārdiem, personas kodiem un saņemamās darba algas, to apkalpoto pirkumu un pārdoto preču skaitu, kā arī to kopējo summu. Lai atvieglotu informācijas iegūšanu par kādu konkrētu darbinieku, ieviesīsim iespēju meklēt darbiniekus pēc to vārdiem, uzvārdiem un personas kodiem.

Minēto mērķu sasniegšanai izveidosim vienu formu. Tā sastāvēs no divām daļām, proti, galvenās formas, kurā atradīsies meklēšanas lauki (darbinieka vārds, uzvārds un personas kods), kuros būs iespējams ievadīt meklējamo informāciju vai tās daļu, kā arī divas pogas „Meklēt” – meklēšanas darbības izpildei un „Rādīt visus” – meklēšanas parametru dzēšanai un visu ierakstu izvadei uz ekrāna, un apakšformas, kurā tad arī tiks atspoguļoti vēlamie ieraksti. Meklēšanu organizēsim pēc summēšanas principa, piemēram, ja laukā „darbinieka vārds” ievadīts „Jānis” un laukā „uzvārds” ievadīts „Bērziņš”, tad meklēšanas rezultāts būs visi Jāņi Bērziņi, nevis visi Jāņi un visi Bērziņi (tas būtu „vai” princips), turklāt, ja kādā no meklēšanas laukiem netiks ievadīta nekāda vērtība, tad šis lauks vienkārši netiks iekļauts meklējamo lauku sarakstā (nevis meklēts ieraksts ar tukšu lauka vērtību).

Ķeramies klāt formu veidošanai. Vispirms izveidosim tukšu formu, kurā ievietosim trīs standarta elementu „Text Box”, izmantojot standarta rīkjoslu „Tool Box”, kā tas aprakstīts iepriekš (sk. augstākminēto), kurus izmantosim meklējamās informācijas, proti, darbinieka vārda, uzvārda un personas koda ievadīšanai. Nosauksim šos laukus attiecīgi „worker_name”, „worker_sec_name” un „worker_pers_code”. Tagad nepieciešams izveidot atbilstošo apakšformu ierakstu izvadei. Vispirms izveidosim sekojošu vaicājumu:

SELECT w.worker_name, w.worker_sec_name, w.worker_pers_code, Count(s.worker_id) AS sales_served, Sum(psl.psl_product_count) AS products_sold, Sum(pr.product_price * psl.psl_product_count) AS total_sum, w.worker_salaryFROM workers AS w INNER JOIN ( sales AS s INNER JOIN ( products AS pr INNER JOIN products_sales_linked AS psl ON pr.id_product = psl.product_id ) ON s.id_sale = psl.sale_id) ON w.id_worker = s.worker_idGROUP BY w.worker_name, w.worker_sec_name, w.worker_pers_code, w.worker_salaryORDER BY Sum(pr.product_price*psl.psl_product_count) DESC;

Nosauksim šo vaicājumu „search_subform_src” un aplūkosim tā darbības rezultātu (sk. Att.3.60).

46

Att. 3.60 – vaicājuma „search_subform_src” darbības rezultāts

Tagad ievietosim meklēšanas formā apakšformu, kas balstīta uz šo vaicājumu. Tā kā apakšformas ievietošana galvenajā formā jau aprakstīta iepriekš (sk. augstākminēto), tad to sīkāk neaplūkosim.

Pēc apakšformas ievietošanas, izveidosim navigācijas pogas pa tās ierakstiem, kas arī ir aplūkots iepriekš (sk. augstākminēto), tādēļ to sīkāk neaplūkosim.

Tagad ķersimies klāt pie meklēšanas organizācijas. Tīri teorētiski to varētu mēģināt realizēt ar makrokomandu palīdzību, proti, izsaucot iebūvēto makrokomandu „ApplyFilter” ar nepieciešamajiem parametriem. Taču šeit problēmas varētu sagādāt tukšie meklēšanas formas lauki, kuros tad būtu jāieraksta „*” un tikai tad to vērtība jāpadod uz „ApplyFilter” makrokomandu, turklāt nepieciešams arī veikt vismaz minimālu to apstrādi (kaut vai iztīrīt liekās tukšumzīmes, jo, ja laukā „worker_name” ierakstīsim „ Jānis” ar tukšumzīmi sākumā, tad meklēšanas rezultāts visticamāk būs tukša kopa, nevis visi ieraksti, kuriem laukā „worker_name” ierakstīts „Jānis”, taču pēc autora pieredzes, lietotājiem bieži vien patīk ievadīt šādus kļūdainus meklēšanas nosacījumus attiecīgajos laukos, un tad izstrādātājam jāuzklausa pārmetumi par nespēju nodrošināt sistēmas funkcionēšanas spēju). Par sliktu šim risinājumam runā arī tas, ka gadījumā, ja meklēšana tiktu izmantota vēl kādā formā (kā mūsu gadījumā arī būs – tā nepieciešama arī meklēšanas formā ar pārskatu), tad vajadzētu veidot jaunu makrokomandu. Šis risinājums autoram neliekas optimāls, tādēļ labāk izmantosim VBA skriptu. Tātad, papildinām moduli „public_functions” ar pāris noderīgām procedūrām/funkcijām, kuras veidosim universālās, proti, tādas, lai tās varētu bez liekas piepūles izmantot arī citās formās, kur nepieciešams veikt datu meklēšanu. Vispirms izveidosim sekojošu funkciju:

Function prepareField(ByVal value As String) As String Dim res As String res = Replace(value, " ", "") prepareField = resEnd Function

Šī funkcija izņem atstarpes no simbolu virknes, kura tai padota kā vienīgais parametrs un caur savu vārdu atgriež iegūto rezultātu. Šī funkcija ir primitīva un principā to varēja vispār nerakstīt, bet vienkārši nepieciešamajā vietā izsaukt iebūvēto funkciju „Replace” ar nepieciešamajiem parametriem, taču domāsim vienu soli uz priekšu, jo nepieciešamības gadījumā tikko uzrakstīto funkciju varētu viegli papildināt ar citām nepieciešamajām darbībām, neveicot izmaiņas citās funkcijās vai procedūrās, kur tā tiek izsaukta.

Tagad uzrakstīsim pašu meklēšanas procedūru:

Public Sub handleSearch(f As Variant, ParamArray fields() As Variant)

Dim i As Integer Dim filter As String Dim not_like As String Dim real_field_name As String Dim is_int As String

47

Dim ending As String not_like = "not_like_" is_int = "_int" On Error Resume Next For i = 0 To UBound(fields) fields(i).value = prepareField(fields(i).value) If (fields(i).value <> "") Then If (filter <> "") Then filter = filter & " and " 'ja lauks nav jaaapstraadaa ar like If (Mid(fields(i).name, 1, Len(not_like)) = not_like) Then 'ja lauks jaapstraadaa kaa skaitlis If (Mid(fields(i).name, Len(fields(i).name) - Len(is_int) + 1) = is_int) Then real_field_name = Mid(fields(i).name, Len(not_like) + 1) real_field_name = Mid(real_field_name, 1, Len(real_field_name) - Len(is_int)) ending = " = " & fields(i).value & "" Else real_field_name = Mid(fields(i).name, Len(not_like) + 1) ending = " = '" & fields(i).value & "'" End If filter = filter & real_field_name & ending Else filter = filter & fields(i).name & " like '*" & fields(i).value & "*'" End If End If Next i f.filter = filter f.FilterOn = True

End Sub

Tā kā skaidri zinām, ka meklēšana būs nepieciešama arī meklēšanas formā ar pārskatu, tad pirmo formas parametru definējam kā „Variant” (varētu definēt to kā „Form”, bet kā tad mēs pieliktu filtru pārskatam?). Tātad, šai procedūrai kā parametru padod formas vārdu, kurā meklēšanas darbība realizējama, un meklēšanas lauku masīvu. Procedūras darbības algoritms ir sekojošs, proti, ar cikla palīdzību tiek aplūkoti visi lauki no parametru masīva un uzbūvēts filtrs atkarībā no to vērtībām, turklāt pirms veikt kāda lauka vērtības analizēšanu, tas tiek apstrādāts ar iepriekš aprakstītās funkcijas „prepareField” palīdzību. Ja būtu jāmeklē vienkārši pēc teksta laukiem, tad pietiktu ar filtra veidošanu uz vienkārša „Like” bāzes, taču paredzēsim meklēšanu arī izmantojot formas elementu „Combo Box”, kura atgrieztā vērtība ir integer tipa mainīgais. Šajā gadījumā tā jāsalīdzina pa tiešo, pie kam nav liekama pēdiņas, kā tas ir ar parastiem teksta laukiem. Lai realizētu šo uzdevumu, nepieciešams šo procedūru kaut kā informēt par katrā laukā esošās vērtības tipu un tam nepieciešamo salīdzināšanas veidu. Šeit pielietosim mazu viltību – nodosim šo informāciju caur meklēšanas lauka nosaukumu, proti, ja lauks jāsalīdzina pa tiešo, neizmantojot „Like”, lauka nosaukumam priekšā rakstām „not_like_”, bet, ja tas salīdzināms, kā skaitlisks mainīgais un nav liekams pēdiņās, tad lauka nosaukuma beigās norādām „_int”. Tātad, ja ir lauks, kurā tiks ievadīta skaitliska vērtība, kas jāsalīdzina pa tiešo tad tā nosaukums izskatīsies apmēram tā: „not_like_lauka_parastais_nosaukums_int”. Jāpiebilst vienīgi, ka lauka

48

nosaukumam (ja neskaita tikko minētos prefiksus un sufiksus) jāsakrīt ar meklējamā lauka nosaukumu rezultējošā formā (vai pārskatā). Ar šo vienkāršo paņēmienu esam realizējuši to, ka uz šo procedūru var padot gan teksta laukus, gan „Combo box” tipa elementu un meklēšana vienalga strādās. Pamēģiniet kaut ko tamlīdzīgu realizēt ar makrokomandu! Pēc šo darbību veikšanas, formai, kura padota uz procedūru kā pirmais tās parametrs, īpašībai „Filter” tiek piešķirts uzbūvētais filtrs, un tās īpašībai „FilterOn” tiek piešķirta vērtība „True”, kas nozīmē, ka formai tiek piemērots filtrs, kurš norādīts tās īpašībā „Filter”. Viegli pārliecināties, ka tikko uzrakstītā procedūra ir universāla, un tā darbosies neatkarīgi no meklēšanas lauku skaita, turklāt to var piemērot jebkurai formai vai pārskatam. Nevienu no šīm iezīmēm nebūtu iespējams realizēt ar makrokomandu palīdzību (neiespējams, protams, nav nekas, un autors nemaz nebrīnītos, ja atrastos kāds gudrinieks, kurš, pēc vairāku dienu rakāšanās pa visdažādākajiem interneta forumiem, apgalvotu, ka viņam ir zināms risinājums, taču, pēc autora domām, vienkāršāk ir uzrakstīt pāris rindiņas VBA nekā dienām ilgi mēģināt atrast citu risinājumu, jo tādejādi tiktu izniekots dārgais projekta realizācijai paredzētais laiks).

Tagad nepieciešams izveidot vēl vienu procedūru, kura realizētu uzstādītā filtra atcelšanu:

Public Sub handleCancelSearch(f As Variant, ParamArray fields() As Variant) Dim i As Integer For i = 0 To UBound(fields) fields(i).value = "" Next i f.filter = "" f.FilterOn = False End Sub

Šai procedūrai, līdzīgi kā iepriekšējai, kā pirmo parametru padod formu (vai pārskatu), uz kuras nepieciešams izpildīt uzstādītā filtra dzēšanu. Lai attīrītu arī meklēšanas formas lauku vērtības, padodam uz šo procedūru kā parametru masīvu arī tos. Šiem laukiem vajadzētu sakrist ar tiem, kas tika padoti uz iepriekš aprakstīto procedūru „handleSearch”. Šeit uzreiz redzamas klases moduļu priekšrocības, jo, izveidojot jaunu klasi, tai vienreiz caur konstruktoru padotu visus nepieciešamos parametrus un tad tikai vajadzētu izsaukt atbilstošās metodes to apstrādei, taču tā kā klases moduļi nav mūsu darba tēma, tad tos tuvāk neapskatīsim.

Pēc nepieciešamo procedūru izveides, tās vajadzētu piekabināt klāt atbilstošiem notikumiem izveidotajā formā. Lai to nodrošinātu, izvietosim galvenajā formā „search” divas pogas - „Meklēt” un „Rādīt visus”, kuras nosauksim attiecīgi „search” un „show_all”. Pogas „search” notikumam „On Click” piekārosim procedūras „handleSearch” izsaukumu:

Private Sub search_Click() handleSearch Me.subform_search.Form, _ Me.worker_name, Me.worker_sec_name, Me.worker_pers_code

End Sub

Šeit procedūrai „handleSearch” kā pirmais parametrs tiek padota apakšforma „subform_search”, jo tieši šai formai mēs liksim virsū filtru (izpildīsim meklēšanu). Parametru masīvā nododam galvenās formas nepieciešamos meklēšanas laukus „worker_name”, „worker_sec_name” un

49

„worker_pers_code”, kurus tad arī izmantosim minētā filtrā veidošanā. Lai atceltu uzlikto filtru, pogas „show_all” notikumam „On Click” piekārtojam procedūras „handleCancelSearch” izsaukumu:

Private Sub show_all_Click() handleCancelSearch Me.subform_search.Form, _ Me.worker_name, Me.worker_sec_name, Me.worker_pers_code

End Sub

Šeit kā parametrus nododam tieši tos pašu objektus, ko funkcijas „handleSearch” izsaukšanas gadījumā.

Tagad esam pabeiguši darbu pie meklēšanas organizēšanas, atliek tikai ievietot formā pogu „Aizvērt”, ko veidojam analoģiski kā iepriekšējās formās, un varam aplūkot iegūto rezultātu (sk. Att. 3.61). Aplūkojot iegūto rezultātu, varam secināt, ka meklēšanas formas darbība ir korekta, tātad darbs pie tās veidošanas ir veiksmīgi pabeigts, un varam ķerties klāt pie nākošās, proti, meklēšanas formas ar pārskatu, izstrādes.

Att. 3.61 – meklēšanas forma

50

3.6. Meklēšanas forma ar pārskatuBieži vien, firmas mārketinga speciālistiem nepieciešams uzzināt kādas preces un kādā

daudzumā ir pārdotas, lai izdarītu attiecīgos secinājumus, un būtu iespējams lemt par iepērkamo preču daudzuma plānojuma maiņu, vai arī pārliecināties par esošā plānojuma darbības efektivitāti.

Nāksim talkā marketinga speciālistiem un izveidosim pārskatu, kurā atspoguļosim informāciju par pārdotajām precēm. Informāciju grupēsim pa ražotājiem un preču tipiem, proti, centīsimies iegūt shēmu, līdzīgu Att. 3.62. redzamajai hierarhijas shēmai.

Att. 3.62 – pārskata hierarhijas shēma

Pārskatā paredzēsim informācijas izvadi par preču ražotājiem, preču tipiem, modeļu numuriem, konkrētā modeļa pārdoto preču skaitu un to kopējo summu. Paredzēsim arī informācijas izvadi par kopējo pārdoto preču skaitu un to kopējo summu katram ražotājam, kā arī visiem ražotājiem kopā (pārskata noslēgumā). Lai atvieglotu lietotājam dzīvi, izveidosim meklēšanas formu, kurā paredzēsim preču meklēšanu pēc ražotājiem, preču tipiem un modeļu numuriem. Izmantojot šo formu, lietotājs varēs izfiltrēt nepieciešamo informāciju par viņu interesējošām precēm un rezultātā iegūt pārskatu ar vēlamo rezultātu.

Vispirms ķersimies pie pārskata veidošanas. Pārskatu balstīsim uz sekojošu vaicājumu:

SELECT pr.manufacturer_id, m.manufacturer_title, prt.product_type_title, pr.product_type_id, pr.product_model, sum(psl.psl_product_count) AS sold, sum(psl.psl_product_count * pr.product_price) AS incomeFROM ( product_types AS prt INNER JOIN ( manufacturers AS m INNER JOIN products AS pr ON m.id_manufacturer = pr.manufacturer_id

51

) ON prt.id_product_type=pr.product_type_id) INNER JOIN products_sales_linked AS psl ON pr.id_product=psl.product_idGROUP BY pr.manufacturer_id, m.manufacturer_title, prt.product_type_title, pr.product_model, pr.product_type_id;

Nosauksim šo vaicājumu „product_report_src” un aplūkosim tā darbības rezultātu (sk. Att. 3.63).

Att. 3.63 – vaicājuma „product_report_src” darbības rezultāts

Aplūkojot vaicājuma darbības rezultātu, varētu rasties jautājums: „Kādēļ gan vaicājumā nepieciešamas kolonnas ar vienādām ierakstu vērtībām?”. Atbilde un šo jautājumu ir vienkārša, proti, lauku „manufacturer_id” un „product_type_id” īpašības attiecīgo tabulu īpašību sadaļās „Lookup” ir uzstādītas tā, ka lietotājam šajā laukā tiek rādīts nevis pliks identifikatora cipars, bet gan atbilstošā vērtība, kura iegūta ar attiecīgu vaicājumu, tādēļ arī kolonnas „manufacturer_id” un „manufacturer”, kā arī „product_type_title” un „product_type_id” izskatās vienādas. Taču tā kā pārskatā lietotājam rādīsim tieši atbilstošās vērtības, tad labāk paļauties uz tikko izstrādātā vaicājuma darbības rezultātu, nevis uz to, kas atrodas atbilstošās tabulas „Lookup” sadaļā, jo kurš var atbildēt, kas notiks ar pārskatā atspoguļoto lauku vērtībām, ja paļausimies uz „Lookup” sadaļas vaicājumu, gadījumā, ja „Lookup” sadaļa tiks mainīta? Attiecīgie identifikatoru lauki būs nepieciešami tālākā pārskata izstrādē (100% pārliecības, protams, nekad nav, bet labāk tos iekļaut jau tagad, paredzot nelielu rezervi, nevis pēc tam mainīt visu sistēmu).

Tagad veidojam jaunu pārskatu, kas tiks balstīts uz tikko uzrakstīto vaicājumu. Pārskata veidošanai izmantosim pārskatu veidošanas veidni, kuru iespējams izsaukt, datu bāzes galvenajā logā, sadaļā „Reports” izvēloties „” (sk. Att. 3.64).

52

Att. 3.64 – pārskata viedošanas veidņa izsaukšana

Izpildot šo darbību, ekrānā parādās pārskata veidošanas veidnis (sk. Att. 3.65)

Att. 3.65 – pārskata veidošanas veidnis

Sākumā nepieciešams izvēlēties tabulu vai vaicājumu laukus, kas kalpos par pārskata datu avotu. Šeit izvēlamies vaicājumu „product_report_src” un norādām visus laukus. Pēc šo darbību izpildes spiežam „Next”. Tagad nepieciešams izvēlēties grupēšanas līmeņus (sk. Att. 3.66).

53

Att. 3.66 – grupēšanas līmeņu izvēle

Pašā augšējā līmenī norādīsim ražotāja vārdu, zem tā seko produkta tips un tad pārējās detaļas par produktu, saskaņā ar iepriekš izveidoto hierarhijas shēmu. Kad tas padarīts, spiežam „Next” un pārejam pie kārtošanas un summēšanas izvēles (sk. Att. 3.67).

Att. 3.67 – kārtošanas un summēšanas izvēle

Šeit iespējams izvēlēties laukus, pēc kuriem kārtot detalizēto informāciju (to, kas atrodas hierarhijas pašā apakšā), kā arī iespējams norādīt laukus pēc kuriem veikt summēšanu, skaitīšanu vai kādu citu agregātfunkciju. Norādām šeit, ka vēlamies kārtot pēc lauka „income”, pie tam dilstošā secībā (descending). Pārskatā iekļausim arī summēšanu, taču šajā brīdī to veidnī nenorādīsim, jo pretējā gadījumā, vadoties pēc izstrādātāja pieredzes, tiks uzģenerēta tāda miežu

54

biezputra, ka gudrs nevarēs tikt, kas tur vispār ir, tādēļ atstāsim summēšanas lauku ievietišanu uz vēlāku laiku. Tagad spiežam „Next” un nonākam pie izkārtojuma izvēles (sk. Att. 3.68).

Att. 3.68 – izkārtojuma izvēle

Šeit jāizvēlas viens no sešiem piedāvātajiem izkārtojuma variantiem. Pēc autora domām, vispiemērotākais šoreiz būs „Align Left 1”, kuru tad arī izvēlamies. Tagad spiežam „Next” un nonākam pie pārskata stila izvēles (sk. Att. 3.69).

Att. 3.69 – pārskata stila izvēle

Arī šeit, līdzīgi kā gadījumā ar formu stila izvēli, nepieciešams ievērot noteiktas normas. Nedrīkst pārskatu pārāk saraibināt, jo tādejādi zūd tā pārskatāmība un lietotājam var rasties priekšstats par izstrādātāja sliktu gaumi. Viens gudrs cilvēks reiz teica: „Nezinu, kuram patīk

55

zaļš uz sarkana, taču nepazīstu nevienu, kuram nepatiktu melns uz balta”. Klausīsim šī cilvēka padomam un izvēlēsimies stilu „Formal”, kurš arī nodrošinās melnus burtus uz balta fona. Tagad spiežam „Next” un pārejam pie pēdējā soļa, proti, pārskata nosaukuma izvēles (sk. Att. 3.70).

Att. 3.70 – pārskata nosaukuma izvēle

Pārskatu nosaucam par „product_report” un spiežam „Finish”, lai pabeigtu darbu pie pārskata veidošanas ar veidņa palīdzību. Tagad aplūkojam iegūto rezultātu un saprotam, ka vēl daudz darba priekšā, līdz šo pārskatu varēs arī kādam rādīt. Veicam dažus pārveidojumus (sk. Att. 3.71– pārskata tapšanas process), proti, pārbīdām ar peli attiecīgos pārskata elementus vēlamajā vietā, kā arī paslēpjam atslēgas laukus no lietotāja acīm. Pēc vizuālo pārveidojumu veikšanas, ķeramies klāt pie agregātfunkcijas saturošo lauku veidošanas. Pārskata sadaļā „manufacturer_title Footer” ievietojam divus jaunus „Text box” tipa elementus. Pirmais no tiem kalpos pašreizējā ražotāja kopējā pārdotā preču skaita atspoguļošanai. Šī lauka īpašībā „Control Source” ierakstām „=Sum([sold]) & " gab."”. Tas nozīmē, ka šeit tiks atspoguļota jau minētā nepieciešamā vērtība, apvienota ar simbolu virkni „ gab.”. Otrajā laukā tiks atspoguļota informācija par ienākumiem no pašreizējā ražotāja pārdotajām precēm. Šī lauka īpašībā „Control Source” ierakstām attiecīgi „=Sum([income])”. Tādus pašus laukus ievietojam pārskata sadaļā „Report Footer”, lai būtu iespējams iegūt informāciju par kopējo pārdoto produktu skaitu un to kopējo cenu. Lai pārskata saturs būtu nedaudz pārskatāmāks, organizēsim to tā, lai viena ražotāja produkti netiktu sadalīti pa lappusēm, bet atrastos vienā lappusē. Šī mērķa sasniegšanā sadaļā „Sorting and grouping” laukam „manufacturer_title” īpašībā „Keep together” norādīsim „Whole group”.

Ja visas iepriekšminētās darbības esam izpildījuši pareizi, tad mūsu rīcībā tagad vajadzētu būt pilnvērtīgam pārskatam (sk. Att. 3.72).

56

Att. 3.71 – pārskata tapšanas process

Att. 3.72 – preču pārskata fragments

Tagad pārejam pie meklēšanas formas izveides, ar kuras palīdzību tad arī veiksim pārskatā redzamo ierakstu filtrēšanu. Sākumā izveidojam vienkāršu formu ar trim laukiem un trim pogām. Pirmo lauku veidosim nepieciešamā ražotāja ievadei, izmantojot standarta rīku „Combo Box”. Nosauksim šo lauku „not_like_manufacturer_id_int” (ja atceramies, kas bija rakstīts par

57

meklēšanas formu, tad varam secināt, ka šis lauks nav jāraksta nosacījumā kā „Like”, bet gan tā vērtība jāsalīdzina tieši, kā arī meklēšanas filtra veidošanas procesā tā vērtību nevajag likt pēdiņās). Šim laukam īpašībā „Row Source” ierakstām „SELECT m.id_manufacturer, m.manufacturer_title FROM manufacturers m ORDER BY m.manufacturer_title;”, tādejādi nodrošinot visu iespējamo ražotāju izvadi šajā laukā, turklāt lietotājam atliks tikai izvēlēties jau esošo ražotāju no saraksta, kas palīdzēs izvairīties no iespējamajām kļūdām šī atlases kritērija ievadei. Lai lietotājs nevarētu kā parasti visu sabojāt, šī lauka īpašībā „Limit To List” norādām „YES”, kas nozīmē, ka lietotājs varēs izvēlēties vērtības vienīgi no saraksta (kam vajadzīgs, lai lietotājs izdomātu pats savu ražotāju, ievadītu to šajā meklēšanas laukā un pēc tam lamātu datu bāzu administratoru par to, ka nekas kā parasti nestrādājot?). Otru lauku veidosim nepieciešamā preču tipa ievadei. Lauka veidošanu realizēsim līdzīgi kā tikko aprakstīts, būs tikai viena atšķirība (ja neskaita lauka nosaukumu, kas šajā gadījumā būs „not_like_product_type_id_int”), proti, īpašības „Row Source” vērtība, kuru šajā gadījumā norādīsim „SELECT p.id_product_type, p.product_type_title FROM product_types p ORDER BY p.product_type_title;”. Trešo lauku veidosim kā parastu teksta lauku informācijas par preces modeļa numura ievadi. Par cik preču modeļu ir neskaitāmi daudz (tik pat cik preču), tad, pēc autora domām, nebūtu lietderīgi šeit izmantot standarta rīku „Combo Box”, jo lietotājs vecs paliks, kamēr sameklēs tajā sarakstā sev interesējošo vērtību, tādēļ arī izvēlamies pieeju, izmantojot teksta lauku.

Tagad pienācis laiks meklēšanas pogas izstrādei. Izveidojam pogu, līdzīgi kā iepriekšējās formās, un tās notikumam „On Click” piekārtojam:

Private Sub search_Click() DoCmd.OpenReport "product_report", acViewPreview handleSearch Reports!product_report, _ Me.not_like_manufacturer_id_int, Me.not_like_product_type_id_int, Me.product_model End Sub

Šeit vienkārši atveram pārskatu „product_report” skatīšanas režīmā (var jau arī drukas režīmā, taču kurš gan vēlas, lai datu bāzes izstrādes gaitā printeris izvemtu neskaitāmu daudzumu bezjēdzīgi apdrukātu lapu?) un tad izsaucam iepriekš uzrakstīto procedūru „handleSearch”, kā parametrus nododot jau minēto pārskatu un nepieciešamos meklēšanas formas laukus. Šeit viegli pārliecināties, ka funkciju veidošana VBA atmaksājas un pat ļoti. Iedomājieties kas par garlaicīgu verga darbu būtu tagad no jauna rakstīt meklēšanas makrokomandu?

Ievietojam meklēšanas formā arī pogu, lai būtu iespējams skatīt visus pārskata ierakstus (kas zina, varbūt lietotājam patīk pētīt garas atskaites). Šai pogai notikumam „On Click” piekārtojam:

Private Sub show_all_Click() DoCmd.OpenReport "product_report", acViewPreview handleCancelSearch Reports!product_report, _ Me.not_like_manufacturer_id_int, Me.not_like_product_type_id_int, Me.product_model

End Sub

Arī šeit ar makrokomandas „OpenReport” palīdzību tiek atvērts pārskats „product_report”. Visi parametri, kas tika padoti procedūrai „handleSearch” šeit tiek padoti funkcijai „handleCancelSearch”, lai atceltu meklēšanas filtru un parādītu visus ierakstus.

58

Tagad tikai atlicis ievietot formā pogu „Aizvērt”, ko veidojam līdzīgi kā iepriekšējās formās. Līdz ar visu augstākminēto darbību izpildīšanu, esam ieguvuši meklēšanas formu ar pārskatu (sk. Att. 3.73).

Att. 3.73 – meklēšanas forma ar pārskatu

Tagad varam pārliecināties par meklēšanas formas darbības korektumu, piemēram, ievadot kāda ražotāja nosaukumu un aplūkojot iegūto rezultātu (sk. Att. 3.74).

Att. 3.74 – iegūtais pārskats

Šeit viegli pārliecināties par iegūtā rezultāta pareizību. Līdz ar to esam beiguši darbu pie formu veidošanas.

59

3.7. Galvenās formas pilnveidošanaTā kā darba gaitā neesam piešķīruši atbilstošās darbības galvenās formas pogām,

izdarīsim to tagad. Sākumā izveidosim makrokomandu ar nosaukumu „main”, līdzīgi kā saucas forma, kurai gatavojamies piekārtot šeit esošās darbības. Tad ieslēgsim kolonnu „Makro Name”, kā tas aprakstīts iepriekš (sk. augstākminēto). Tagad izveidosim katrai pogai atbilstošu makrokomandu (sk. Att. 3.75).

Att. 3.75 – pogām atbilsošās makrokomandas

Viss ko atlicis izdarīt, ir piesaistīt atbilstošo makrokomandu attiecīgajai pogai un darbs pie darbību piesaistīšanas pogām ir pabeigts.

Tagad vēl, smukuma pēc, izdarīsim tā, lai atverot datu bāzi, ekrānā uzreiz parādītos forma „main”, pie tam nebūtu redzams datu bāzes galvenais logs (priekš kam lietotājam viņš?). Lai to realizētu, atvērsim „Tools->Startup”. Pēc šīs darbības izpildes, ekrānā parādās sāknēšanas parametru rediģēšanas logs (sk. Att. 3.76).

Att. 3.76 – sāknēšanas parametru rediģēšanas logs

Šeit laukā „Display Form/Page” norādām formu „main” un izņemam ķeksīti no lauka „Display database Window”. Tagad sākam priecāties, jo mūsu rīcībā ir pilnvērtīga datu bāze.

60

SecinājumiVeidojot darbu sāku pamazām atcerēties, kādēļ pārgāju no Access uz PHP savienojumā

ar MySQL. Lieta tāda, ka iebūvētās Access komandas un makrokomandas strādā lieliski, taču tikai tādā gadījumā, ja nepieciešams ļoti ātri izveidot ļoti vienkāršu sistēmu. Tiklīdz pieskaras kam nedaudz sarežģītākam (kā tas bija gadījumā ar apakšformas navigāciju no galvenās formas – dabūju nedaudz padomāt, kamēr piemānīju Access), uzreiz sākas iekulšanās auzās. Tu, cilvēks, veido, veido makrokomandu, kādu ½ stundu mēģini izdomāt kā tas viss strādās. Kad beidzot viss ir izdomāts un izdarīts, saņem laipnu paziņojumu no sistēmas „No Current Record” vai arī vienkārši nepareizi iegūtu rezultātu. Tad, protams, nospļaujies, izdzēs ārā makrokomandu, atver VBA rediģēšanas logu un nopūlies vēl tikpat ilgi lai izveidoto makrokomandu pārveidotu VBA skriptā (protams, makrokomandu var arī pārkonvertēt uz VBA pa tiešo, izmantojot Access iebūvētās iespējas, taču, kad es to izmēģināju, man goda vārds, slikti sametās no tā ko ieraudzīju). Kad tas padarīts, protams, saproti, ka paņemts pārāk augsts abstrakcijas līmenis, jo Access kļūdu paziņojumu sistēma darbojas nevainojami, un sāc visu atkal pārveidot zemākā līmenī, piemēram, sāc ar makrokomandu, kas realizē ieraksta dzēšanu apakšformā, tad ātri vien kļūst skaidrs, ka nepieciešamas visādas pārbaudes un attiecīgo navigācijas pogu atslēgšana robežgadījumos, sāc saprast, ka makrokomandu veidošanas logs visām šīm darbībām sāk palikt par šauru un pārej uz VBA, un sāc bakstīties ar formas metodi Recordset. Pēc kāda laika jau pieminētais paziņojums „No Current Record” sāk tik tālu krist uz nerviem, ka uzraksti atsevišķu funkciju, kura dinamiski, atkarībā no nodotajiem parametriem uzbūvē SQL vaicājumu, ar kura palīdzību attiecīgais ieraksts tiek dzēsts. Tikai tad viss sāk daudzmaz sakarīgi strādāt. Šeit uzreiz parādās jautājums – kādēļ gan no paša sākuma nesākt rakstīt visu pašā zemākajā līmenī, nevis bakstīties pa augstākiem, kamēr beigu beigās tāpat nokrist uz zemāko? Šis ir vienīgais secinājums, kādu var izdarīt pēc ietiepīgas mēģināšanas izmantot makrokomandas. Ne velti man kādreiz mācīja, ka makrokomandu izmantošana ir slikts stils, un ka no to izmantošanas vajag izvairīties. Šo darbu izstrādājot es vēlreiz pilnībā pārliecinājos, cik patiesi ir šie vārdi. Protams, makrokomandas var arī izmantot (ja nu tiešām gribās un nekādi citādi nevar), taču tikai tādiem vienkāršiem mērķiem kā formas atvēršana vai aizvēršana. Veidojot sarežģītākas lietas uzreiz jāver vaļā VBA redaktors, nemaz nedomājot vai doto darbību var izpildīt izmantojot makrokomandas vai nē (pamatojums – kaut vai tāpēc, ka makrokomandā nevar ierakstīt „On Error Resume Next”, kas ļautu atbrīvot lietotāju vismaz no dažiem Access kļūdu paziņojumiem. Protams, ne jau vienmēr visas kļūdas var ignorēt, taču, ja izstrādātājs saprot ko dara, tad viss būs kedā). Salīdzinot ar jau pieminēto PHP un MySQL savienojumu manās acīs Access ir vienkārši nulle. PHP visu raksta nu nulles (protams, ja pats neesi jau uzrakstījis moduļu kolekciju, kuru tad arī izmanto sistēmas izstrādē, kā tas parasti arī notiek) un ir skaidri un gaiši saprotams kādu rezultātu iegūst no kādas darbības. Ja kāda funkcija nestrādā kā pienākas, tad 99% gadījumu (jāatzīst, ka strādājot ar šo sistēmu vienu kļūdu tomēr atradu – tā bija funkcijā array_multisort – kārtojot tai kā parametru nodotus masīvus, tā pie reizes nez kāpēc sakārtoja arī $_POST un $_GET masīvus no kā pat mans tā laika tiešais priekšnieks palika mēms) to esi rakstījis pats vai to ir darījis kāds no taviem kolēģiem un nav nekādu problēmu atvērt attiecīgo moduli un papētīt, kur ir problēma. Kad kļūda izlabota, sistēma strādā dzelžaini nevainojami, un vienīgais, no kā lietotājam jābaidās, ir paziņojums „PHP Warning: mysql_connect() Can't connect to MySQL server on 'localhost' (10061) in D:\\html\\piem\\login.php on line 20, referer: http://localhost/index.php?page=login”, kuru var izraisīt vienīgi servera bojājums, nevis, piemēram, tukša ieraksta dzēšana, kā tas ir gadījumā ar Access. Ja es veidoju datu bāzi PHP, tad pēc tās izstrādes varu ar drošu sirdi to nodot lietotāja rīcībā, un zināt, kā tā strādās un kādas problēmas tur varētu rasties. Ja man būtu jānodod lietotāja rīcībā Access izveidota datu bāze, tad es noteikti sirms paliktu no lietotāja zvaniem ar sūdzībām par sistēmas funkcionēšanas mazspēju. Šādu situāciju jau piedzīvoju, kad tehnikuma gados praksēju Rīgas Domes Rīgas bāreņtiesā par datortīkla administratora palīgu. Tur viens maniaks bija izveidojis datu bāzes lietojumu MS Access. Labi vēl, ka tabulas bija piesaistītas no SQL servera. Šajā sistēmā katru otro dienu kaut

61

kas nestrādāja. Visu laiku tika saņemtas lietotāju sūdzības. Atceros tos „laimes pārpilnos” brīžus – tu, cilvēks skaties uz kodu, kuram pēc visiem priekšrakstiem būtu jāstrādā tā, kā to ir paredzējis izstrādātājs, bet reālā tā darbība ir pavisam cita. Dzīvs piemērs – „Recordset” metode (nu labi – īpašība) „RecordCount” - ja pirms tās izsaukšanas netiek izsaukta metode „MoveLast”, rezultāti ir pasakaini interesanti, bet tikai ne tādi, kādus tos ir gaidījis izstrādātājs. Pats interesantākais šajā sistēmā ir tas, ka izejot šim kodam cauri ar „Debug” soli pa solim (F8), rezultāts ir pareizs, taču tiklīdz šo kodu palaiž normālā režīmā – atkal nekā – katru reizi kaut kas jauns. Neticiet – pārbaudiet paši! Salīdzinot ar PHP – funkcija „mysql_num_rows($res)” nekad nav atgriezusi nepareizu vērtību.

Vēlos atzīmēt, ka darba izstrādāšanai katastrofāli pietrūka laika. Pēc manām domām, šim darbam bija jāatvēl vismaz trīs nevis divas nedēļas, jo tas bija ļoti darbietilpīgs. Dažas ieceres tā arī palika nerealizētas, jo vienkārši pietrūka sērkociņu, ko likt plakstiņos, lai pa naktīm strādājot acis neliptu ciet. Saprotamu iemeslu dēļ, nianses neminēšu, bet domāju, ka manu darbu lasot radās nojausma par ko iet runa.

62

Literatūras saraksts I. Kliedere „Microsoft Access 2000 datu bāzes veidošana piemēros”, Rīga 2003.

63