Visual Basic
door ir. C.Daniels
1
I. Lab 1 - Inleiding en kennismaking met VB A. Waarom Visual Basic? Visual Basic is een grafische programmeeromgeving, waarmee u makkelijk windowsprogramma’s kunt schrijven. Dit is niet vanzelfsprekend. Programmeren in windows is zelfs voor gehaaide programmeurs een hele klus, en zeer ingewikkeld. Visual Basic verlicht deze taak, door de specifieke windows-programmering op zich te nemen, en de gebruiker alleen maar de voor hem interessante programmaonderdelen te laten schrijven. Het ontwerpen (programmeren) en openen van een venster vergt heel wat kennis van de programmeur over windows. Ook het onderscheppen en behandelen van de windowsberichten is een hele klus. Temeer omdat windows een multitasking omgeving omvat, dwz dat windows meerdere programma’s tegelijkertijd kan laten draaien. De programmeur dient zich dan ook te houden aan de vooropgestelde spelregels. Maar zoals gezegd, visual basic ontlast de programmeur, en heel de nodige programmeerbackground wordt voor de gebruiker geregeld, als het ware achter de schermen, ze is er wel, maar u ziet ze niet, en hoeft u er ook niet om te bekommeren. Dat is een van de grote voordelen om eenvoudige windows-programma’s te schrijven in Visual Basic. Daarnaast kan deze taal ook gebruikt worden in programma’s zoals Word en Excel om de kracht van deze programma’s te vergroten door het schrijven van u eigen macroprogramma’s. Dit wordt dan Visual Basic for Applications genoemd, dikwijls afgekort tot VBA.
B. Hoe werkt windows? De windows-omgeving is “event driven”, zoals dit in vaktaal wordt genoemd. Vrij vertaald: gestuurd door gebeurtenissen. Wat betekent dit? Dit betekent dat windows reageert op elke actie van een gebruiker. Acties kunnen zijn het klikken op een venster, op een knop, het invullen van tekst in een invoervak, het aanslaan van een toets, het vergroten of verkleinen van een venster, enz. Voor elke actie is er een geschikt programma-onderdeel nodig, dan de goede acties uitvoert. Het is windows zelf die deze events of berichten detecteert en verder stuurt aan de draaiende programma’s. In Visual Basic moet de gebruiker alleen programmatuur schrijven voor de gebeurtenissen (events) die hem aanbelangen. Ander gebeurtenissen zoals het klikken op het kruisje rechts boven in een venster, zijn al automatisch voorgeprogrammeerd. Daar hoeft de gebruiker zich niet om te bekommeren.
Visual Basic
door ir. C.Daniels
2
Programma x
Private Sub Knop1_Click …………. end
X
Knop 1 Knop2
Private Sub Knop2_Click …………. end
In bovenstaand voorbeeld ziet u een eenvoudig programma met twee drukknoppen. Als de gebruiker op Knop1 klikt wordt door windows het bijbehorende programma-onderdeel private sub Knop1_Click aangeroepen. Voor het klikken op Knop2 geldt hetzelfde maar nu wordt het programma-onderdeel private Sub Knop2_Click aangeroepen.
Windows is: - Multitasking - Event driven
Onthou !
C. De programmeeromgeving van Visual Basic: ons eerste programma. Maak eerst een nieuwe map aan op de harde schijf of op uw diskette met de naam Mijnprogrammas bv. of kies zelf een toepasselijke naam. Als uw programma Visual Basic opstart krijgt u ongeveer het volgende te zien:
Visual Basic
door ir. C.Daniels
3
De opdrachten door u uit te voeren, worden in cursieve tekst aangeduid zoals hieronder: Ø Opdracht: doe nu….. Bij het openen van VB krijgt u het dialoogscherm New project. U heeft verschillende mogelijkheden. In het opstartscherm vraagt VB of u een nieuw of een bestaand programma wil openen. Ø Kies voor het tabblad New, want we gaan een nieuw programma ontwerpen. Laat
de optie Standard.exe geselecteerd. Dit is namelijk een gewoon VB-programma. Andere opties komen later ter sprake. Ø Klik op Openen Daarna krijgt u ongeveer het volgende te zien:
2.Project Explorer venster
3.Properties dialoog
1.Form window: het venster met het programma dat je gaat ontwerpen
4.Form layout
Als u niet alle vensters ziet zoals hierboven, kunt u dit aanpassen door in het menu -> View het juiste venster aan te klikken. U kunt de vensters ook apart vergroten, verkleinen of verslepen met de muis. Ø Probeer dit uit totdat u ongeveer de layout bekomt zoals hierboven.
Visual Basic
door ir. C.Daniels
4
Hier wat uitleg bij de verschillende vensters. Later zullen we leren ze te gebruiken. 1. Form window: in dit venster gaat u de layout van uw programma bepalen. U kunt er knopjes plaatsen, invulvelden en allerlei andere objecten nodig voor uw programma. Een groter programma kan meerdere formulieren (vensters) bevatten. 2. Het venster van de Project Explorer. Deze geeft de documenten aan die bij ons project behoren. Nu zijn dit voorlopig: - Het project zelf: dit heet voorlopig Project1 - Een formulier met naam Form1. 3. Het properties venster. Hier vindt u de eigenschappen van het aangeklikte object. Wij hebben er slechts één: het formulier Form1. Een object is aangeklikt of geselecteerd als u er omheen de zwarte blokjes ziet. 4. Form layout. Hiermee kunt u de plaats op uw scherm bepalen, waar uw programma opstart. U kunt uw programma verschuiven op uw monitor door er met de muis op te klikken en te verschuiven. U gelooft het of niet, maar we hebben al een werkend programma gemaakt! Ø Om dit programma te laten draaien klikt u
op o Menu->Run -> Start o of gebruik F5 o of klik op:
Als u dit doet zult u het programma opstarten. Het is slechts een leeg venster zoals je hierboven ziet, maar je kan het venster vergroten, verkleinen, minimaliseren, en zelfs afsluiten door op het kruisje rechts boven te klikken. Dus het heeft alle eigenschappen van een windows-programma! Ø Sluit uw eerste programma af door op het kruisje rechts boven van uw programma
te klikken of gebruik de knopjes uit de toolbar:
Afbreken Ctrl-Break
Visual Basic
Sluiten
door ir. C.Daniels
5
D. De eigenschappen van een object veranderen We hebben nog maar één object: ons formulier. Laten we proberen enkele eigenschappen hiervan aan te passen. Zorg dat dit formulier aangeklikt is. En concentreer u op het venster Properties. Ø Pas de volgende eigenschappen aan: Ø Name: Verander dit in Formulier1 (geen spaties!). De naam hebben we nodig in
het programma dat we gaan schrijven.
Onthou ! Belangrijk: in een naam van een object mag je geen spaties zetten! Dit zal later ook gelden voor namen van variabelen als we gaan programmeren! Ø BackColor: klik op deze eigenschap en daarna op het pijltje rechts. Kies palette en
selecteer een mooie achtergrondkleur voor uw programmavenster. Ø Borderstyle: fixed. We kunnen het venster nu niet meer groter of kleiner maken. Ø Caption: verander dit in Eerste Programma. De caption is de titel van uw venster
en wordt getoond in de blauwe balk van uw formulier. Ø Moveable: verander dit in False. U kunt het venster nu niet meer verplaatsen over
uw monitor. Ø Start het programma op, en bekijk het resultaat.
Merk op dat u onderaan in het Properties-venster wat uitleg krijgt over de aangeklikte eigenschap!
Visual Basic
door ir. C.Daniels
6
E. Reageren op een event Laten we een drukknop plaatsen in ons ontwerp. Als we op de drukknop klikken moet ons programma afsluiten. Om de knop op ons formulier te plaatsen, hebben we het Toolbox venster nodig.
Invulveld (text)
Tekstveld (label)
Drukknop (command)
Als dit venster niet zichtbaar is, kunt u dit nog doen door in het menu te kiezen View --> Toolbox.
Ø Klik de drukknop naar uw formulier, en sleep op uw formulier een drukknop. Zorg
ervoor dat u de grootte aanpast aan uw behoefte. Ø Zorg dat de knop aangeklikt is en verander enkele eigenschappen als volgt, in het
properties venster: §
§
Visual Basic
Name: cmdSluiten, de naam die we voor de knop gebruiken in het programma. Deze laten we beginnen met de letters cmd zodat we weten dat deze variabele een knop aanduidt. Caption: verander dit in Sluiten. Dit is het opschrift wat u op de knop kunt lezen.
door ir. C.Daniels
7
Uw ontwerp moet er nu ongeveer als volgt uitzien:
Als we nu ons programma zouden laten draaien, kunnen we wel klikken op de knop (proberen!), maar er zal niets gebeuren. We moeten een klein stukje programma schrijven dat reageert op het klikken. Ø We doen dit als volgt:
Ofwel: § §
Dubbelklik op de knop in de ontwerpfase. Of selecteer het programmeervenster door in het Project-venster formulier1 aan te klikken, en op het icoon View code te klikken. Selecteer linksboven de knop cmdSluiten, kies rechtsboven het event Click. Dit is wat ingewikkelder maar geeft meer mogelijkheden.
Verander het subprogramma als volgt: Private Sub cmdSluiten_Click() End End Het commando End zorgt ervoor dat uw programma sluit als u op de knop klikt. Dit programmavenster moet er nu als volgt uitzien:
Visual Basic
door ir. C.Daniels
8
Nu moet de drukknop werken! Laat het programma runnen, en kijk of het programma sluit als we op de knop klikken.
F. Een popup-scherm Een popup-scherm is een venster dat opengaat om een mededeling, waarschuwing aan de gebruiker te melden. Ø Plaats een nieuwe knop op uw formulier, en verander de eigenschappen als volgt: § Name: cmdKlik § Caption: Klik hier!
Dubbelklik op de knop om het programma aan te vullen als volgt (alleen het vetgedrukte moet u zelf aanvullen: Option Explicit Private Sub cmdKlik_Click() Dim intAntwoord As Integer intAntwoord = MsgBox("Hier komt je mededeling!", 0, "Hi!") End Sub Private Sub cmdSluiten_Click() End End Sub Als u het programma laat runnen, krijgt u volgend resultaat als u de knop Klik hier aanklikt:
Zo’n scherm is zeer nuttig, als u een mededeling wilt geven aan de gebruiker van het programma, als deze bijvoorbeeld een foutieve ingave doet.
Visual Basic
door ir. C.Daniels
9
Onthou ! Het commando Msgbox ziet er als volgt uit:
Variabele = MsgBox( “De tekst die je wil tonen”, getal, “De paginatitel ”) Variabele: hierin wordt een geheel getal geplaatst naargelang je reactie op het popupscherm. Zie verder voor uitleg over variabele. Getal: met dit getal kun je extra knoppen of symbolen bijvoegen in je popupscherm. Naargelang de reactie op dit popupscherm, verandert de waarde van de variabele. Ø U kan de waarde van de variabele intAntwoord zichtbaar maken door de volgende
lijn in uw programma bij te voegen: Private Sub cmdKlik_Click() Dim intAntwoord As Integer intAntwoord = MsgBox("Hier komt je mededeling!", 0, "Hi!") Debug.Print intAntwoord End Sub De waarde van intAntwoord worden dan zichtbaar in het Immediate Window. Als dit niet zichtbaar is, kies dan in het menu View->Imediate window. In plaats van een getal kunt u ook een zogenaamde constante gebruiken. Dit is een naam die hetzelfde effect heeft, en makkelijker te onthouden is. Probeer eens de volgende waarden van getal uit, en noteer het resultaat van intAntwoord als u op een knop klikt: (eerste lijn is reeds ingevuld) Getal
Constante
1
vbOkCancel
Resultaat (nieuwe knoppen, speciale tekens) Knoppen Ok Annuleren
Waarde van de variabele 1 2
2 3 4 8 16 32 64
Visual Basic
door ir. C.Daniels
10
U kunt deze opties ook combineren. Als u optie 1 en 64 samen wil vult u 65 (= 64 + 1) in! Ø Probeer uit!
G. Wat is een variabele? In elk programma heeft u wel behoefte om enkele gegevens (getallen, tekst,..) te bewaren. Hiervoor moet u geheugenruimte reserveren in het RAM-geheugen van uw pc. Dit geheugen is vluchtig: als u de pc afzet zijn alle gegevens uit dit geheugen verdwenen. Vandaar dat elke pc ook een harde schijf heeft, waar u op magnetische weg, langdurig, gegevens kunt opslaan. Het RAM-geheugen kunt u beschouwen als een enorme kast met schuifjes. Alle schuifjes worden genummerd van 0 tot… Zo heeft een geheugen van 16Mb (megabyte) ongeveer 16.000.000 (juister: 224) vakjes. In elk vakje past één byte, ofwel 8 bitjes.
In één geheugenvakje kunt u dus één byte bewaren. Als u deze byte terug wilt zoeken, heeft u natuurlijk de nummer van het juiste vakje nodig. Dit zou erg omslachtig zijn. In de begintijd van de computers gebeurde dit wél op deze manier! Maar nu wordt aan een geheugenvakje een naam gegeven. Dit is makkelijker te programmeren. En de computer kan nu dat vakje in zijn geheugen zetten, waar hij wil. Het juiste nummer van de plaats hoeft u niet te weten, alleen de computer weet dit. Zo’n geheugenplaatsje is een variabele. Eigenlijk duidt deze naam dus aan over welk vakje u wilt beschikken in uw programma. Zo is intAntwoord een plaatsje waar uw een geheel getal (integer) kan instoppen. Om zo’n vakje te reserveren in uw programma heeft uw dan de volgende instructie nodig: Dim intAntwoord As Integer Men noemt dit een variabele declareren. Dim As Integer
staat voor dimension, engels voor dimensioneren. wil zeggen dat we een vakje willen waar een geheel getal in kan.
In dit geval heeft u twee bytes (twee vakjes) nodig om dat geheel getal op te slaan. We zullen later kennismaken met andere types van variabelen. U mag ook meerdere vakjes in éénmaal declareren zoals hieronder Dim i,j,k as Integer
Visual Basic
door ir. C.Daniels
11
Hier declareert men 3 vakjes om een geheel getal te bewaren met de namen i, j en k. Het is een goede gewoonte (maar niet verplicht) om in de naam van de variabele aan te geven over welk type van variabele het gaat. Vandaar dat we de variabele in ons programma de naam intAntwoord hebben gegeven. We weten onmiddellijk dat het hier over een geheel getal gaat. Variabelnamen zoals a,b,c, … gebruikt u beter niet. Het is niet duidelijk wat ze betekenen. Soms worden toch de variabelnamen i, j, k… gebruikt om tellers aan te duiden die we maar even nodig hebben. Onthou ! Variabele: - Een variabele is geheugenvakje om gegevens op te slaan in het RAM-geheugen van de computer. We geven zo’n vakje een naam, om het te kunnen gebruiken in een programma. -
Een geheugenvakje om gehele getallen op te slaan wordt een integer genoemd, en hiervoor zijn 2 bytes nodig in het RAM-geheugen.
-
Het is een goede gewoonte om in de naam van de variabele aan te geven over welk type het gaat. Zo gebruikt men int als voorvoegsel om een variabele voor een geheel getal aan te geven, bv. intAntwoord
-
Geef altijd een naam die een betekenis heeft, dus niet a, b en c. Maar een naam zoals intAntwoord. Alleen voor tellertjes die maar even nodig zijn, worden nogal eens de waarden i, j, k… gebruikt.
1. Option Explicit Bovenaan uw programma ziet u de woorden Option Explicit staan. Deze instructie zorgt ervoor dat u verplicht zijt al de gebruikte variabelen te declareren. Het gebruik van deze optie is niet verplicht. Toch raden we ten zeerste aan deze optie te gebruiken. Het vermijdt dat uw fouten maakt in de naam van uw variabele. Een typefout in een naam van een variabele wordt door de compiler onmiddellijk ontdekt, en vermeld dat hij een onbekende variabele gevonden heeft. Bij uitvoering geeft de compiler deze foutmelding hiernaast.In uw programma wordt tegelijkertijd de regel aangeduid waarin zich de fout bevindt! De Option Explicit komt automatisch in uw programma te staan. Als dit niet gebeurt, kunt u dit aanpassen door in het menu Tools -> Options -> Editor de optie Require variable declaration aan te klikken.
Visual Basic
door ir. C.Daniels
12
Ø Zoek deze instelling op in het programma, en verander indien nodig!
Sla uw oefening op! Menu->file->save Kies echter andere, meer betekenisvolle namen voor het project en het formulier, bv Oef1(de extensie vbp, of frm niet invullen!)
2. Datatypes VB kent verschillende soorten datatypes. Hieronder staat een lijst met de verschillende mogelijkheden. Datatype Uitleg Bereik Nodige geheugen ruimte in bytes Bevat gehele getallen. -32,768 tot 32,767. 2 Integer Een declaratie met percent teken (%) achteraan stelt een Integer datatype voor. Bevat gehele getallen. -2,147,483,648 tot 4 Long Een declaratie met ampersand 2,147,483,647 teken (&) achteraan stelt een Long datatype voor. Kan een reeks karakters bevatten. Vaste lengte: String Dat kunnen letters, cijfers, spaties 0 tot 63K karakters of leestekens zijn. Variabele lengte: Een declaratie met Dollar-teken 0 tot ong. 2 miljard ($) achteraan stelt een String karakters datatype voor. Kan slechts 2 waarden bevatten: 2 Boolean True (-1) of False (0) Voor kleine gehele getallen. 0 – 255 1 Byte Bevat decimale getallen in enkele Positieve getallen: 4 Single precisie. 1.401298E-45 to Een declaratie met uitroepteken (!) 3.402823E38 Negatieve achteraan stelt een Single datatype getallen: voor. -3.402823E38 tot 1.401298E-45 Bevat decimale getallen in Positieve getallen: 8 Double dubbele precisie. 4.94065645841247E-324 tot Een declaratie met spoorwegteken 1.79769313486232E308 (#) achteraan stelt een Double Negatieve getallen: datatype voor. -1.79769313486232E308 to -4.94065645841247E-324 Voor datum- en tijdwaarden. 8 Date Worden opgeslagen als decimale getallen. Het gedeelte voor de komma stelt de datum voor, het gedeelte achter
Visual Basic
door ir. C.Daniels
13
Currency
Variant
de komma de tijd. Bevat getallen, speciaal voor berekeningen met munteenheden. Een declaratie met het teken (@) achteraan stelt een Currency datatype voor. Kan alle soorten data bevatten. Ook speciale warden zoals Empty (leeg) en Null. Als variabelen niet expliciet gedeclareerd worden zijn het automatisch variabelen van het varianttype.
-922,337,203,685,477.5808 tot 922,337,203,685,477.5807
3. Declareren van variabelen Variabelen declareren betekent eigenlijk geheugenruimte reserveren voor die variabele. Variabelen kunt u declareren op twee manieren: -
Door het aangeven van het type: Dim B as Integer - Of door het achtervoegen van een speciaal teken (verouderd) Dim B% Beide declaraties stellen een integer-variabele voor. Wij zullen in de cursus altijd de eerste methode aanhouden. U kiest beter voor duidelijke variabelnamen, die aangeven welk gegeven u erin gaat opslaan. Dus niet A,B of c1, maar wel bijvoorbeeld strIngegevenTekst. Dit geeft iets meer typewerk bij het ontwerpen, maar vergemakkelijkt in hoge mate de leesbaarheid en duidelijkheid van het programma. Alleen voor tellertjes in lusinstructies, worden nogal eens de variabelen i,j,k… gebruikt.
In de oefeningen zullen we deze verschillende datatypes leren gebruiken. H. Oefeningen
1) 2)
Oefening 1
Schrijf een nieuw programma. Pas de grootte en de kleuren van het formulier aan. Plaats er drie drukknoppen op, met de opschriften: “Klik hier!” “Hier afblijven!” “Sluiten”. Als u op de eerste knop klikt, moet er en popup-scherm verschijnen met de tekst “Goed zo!”, een Uitroepteken en een OK-knop. Als u op de tweede knop drukt moet er een popup verschijnen met de tekst: “Dat is niet toegelaten!” en een rode cirkel met een wit kruis, en de knoppen “Nogmaals” en “Annuleren”. Als u op de derde knop klikt moet het programma afsluiten.
Visual Basic
door ir. C.Daniels
14
Visual Basic
door ir. C.Daniels
15
II. Lab 2 - Voorwaardelijke programma-uitvoering A. If then else – instructie Soms is het nodig dat u in een programma een beslissing neemt. Als een bepaalde voorwaarde waar is, doet u iets, is die voorwaarde niet waar, moet u wat anders doen. In basic ziet dit er als volgt uit: If
voorwaarde then Doe iets als de voorwaarde waar is …
Else Doe iets anders als ze niet waar is … End If Voorwaarde: dit moet een test zijn, die als uitkomst waar of niet waar is, bv. - intAntwoord > 100 : test of intAntwoord groter is dan 100 - intAntwoord <= 7 : test of intAntwoord kleiner of gelijk is aan 7 - IntAntwoord =55 : test of intAntwoord gelijk is aan 55 U kunt die instructies in elkaar nesten zoals dat heet. Stel dat we willen testen of een getal in de variabele intGetal groter is, gelijk is aan of kleiner is dan 100, dan zou dat als volgt kunnen: If intGetal > 100 then Druk af dat het groter is dan 100 Else If intGetal = 100 then Druk af dat het getal gelijk is aan 100 Else Druk af dat het getal kleiner is dan 100 End If End If Merk op dat er voor elke If ook een End if staat! Er zijn ook andere mogelijkheden die exact hetzelfde doen, bv. If intGetal = 100 then Druk af dat het getal gelijk is aan 100 Else If intGetal < 100 then Druk af dat het getal kleiner is dan 100 Else Druk af dat het getal groter is dan 100 End If End If
Visual Basic
door ir. C.Daniels
16
Het Else-statement moogt u weglaten, als u het niet nodig heeft. Veronderstel dat u een waarschuwing wilt geven als een getal groter is dan 10000, en niets zeggen als het kleiner is, dan kan dit als volgt: … If (intGetal > 10000) then geef waarschuwing dat het getal te groot is End If … Laten we dit even gebruiken in een eenvoudig programma. We zullen hierin een tekstveld gebruiken. Hierin kan de gebruiker zelf tekst of getallen typen, die we in het programma kunnen gebruiken. We zullen ons programma laten testen of een getal groter, kleiner of gelijk is aan 100. Ø Maak een nieuw project aan, zoals in de eerste oefening. Ø Plaats hierin een label met de tekst ‘Geef een getal in:’, een tekstveld, en twee
knoppen, een om te de waarde van het getal te testen, en één om het programma af te sluiten. Ø Pas de eigenschappen van de verschillende objecten als volgt aan:
Formulier: -
Caption: Test 100
-
Caption: Geef een getal in:
-
Name: cmdTesten Caption: Testen Default: true. Hierdoor wordt deze knop automatisch geselecteerd als u het programma start.
-
Name: cmdSluiten Caption:Sluiten
Label:
Knop1:
Knop2:
Tekstveld: Name: txtGetal Alignment: Right Justify (rechts oplijnen voor een getal) Text: 0 Ø In het venster Form Layout zorgen we ervoor dat het programma ongeveer in het
midden van het scherm opstart.
Visual Basic
door ir. C.Daniels
17
Ø Een en ander moet er nu ongeveer als volgt uitzien:
De layout van het programma is klaar. Nu moet nog de nodige programmatuur worden bijgevoegd, zodat ons programma gaat functioneren zoals we willen! Ø Dubbelklik op de knop cmdSluiten, en voeg de code toe om het programma te laten
afsluiten. Zie het voorgaande voorbeeld. Ø Dubbelklik op de knop testen. Hier hoort het stukje programma bij, om het ingegeven
getal te testen. We gebruiken hier de If-instructie: Rem test de waarde van het getal! Private Sub cmdTest_Click() Dim i As Integer ' hulpvariabele voor MsgBox Dim intGetal As Integer 'de waarde in het tekstveld intGetal = Val(txtGetal.Text) ' Haal het getal uit het tekstveld If intGetal > 100 Then i = MsgBox("Het getal is groter dan 100", vbInformation,"Test") Else If intGetal = 100 Then i = MsgBox("Het getal is gelijk aan 100", vbInformation,"Test") Else i = MsgBox("Het getal is kleiner dan 100", vbInformation,"Test") End If End If End Sub
Als u de lijnen ivm de MsgBox intypt zult u zien dat de editor aanwijzingen geeft over hetgeen u moet ingeven. Bij het getal kunt u ook kiezen uit standaardwaarden zoals hier vbInformation, dit is een andere aanduiding voor de waarde 32. Maar deze is duidelijker, u weet onmiddellijk dat er een “I” van information wordt getoond. We kunnen het programma van commentaar voorzien: - Ofwel gebruik u een volledige regel als commentaarlijn. Plaats vooraan de instructie Rem van het engels:remark (opmerking) - Ofwel achteraan een programmaregel door een aanhalingsteken ‘ te plaatsen.
Visual Basic
door ir. C.Daniels
18
Tip: Merk ook op dat we de lijnen mooi laten inspringen (tab-toets!), dit verhoogt in aanzienlijke mate de leesbaarheid van het programma! Als we het allemaal achter elkaar zouden typen, werkt het programma even goed, maar als u moet uitzoeken hoe het in elkaar zit…. En dit is maar een eenvoudig programma… onderstaande layout van de programma is dus beslist af te raden! Private Sub cmdTest_Click()
Dim i As Integer Dim intGetal As Integer intGetal = Val(txtGetal.Text) ' Haal het getal uit het tekstveld If intGetal > 100 Then i = MsgBox("Het getal is groter dan 100", vbInformation,"Test") Else If intGetal = 100 Then i = MsgBox("Het getal is gelijk aan 100", vbInformation,"Test") Else i = MsgBox("Het getal is kleiner dan 100", vbInformation,"Test") End If End If End Sub Ø
Tip: Voeg ook veel commentaar bij in uw programma! Beter wat teveel uitleg, als te weinig! Als u dit programma binnen een jaar moet gaan wijzigen, zult u blij zijn met de uitleg! Of misschien moet u zelfs het programma van een andere programmeur aanpassen, en als die vergat er wat uitleg bij te schrijven kunt u aardig wat tijd verliezen om uit te zoeken, wat hij nu juist bedoelde… Stel dat deze programmeur dan nog variabelen gebruikte zoals a,b,c,ak, zl,…. Dan wordt het een nachtmerrie… Ø
Als het programma klaar is ziet het eruit zoals hiernaast.
Ø Sla het project op als Oef2_1.vbp en het formulier als Form2_1.frm. Ø Test eens uit wat de reactie is van het programma als u 100,5 intypt? Kunt u dat
verklaren? Ø Of als u een tekst intypt….?
Visual Basic
door ir. C.Daniels
19
Ø
Oefening: Programmeer nu zelf eens de volgende oefening. U moet twee gehele getallen kunnen ingeven Getal1 en Getal2. Als u op de knop Testen klikt, moet het programma vertellen in een popup welk van de twee het grootste is, of dat ze gelijk zijn.
Ø Ø Sla het op als Oef2_2.vbp en FormOef2_2.frm.
Als het programma werkt zou het er zo ongeveer moeten uitzien:
A. Een eenvoudig spelletje: Raadspelletje
3)
De opdracht
We laten de computer een willekeurig getal genereren tussen 0 en 100. Wij moeten raden. De computer zegt alleen of het te hoog of te laag was. Het spelletje start als volgt op: (de namen van de objecten zijn aangegeven)
lblHoofding txtGetal cmdRaden cmdSluiten
Visual Basic
door ir. C.Daniels
20
Als u een foutieve ingave geeft krijgt u een foutmelding
Anders geeft het programma een suggestie om hoger of lager te raden. Als u het gevonden heeft wordt u gefeliciteerd!
4)
Een random getal genereren
Als we ons spelletje spannend willen houden moeten de computer telkens een ander getal uitzoeken om te raden. We zullen dit getal in ons programma in een variabel zetten met naam intTeRadenGetal. Voeg daarvoor de volgende code in vlak onder Option Explicit: Option Explicit Dim IntTeRadenGetal as Integer
Hoe maken we nu een willekeurig getal tussen 1 en 100? Ø VB kent de functie rnd. Deze functie genereert een willekeurig getal tussen 0 en
0,99999…. Test dit even uit! Maak het Immediate window zichtbaar als dat er niet is door in het menu op View->Immediate window te klikken.
Visual Basic
door ir. C.Daniels
21
Ø In het Immediate window typt u enkele malen ?rnd [enter-toets] Het vraagteken is
een verkorte vorm in basic voor de instructie print. U zal zien dat u telkens een ander getal krijgt tussen 0 en 0,999…. Ø
Hoe maken we daaruit een geheel getal tussen 1 en 100? Dit doen we als volgt: Rnd 100*Rnd Fix(100*Rnd) Fix(100*Rnd)+1
= een getal tussen 0 en 0,999… =een getal tussen 1 en 99,999… =neemt alleen het gedeelte voor de komma, is dus van 0 tot 99 =een geheel getal van 1 tot 100
Deze uitdrukking Fix(100*Rnd)+1 kunnen we dus gebruiken om een geheel getal tussen 1 en 100 te maken. Ø Ontwerp zelf eens een formule om een willekeurig getal tussen 100 en 999 te
genereren! Test dit uit in het Immediate Window!
5)
Randomize
Er is nog een probleempje. Als we Rnd gebruiken, wordt telkens hetzelfde getal gegenereert als we het programma opstarten. Om dit te verhinderen moeten we zorgen dat de random-getallen volledig willekeurig worden. Dit kan door de klok van de pc te gebruiken als startwaarde voor de willekeurige getallen. De instructie randomize doet dit. Deze moeten we slechts éénmaal toepassen bij de start van het programma. Hoe kunnen we dit laten uitvoeren bij het openen van het venster?
6)
Het event Load van een formulier
Bij de start van het programma wordt het event Load van het formulier uitgevoerd. Hierin kunnen we dingen programmeren die we bij de openen van het formulier (venster) willen uitvoeren. Ø Zorg dat de programmacode zichtbaar is.
Als dit niet zo is, klikt u in het venster Project Explorer op de knop View code. View code
View object
Klik het gewenste formulier aan
Visual Basic
door ir. C.Daniels
22
Ø Het programmagedeelte dat hoort bij het event Load vindt u als volgt. Klik in het
venster met de programma code bovenaan op Form in de linkerdialoog, en op Load in de rechterdialoog
Ø Voeg de volgende toe aan het subprogramma
Randomize intTeRadengetal = Fix(Rnd * 100) + 1 Debug.Print intTeRadengetal De eerste twee lijnen kennen we al. De derde lijn toont het willekeurig getal in het Immediate venster. Dit kan u helpen uw programma te debuggen. Als u deze optie niet meer nodig hebt, veegt u deze lijn weg of u zet er een Rem voor: Rem Debug.Print intTeRadengetal Ø We moeten natuurlijk ook nog de code invullen om het geraden getal te testen. Deze
code zit in het event Click van de knop cmdRaden. Het vetgedrukte gedeelte moet u zelf intypen. Daar zitten geen nieuwe dingen in behalve de Or-operator. Private Sub cmdRaden_Click() Dim i As Integer ' voor MsgBox Dim intGetal ‘het ingegeven getal om te raden intGetal = Val(txtGetal.Text) ' Haal het getal uit het tekstveld ' Test of het getal tussen 1 en 100 ligt If (intGetal < 1) Or (intGetal > 100) Then i = MsgBox("Het getal moet tussen 1 en 100 liggen!", vbInformation + vbOKonly, "Foutieve ingave") ' Anders testen we of het goed is, te hoog of te laag ' en we geven een reactie in het bovenste label Else If intGetal = intTeRadengetal Then lblHoofding.Caption = "Gefeliciteerd! Gevonden !!!" Else If intGetal < intTeRadengetal Then lblHoofding.Caption = "Raad hoger!" Else lblHoofding.Caption = "Raad lager!" End If End If End If End Sub
Visual Basic
door ir. C.Daniels
Wel alles op één regel zetten!
23
7)
De Or-operator
Vergelijk dit met de Or-poort uit de digitale techniek! Slechts één van beide voorwaarden (intGetal < 1) (intGetal > 100)
moet waar zijn opdat de volledige instructie waar zou zijn. Ø Sla het project en het formulier op met een betekenisvolle naam, zoals Raadspel.vbp
voor het project en Raadspel.frm voor het formulier. Ø Controleer nu of het programma werkt naar behoren. Zorg in het begin dat u het
Immediate venster ziet, zodat u kan controleren welk getal de computer gegenereerd heeft!
Tip: Vóór u een programma uittest kunt u het beter opslaan op schijf. De uitvoering kan mislopen, het programma kan hangen, en dan is al uw werk voor niets geweest… B. Het programma Raadspelletje afwerken Zoals het nu is kunnen we maar één spelletje spelen. Als het getal geraden is zouden we de computer moeten laten vragen of u nog een spelletje wilt spelen. Indien ja, genereert hij weer een ander willekeurig getal, indien neen, stopt het programma.
Ø Probeer zelf eens of u weet waar u de code moet veranderen!
Indien u nog niet bedreven genoeg bent staat hieronder de volledige code van het aangepaste subprogramma. Alleen de vetgedrukte delen zijn bijgevoegd. Probeer vooral het programma te begrijpen, en niet gewoon over te typen!
Visual Basic
door ir. C.Daniels
24
Private Sub cmdRaden_Click() Dim i As Integer ' voor MsgBox Dim intGetal intGetal = Val(txtGetal.Text) ' Haal het getal uit het tekstveld ' Test of het getal tussen 1 en 100 ligt If (intGetal < 1) Or (intGetal > 100) Then i = MsgBox("Het getal moet tussen 1 en 100 liggen!", vbInformation + vbOKOnly, "Foutieve ingave") ' Anders testen we of het goed is, te hoog of te laag ' en we geven een reactie in het bovenste label Else If intGetal = intTeRadengetal Then lblHoofding.Caption = "Proficiat! Gevonden !!!"
Alles op één lijn zetten…
‘ Vraag of de speler nog een spelletje wil i = MsgBox("Nog een Spelletje?", vbQuestion + vbYesNo, "Einde spel") If i = vbYes Then ‘nieuw getal genereren intTeRadengetal = Fix(Rnd * 100) + 1 Debug.Print intTeRadengetal lblHoofding.Caption = "Geef een getal tussen 1 en 100" Else End ‘ nee, dus stoppen End If Else If intGetal < intTeRadengetal Then lblHoofding.Caption = "Raad hoger!" Else lblHoofding.Caption = "Raad lager!" End If End If End If End Sub
Ø Sla het programma op, en test het uit!
Uitleg bij If i = vbYes Then Als u antwoordt met ja, of nee, wordt er een bepaalde waarde gestopt in de variabele i. Als u de waarde kent, kunt u daarop testen. Maar u kunt ook vaste uitdrukkingen zoals vbYes, gebruiken. Ø Zoek in de help eens naar andere mogelijkheden voor het antwoord als u op OK klikt,
of Cancel, Ja, Nee. Of probeer het uit…denk aan de mogelijkheid van debug.print…in het Immediate venster.
Visual Basic
door ir. C.Daniels
25
8)
Elseif
Er bestaat ook nog een andere vorm van de If-instructie: If (voorwaarde 1) then Programmacode 1 Elseif (voorwaarde 2) then Programmacode 2 Elseif (voorwaarde 3) then Programmacode 3 Elseif … Endif Ø
Opgave: Herwerk het voorgaande spelletje en maak gebruik van deze alternatieve vorm van de If-instructie. Sla het desnoods op onder een andere naam, als u het voorgaande niet wil veranderen.
Ø
Opgave: Voeg een teller toe aan het voorgaande programma, zodat u kunt aangeven in hoeveel maal u het getal geraden hebt. U kunt eventueel uw felicitatie laten afhangen van de snelheid waarmee men het getal vindt. Als men het extra snel vindt, zou u kunnen aangeven “Fantastisch! In slechts .. keer gevonden!”, of als het extra lang duurde: “Proficiat! Maar kon toch wat sneller?” of zo…. Noem die teller bv. intAantalKeer en declareer deze in het declaratie-gedeelte onder Option Explicit. Kies (general) (Declaration) in het programmavenster.
Tip: U kunt ervoor kiezen slechts één subprogramma te bekijken ofwel de gehele programmacode. De eerste optie is vooral interessant als uw programma wat langer wordt.
Eén subprogramma Visual Basic
De hele programmacode door ir. C.Daniels
26
III. Lab 3 – containers – select - menu A. Containers Containers zijn objecten die andere objecten kunnen bevatten. Een windows-venster is natuurlijk zo een een container. We zullen in het volgende voorbeeld een andere container leren kennen: een frame.
9)
Frame en Option Button Maak een nieuw project aan met de naam BtwProg. De bedoeling is om de BTW te berekenen op een bepaald geldbedrag. Geef de form de naam:BTWform, en als caption: BTW berekenen. Sleep op dit formulier de volgende objecten Object Frame Option Button
Option Button
Option Button
Label Label Label Text
Text
Text
Button
Button
Visual Basic
Eigenschappen Name: fraBTW Caption: BTW% Name: optKnop1 Caption: 6 % Value: false Name: optKnop2 Caption: 12 % Value: false Name: optKnop3 Caption: 21 % Value: true Name:lblBedrag Caption: Bedrag : Name:lblBTW Caption: BTW : Name:lblTotaal Caption: Totaal : Name: txtBedrag Alignment:right jusitify Text: (niets) Name: txtBTW Alignment:right jusitify Text: (niets) Name: txtTotaal Alignment:right jusitify Text: (niets) Name: cmdBerekenen Caption: &Berekenen Default: true Name: cmdSluiten Caption: &Sluiten Default: false
door ir. C.Daniels
27
De eigenschap value van een selectieknop (Option Button) geeft aan of de knop aangeklikt is (true) of niet (false). De optie default van een knop geeft aan of de knop geselecteerd is, hij heeft dan een dikkere rand, en wordt ingedrukt als je op de Enter-toets duwt. Waarom worden de selectieknoppen gegroepeerd in een frame? Van elk van deze knoppen mag er slechts één enkele aangeklikt worden. Vandaar dat we ze groeperen in een frame, zodat het programma weet welke selectieknoppen één geheel vormen.
Waarvoor dient het teken & bij de caption van de knoppen Berekenen en Sluiten?
Tip: -
Als je de selectieknoppen mooi wil oplijnen, ga je als volgt te werk: Klik de selectieknoppen alle drie samen aan. Om dat te bereiken moet je de shift-toets ingedrukt houden bij het aanklikken van de tweede en de derde knop. Kies in het menu Format -> Align en/of Format -> Make same size.
Als het formulier klaar is ziet het er als volgt uit:
Kies het gedeelte (general) (Declarations) om je variabelen te declareren Dim Dim Dim Dim
Visual Basic
intBTWperc As Integer intBedrag As Integer intBTWbedrag As Integer intTotaal As Integer
door ir. C.Daniels
28
De programmacode om de BTW te berekenen hoort natuurlijk bij het event Clck van de knop Berekenen. Kies in het programmavenster bovenaan cmdBerekenen en Click, of dubbelklik op de knop cmdBerekenen. De programmacode voor dit event ziet er als volgt uit: Private Sub cmdBerekenen_Click() intBedrag = Val(txtBedrag.Text) ' bedrag ophalen ' Kijk welk BTW-percentage van toepassing is If OptKnop1.Value Then intBTWperc = 6 ElseIf OptKnop2.Value Then intBTWperc = 12 ElseIf optKnop3.Value Then intBTWperc = 21 End If ' Nu kunnen we berekenen: intBTWbedrag = intBedrag * intBTWperc / 100 intTotaal = intBedrag + intBTWbedrag 'toon deze bedragen in het juiste tekstvenster txtBTW = Str(intBTWbedrag) txtTotaal = Str(intTotaal) End Sub
10)
Str-functie
De Str-functie is de omgekeerde functie van Val. Ze zet een getal om in een tekst. In een tekstvenster kan in principe alleen ‘tekst’ getoond worden(1). De code voor de knop Sluiten is bekend. Sla het programma op, en test het uit. Het programma werkt als je alles goed hebt gedaan. Maar er is nog een schoonheidsfoutje. Als je iets berekend hebt, en je verandert daarna van BTW-percentage, worden het BTWbedrag en het totaal niet opnieuw berekend. En dus zien we een foutief resultaat. Om dit te verhelpen moeten we reageren op het event Click van de drie knoppen. Selecteer dit event voor elke selectieknop en vul de code als volgt aan Private Sub OptKnop1_Click() intBTWperc = 6 ' Nu kunnen we berekenen: intBTWbedrag = intBedrag * intBTWperc / 100 1
(VB zorgt toch dat één en ander goed verloopt, ook als je Str weglaat. Maar dit is een slechte gewoonte. Andere talen staan dit niet toe, of geven foutieve resultaten. Visual Basic
door ir. C.Daniels
29
intTotaal = intBedrag + intBTWbedrag 'toon het in het juiste tekstvenster txtBTW = Str(intBTWbedrag) txtTotaal = Str(intTotaal) End Sub Private Sub OptKnop2_Click() intBTWperc = 12 ' Nu kunnen we berekenen: intBTWbedrag = intBedrag * intBTWperc / 100 intTotaal = intBedrag + intBTWbedrag 'toon het in het juiste tekstvenster txtBTW = Str(intBTWbedrag) txtTotaal = Str(intTotaal) End Sub Private Sub optKnop3_Click() intBTWperc = 21 ' Nu kunnen we berekenen: intBTWbedrag = intBedrag * intBTWperc / 100 intTotaal = intBedrag + intBTWbedrag 'toon het in het juiste tekstvenster txtBTW = Str(intBTWbedrag) txtTotaal = Str(intTotaal) End Sub
Tip: Moet je niet allemaal typen, met knippen en plakken kun je veel bereiken! Het programma reageert nu zoals we graag willen. Test uit!! Wat doet het programma als je als bedrag 10000 ingeeft? Om dit probleem op te lossen moet je variabeltype veranderen van Integer naar Long. Dit type kan veel grotere gehele getallen aan. Pas het programma aan en zoek eens uit hoe groot het bedrag nu mag zijn voor het programma crasht…
Visual Basic
door ir. C.Daniels
30
B. De Select Case intructie Als je verschillende keuzes moet maken, naargelang de waarde kun je best met de Select Case instructie. Select Case testwaarde Case waarde Programmacode als testwaardegelijk is aan waarde Case waarde1 to waarde2 Programmacode als testwaarde ligt tussen waarde1 en waarde2 Case waarde3,waarde4,… Programmacode als testwaarde gelijk is aan waarde3 of waarde 4 … Case Else Programmacode als geen van voorgaande waar is End Case Een voorbeeldje maakt dit wat duidelijker: Dim Nummer Nummer = 8
' Initialiseer de variabele Nummer.
Select Case Nummer
'Evalueren
Case 1 To 5
' Ligt het nummer tussen 1 en 5? Debug.Print "Tussen 1 en 5"
' De volgende lijn is de enige die waar is Case 6, 7, 8 ' Ligt tussen 6 en 8 Debug.Print "Tussen 6 en 8"
Case 9 To 10
' Nummer is 9 of 10. Debug.Print "Groter dan 8"
Case Else
' Ander waarden Debug.Print "Niet tussen 1 en 10"
End Select Dit programmastukje zal dus de tekst “Tussen 6 en 8” afdrukken in het Immediate venster. Maak een nieuw project aan met de naam Dobbelspel. U krijgt 100F om in te zetten bij een dobbelspel. We gaan een teerling gooien, en naargelang de waarde van de worp wordt onze score verhoogd en verlaagd als volgt: - Bij een 1 wint u 20F - Gooit u een 6 wint u 15F - Bij al de rest verliest u 10F. Als uw geld op is is het spelletje gedaan.
De layout van ons spelletje bij het opstarten is als volgt : Visual Basic
door ir. C.Daniels
31
Label lblGegooid
Tekst txtScore Knop cmdGooien Label lblScore
Object Form
Eigenschappen Name: Form1 Borderstyle: Fixed Single Caption: Dobbelspel BackColor: (naar keuze)
Label
Name: lblGegooid Caption: Klik op ‘Gooien’ BackColor: (naar keuze) Font: Ms Sans Serif 14p
Knop
Name : cmdGooien Caption : Gooien
Label
Name: lblScore Font:Ms Sans Serif 14p BackColor : (naar keuze)
Tekst
Name :txtScore Font :Ms Sans Serif 14p BackColor : (naar keuze)
In het gedeelte (General) (Declarations) plaatsen we de nodige variabelen: Option Explicit Dim intGegooid As Integer ' getal gegooid door de dobbelsteen Dim intScore As Integer ' geldbedrag in kassa
We initialiseren het beginbedrag in het vent Load van het formulier: Private Sub Form_Load() Randomize ' initialiseer de random generator intScore = 50' Beginbedrag op 100 F zetten Visual Basic
door ir. C.Daniels
32
txtScore.Text = Str(intScore) End Sub In de code achter het event Click van de knop cmdGooien, gebruiken we de Select Case instructie: Private Sub cmdGooien_Click() ' gooien: een random getal van 1 tot 6 intGegooid = Fix(6 * Rnd) + 1 lblGegooid.Caption = "Je hebt een " + Str(intGegooid) + " gegooid!" 'Pas de score aan Select Case intGegooid Case 1 intScore = intScore + 20 'Je wint 20 F lblGegooid.BackColor = &HFF00& 'Pas achtergrondkleur aan Case 2 To 5 intScore = intScore – 10 'Je verliest hier 10 F lblGegooid.BackColor = &HFF& Case 6 intScore = intScore + 15 'Je wint 15 F lblGegooid.BackColor = &HFF00& End Select 'Pas het tekstveld score aan txtScore.Text = Str(intScore) End Sub
Oefening: Zorg ervoor dat het programma eindigt als u geen geld meer heeft. Toon nog een popup met de mededeling dat uw geld op is, en laat het programma eindigen!
Visual Basic
door ir. C.Daniels
33
C. Een menu Stel dat we een menu willen maken in ons dobbelspelprogramma als volgt:
In het eerste menu-item kunnen we kiezen uit verschillende beginbedragen: 50F, 100F, en 250F. De gemaakte keuze is gemerkt met een vinkje. Het programma moet opstarten met de keuze 50F aangekruist. Met de menukeuze Optie kunt u gegevens opvragen over de auteur. Merk de onderlijnde letters op. Daardoor kunt u de bijvoorbeeld de optie Beginbedrag oproepen met de muis, maar ook met de toetsencombinatie Alt-B. Om het menu aan te maken gaat u als volgt te werk: Selecteer het formulier waarin u een menu wilt maken Klik in het menu op Tools à Menu Editor Vul de gegevens voor Caption , Name als volgt in:
Caption &BeginBedrag & 50 &100 &250 &Sluiten &Info &Auteur
Name mnuBeginbedrag mnu50 mnu100 mnu250 mnuLijn mnuSluiten mnuInfo mnuAuteur
Inspringen 0 1 1 1 1 1 0 1
Het inspringen doet u met de pijltjes naar links en rechts. Het inspringen bepaalt de structuur van het menu. Door nog verder in te springen kunt u submenu’s van dit menu aanmaken. Met Next springt u naar het volgende menu-item. Met Insert en Delete kunt u een menu-item tussenvoegen of verwijderen
Visual Basic
door ir. C.Daniels
34
Als alles goed is ziet u menu-editor eruit zoals hieronder:
Klik op OK
Tip: Zorg dat u onderaan geen lege lijn heeft, anders wordt het menu niet aanvaard! Verwijder ze eventueel met Delete. Bij het opstarten zorgen we ervoor dat het beginbedrag op 50F wordt gezet, en dat ook alleen de optie 50F in het menu is aangekruist. Het aankruisen van een menu-item gebeurt door de eigenschap Checked op true of false te zetten Plaats de volgende code bij in de events mnu50 Click, mnu100 Click en mnu250 Click: Private Sub mnu50_Click() mnu50.Checked = True mnu100.Checked = False mnu250.Checked = False intScore = 50 txtScore.Text = Str(intScore) End Sub Private Sub mnu100_Click() mnu50.Checked = False mnu100.Checked = True mnu250.Checked = False intScore = 100 txtScore.Text = Str(intScore) Visual Basic
door ir. C.Daniels
35
End Sub Private Sub mnu250_Click() mnu50.Checked = False mnu100.Checked = False mnu250.Checked = True intScore = 250 txtScore.Text = Str(intScore) End Sub Als we beginnen te spelen mogen we ons bedrag niet meer kunnen aanpassen! Daarom moeten we deze opties uitschakelen. Dit kan door de optie enabled van deze menuitems op false te plaatsen. Tevens laten we spelletje eindigen als ons geld op is, en vragen we of we nog een spelletje willen spelen. Doe dit als volgt door het event cmdGooien Click te wijzjgen als hieronder: Private Sub cmdGooien_Click() Dim i As Integer ' voor msgbox mnu50.Enabled = False mnu100.Enabled = False mnu250.Enabled = False ' gooien: een random getal van 1 tot 6 intGegooid = Fix(6 * Rnd) + 1 lblGegooid.Caption = "Je hebt een " + Str(intGegooid) + " gegooid!" 'Pas de score aan Select Case intGegooid Case 1 intScore = intScore + 20 lblGegooid.BackColor = &HFF00& Case 2 To 5 intScore = intScore - 10 lblGegooid.BackColor = &HFF& Case 6 intScore = intScore + 15 lblGegooid.BackColor = &HFF00& End Select 'Pas het tekstveld score aan txtScore.Text = Str(intScore) ' Stoppen als het geld op is
If intScore <= 0 Then i = MsgBox("Je geld is op!" + strCrLf + "Einde spel!"+ _ strCrLf + "Nog een spelletje? ", vbYesNo, "Sorry...") 'Nog een spelletje?
If i = vbYes Then mnu50.Enabled = True ' menu-items toegankelijk maken mnu100.Enabled = True Visual Basic
door ir. C.Daniels
36
mnu250.Enabled = True intScore = 50 ' Kies 50F om te starten mnu50.Checked = True mnu100.Checked = False mnu250.Checked = False txtScore.Text = Strl(intScore) lblGegooid.Caption = "Klik op gooien!" Else End End If End If End Sub
Test het spelletje uit en zorg dat alles werkt naar behoren! Zorg dat de optie Sluiten uit het menu het programma stopt. (Plaats in het event mnuSluiten Click de code End) Als we op Info à Auteur klikken moet de naam van de maker in een apart venster verschijnen: D. Een nieuw formulier toevoegen Voor de optie Auteur uit ons menu voegen we een nieuw zelfontworpen formulier toe aan ons project:
Kies in het menu Project à Add Form. Uit de dialoog die dan verschijnt kiest u de optie Form. Deze nieuwe form krijgt ook automatisch een eigen module. Plaats er labels op met de nodige tekst en een knop met naam cmdOK en Caption OK zoals hierboven getoond. Pas de eigenschappen van het formulier als volgt aan: Name Caption Appearance Moveable StartUpPosition
formAuteur Auteur 1- 3D False 2 - CenterScreen
Voeg in de module van Form1 de volgende code toe in het event mnuAuteur Click : Visual Basic
door ir. C.Daniels
37
Private Sub mnuAuteur_Click() Form2.Show vbModal End Sub In de module van Form2 vult u het event cmdOK Click als volgt aan:
Daardoor sluit het venster Auteur als u op de knop Ok klikt De optie vbModal betekent dat het een modaal venster betreft. Dit is een venster dat u eerst moet sluiten voor u verder kunt. Als u deze optie weglaat wordt het een modeless venster. De applicatie kan verder functioneren zonder dat dit venster moet gelsoten worden. Laat de optie vbModal weg, en kijk wat het verschil is.
Tip: Ons project heeft nu twee formulieren. Geef deze beide een andere meer zinvolle naam als form1 en form2. Anders worden deze ook opgeslagen als Fom1.frm en Form2.frm. Bij een volgend project worden weer formulieren Form1, Form2,… aangemaakt. Als u deze zonder naamswijziging opslaat overschrijft u uw oude formulieren en bent u dus alles kwijt! Nog beter is het voor elk project een aparte map aan te maken! Maak een nieuw map Dobbelspel aan, en sla het project en de twee formulieren op in deze nieuwe map.
Visual Basic
door ir. C.Daniels
38
IV. Lab 4 – lusintsructies – foutafhandeling - combobox A. Lusinstructies Soms moet u een bepaalde handeling of berekening meerdere malen herhalen. Hiervoor heeft VB speciale lusinstructies (engels: loop).
11)
For…Next
De for-next-instructie ziet er als volgt uit: For teller = beginwaarde to eindwaarde step interval Doe wat… Next De teller is een numerieke variabele. Deze wordt initieel gelijk gezet aan de beginwaarde en in stapjes verhoogd tot hij groter is dan de eindwaarde. Dan stopt de lus. Het gedeelte step moogt u eventueel weglaten. Dan wordt de stap automatisch gelijk aan 1 gezet. Voorbeeld 1: De volgende code: For i = 1 to 5 Print i; Next i Geeft de volgende output: 1 2 3 4 5 (de ; zorgt ervoor dat alles op één enkele lijn wordt afgedrukt) Voorbeeld 2: De volgende code: For i = 2 to 4 step 0.5 Print i; Next i Geeft de volgende output: 2 2.5 3 3.5 4
Voorbeeld 3: de stap mag ook negatief zijn De volgende code: For i = 3 to 2 step -0.25 Print i; Next i
Visual Basic
door ir. C.Daniels
39
Geeft de volgende output: 3 2.75 2.5 2.25 2 Voorbeeld 3: u mag ook variabelen gebruiken voor de beginwaarde, eindwaarde en de stap: De volgende code: intBegin = 2 intEinde = 7 intStap = 0.7 For i = intBegin to intEinde step intStap Print i; Next i Geeft de volgende output: 2 2.7 3.4 4.1 4.8 5.5 6.2 6.9
Ø
Oefening: we gaan dit uittesten. Hiervoor zorg u dat het Immediate venster open is. Indien dit niet zo is kan dat door in het menu te klikken op View à Immediate Window. De for-next-instructie bestaat uit verschillende lijnen. In het Immediate venster kunt u slechts één enkele lijn typen. Maar dit kan door tussen de verschillende instructie een dubbelpunt te plaatsen. Duw op Enter om de instructie uit te voeren.
Ø Ø Ø Ø
Probeer de voorgaande voorbeelden uit in het Immediate venster Maak een lus die de getallen 5 tot 10 genereert in stapjes van 0.5 Maak een lus die de getallen 20 tot -10 genereert in stapjes van -5 Maak een lus die de getallen 1 tot 11 genereert in stapjes van 4
Ø Project Faculteit Maak een nieuw project aan met de naam Faculteit zoals hieronder getoond in de ontwerpfase:
txtGetal
Visual Basic
cmdBerekenen
door ir. C.Daniels
40
Ø Geef de objecten de volgende eigenschappen:
Formulier
Text
Button
Name: Form1 Appearance: 0 - Flat AutoRedraw: true Font: Arial, vet, 12p Name : txtGetal Text: (leeg) Allignment: 1 –Right justify Name: cmdBerekenen Caption: Berekenen
Ø Declareer de volgende variabelen in het gedeelte (General) (Declarations)
Option Explicit Dim i, intGetal As Integer Dim Fac As Currency Ø Plaats de volgende code in het event cmdBerekenen Click
Private Sub cmdBerekenen_Click() Dim s As String 'definieer een variabele om tekst te bevatten intGetal = Val(txtGetal.Text) ' haal de waarde uit het tekstvak ' start de berekening Fac = 1 For i = 2 To intGetal Fac = Fac * i Next ' ok, nu resultaat op het scherm afdrukken ' plaats eerst spaties tussen elke drie cijfers voor de duidelijkheid s = Format(Fac, "### ### ### ### ###") Cls ' Maak het formulier schoon Print Str(intGetal) + "! = " + s 'druk de tekst af in het formulier End Sub
Uitleg: - Het resultaat plaatsen we in een variabele van het type Currency. Dit kan zeer grote gehele getallen bevatten. Zoek op in het Addendum. -
We gebruiken een nieuw type variabele: String. Dit is een geheugenplaats waarin u tekst kunt plaatsen. Elke letter neemt één byte in beslag in het geheugen.
-
De functie Format gebruiken we om het getal af te drukken met spaties tussen elke groep van drie cijfers. Als we dat niet doen, worden alle cijfers tegen elkaar gedrukt, wat het geheel erg onleesbaar maakt.
-
De functie Cls maakt het formulier schoon (afkorting van Clear Screen)
Visual Basic
door ir. C.Daniels
41
-
Met Print wordt de tekst op het formulier afgedrukt.
Hieronder ziet u het programma in werking. Vul een getal in in de tekstbox, en klik op berekenen. Het resultaat verschijnt bovenin het formulier.
Ø Als we een nieuwe berekening willen maken, klikken we in het tekstvak. Het is best dat
dan het formulier terug wordt gewist. Plaats daarom de volgende code in het event txtGetal Click Private Sub txtGetal_Click() Cls End Sub Ø Probeer eens of u 25! Kunt berekenen. Wat stelt u vast?
12)
While…Wend
Deze lusinstructie ziet er als volgt uit While voorwaarde Doe iets… Wend Een voorbeeldje kan dit duidelijker maken:
Dim Counter Counter = 0
' Initialiseer de variabele.
While Counter < 20
' Test de waarde van de teller.
Counter = Counter + 1 ' Verhoog de teller. Wend
' Stop de While lus als de teller > 19.
Debug.Print Counter ' drukt de waarde van de variabele Counter ' af in het Immediate window na het ' uitvoeren van de lus, hier dus 20.
Tip: Visual Basic
door ir. C.Daniels
42
in de For-lus hoeft u zich niets aan te trekken van de teller. Die wordt automatisch verhoogd. Bij de While-lus moet u daar zelf voor zorgen! Anders stopt uw lus niet, en uw programma hangt! Ø Probeer dit eens uit in het Immediate venster, bv. als volgt:
c=1: while c<20:Print c;:c=c+1:wend
13)
Do…Loop
Deze lusinstructie heeft de volgende vorm Do While | Until voorwaarde Doe iets Loop
Of: Do Doe iets Loop While | Until voorwaarde
U kunt zowel While als Until gebruiken, maar niet beiden gelijk. While: de voorwaarde waaronder de lus blijft werken Until: de voorwaarde waarbij de lus stopt
Enkele voorbeelden maken dit duidelijker. Voorbeeld 1: drukt de getallen van 1 tot 9 af i=1 Do While i<10 Print i; i = i + 1 Loop
Visual Basic
door ir. C.Daniels
43
Voorbeeld 2: drukt de getallen van 10 tot 14 af i=10 Do Until i>=15 Print i; i = i + 1 Loop Voorbeeld 3: drukt de getallen van 5 tot 9 af i=5 Do Print i; i = i + 1 Loop While i<10
Voorbeeld 4: drukt de getallen van 1 tot 15 af i=1 Do Print i; i = i + 1 Loop Until i>15 Ø Opgave: Probeer deze voorbeeldjes uit in het Immediate window! Ø Opgave: Gebruik For…Next, While…Wend, Do..Loop om de getallen 11 tot 20 op het
scherm te brengen. Bedenk alle mogelijkheden…en dat zijn er vele…
Tip: Welke lusinstructie gebruiken? Er zijn vele mogelijkheden om hetzelfde resultaat te bereiken: -
Als u weet (of kunt berekenen) bij welke waarden uw lus begint en stopt, gebruikt u liefst een For…Next. Maar een While…Wend of Do…Loop gaat ook, maar is dan omslachtiger.
-
Als u code in de lus altijd minstens éénmaal wordt uitgevoerd gebruikt u best een Do… Loop Wile|Until. Vermits de voorwaarde pas na het uitvoeren van de code wordt getest, wordt deze code minstens éénmaal uitgevoerd
Visual Basic
door ir. C.Daniels
44
-
Als de code soms niet mag worden uitgevoerd, kiest u voor de Do While|Until … Loop. Als de voorwaarde niet waar is, wordt er geen code uitgevoerd.
We zullen deze lusinstructies nog veel nodig hebben in de volgende oefeningen. B. Foutafhandeling: On Error Zoals u heeft vastgesteld, geeft het programma een foutmelding als het te berekenen getal te groot wordt. Het programma “crasht”, en stopt. Dit is niet wenselijk. Mogelijkheden om dit op te lossen zijn: -
Belet de klant een te groot getal in te geven. (Vanaf welk getal “crasht” ons programma?)
-
Vang de fout in het programma op
Of: Ø Oefening: Pas het programma aan, zodat bij het ingeven van een te groot getal de
gebruiker een foutmelding krijgt, en gevraagd wordt een nieuw getal in te geven. Gebruik een MsgBox.
De fout opvangen kan ook. Er bestaat een speciale instructie On Error goto die dit realiseert: Ø Verander de code van het event CmdBerekenen_Click als volgt:
Private Sub cmdBerekenen_Click() Dim s As String 'definieer een variabele om tekst te bevatten intGetal = Val(txtGetal.Text) ' haal de waarde uit het tekstvak 'Vang eventuele fout op On Error GoTo Fout ' start de berekening Fac = 1 For i = 2 To intGetal Fac = Fac * i Next ' ok, nu resultaat op het scherm afdrukken ' plaats eerst spaties tussen elke drie cijfers voor de duidelijkheid s = Format(Fac, "### ### ### ### ###") Cls ' Maak het formulier schoon Print Str(intGetal) + "! = " + s 'druk de tekst af in het formulier Exit Sub ' in geval er een fout optreedt Fout: Print "Getal End Sub
Visual Basic
door ir. C.Daniels
te groot!"
45
Uitleg: De instructie On error goto Fout zorgt ervoor dat het programma bij een fout verder gaat vanaf het label Fout:. We moeten ook de regel Exit Sub bijvoegen om te zorgen dat het programma daar stopt, als er geen fout optreedt. (Laat deze lijn eens weg, en kijk wat er gebeurt…) Probeer het programma nu uit, voor kleine en grotere getallen. Ons programma zal nu niet meer “crashen”.
Ø
Als u een Do- lus voortijdig wil verlaten kunt u de code Exit Do in uw lus plaatsen. Ø
Oefening: Fonts - lettertypes
Dit is wel een zeer eenvoudige toepassing van de ForNext-lus. Het toont de letterfonts (lettertypes) die op uw pc aanwezig zijn. Ø Maak een nieuw project aan met de naam Fonts1. Ø Voeg de volgende code toe aan het event Form_Load: Option Explicit Dim i As Integer Private Sub Form_Load() AutoRedraw = True ' activeer Autoredraw Print "Er zijn " + Str(Screen.FontCount) + " lettertypes aanwezig." For i = 0 To Screen.FontCount 1 FontName = Screen.Fonts(i) ' verander van lettertype Print Screen.Fonts(i) Next End Sub
Uitleg: Visual Basic
door ir. C.Daniels
46
-
De functie Autoredraw wordt geactiveerd, het formulier wordt dan automatisch opnieuw opgevuld met tekst en tekeningen als het geopend, verplaats of van grootte wordt veranderd.
-
FontName: een eigenschap van het formulier die de naam van het gebruikte lettertype weergeeft of verandert
-
FontCount: een eigenschap van het scherm-object (Screen) die het aantal fonts telt die voor het scherm beschikbaar zijn. De telling begint bij 0.
Ø Oefening: Fonts – lettergrootte Ø Deze oefening is vergelijkbaar met de vorige maar nu worden de grootte en stijl van
het lettertype gewijzigd. Ø Maak een nieuw project aan met de naam Fonts2. Ø Voeg de volgende code toe aan het event Form_Load: Option Explicit Dim i As Integer Private Sub Form_Load() AutoRedraw = True ' activeer Autoredraw FontName = "Arial" FontSize = 8 For i = 1 To 6 FontBold = False FontItalic = False Print "Dit is " + FontName + Str(FontSize) + " Normaal" FontBold = True FontItalic = False Print "Dit is " + FontName + Str(FontSize) + " Vetjes" FontBold = False FontItalic = True Print "Dit is " + FontName + Str(FontSize) + " Cursief"
Visual Basic
door ir. C.Daniels
47
FontBold = True FontItalic = True Print "Dit is " + FontName + _ Str(FontSize) + " Vetjes en cursief" Print ' lege lijn FontSize = FontSize + 2 Next End Sub
Uitleg: -
We gaan nu de eigenschappen FontBold en FontItalic wijzigen. Deze kunnen de waarden True (1) of False (0) hebben. We doen dit in een lus waarbij telkens de fontgrootte met 2 punten wordt verhoogd. Niet alle lettergroottes zijn beschikbaar. Windows neemt de grootte die het dichtst de gevraagde grootte benadert.
-
Probeer ook eens met een ander lettertype!
C. De ComboBox Ø
Oefening: een ingewikkelder project ontwerpen.
Laten we ons eens een ingewikkelder opgave stellen. De kunst om dit te ontwerpen is “stapje voor stapje” vooruitgaan.
Tip: Probeer nooit alles ineens te programmeren, u loopt gegarandeerd de mist in! De opgave: We willen de waarde berekenen van ex met behulp van de reeksontwikkeling:
x x 2 x3 x 4 xn e = 1 + + + + + ... + 1 2! 3! 4! n! x
We willen die waarde berekenen tot op een bepaalde nauwkeurigheid, tot op 1/1000, 1/1000000 en 1/1000 000 000. De klant moet een van deze drie kiezen, voor hij begint. Tevens willen we tellen hoeveel termen we nodig hadden om deze nauwkeurigheid te berekenen. Hoe te werk gaan? Er zijn vele wegen die naar Rome leiden, maar begin met één klein elementje! Ik heb gekozen om de gebruiker de nauwkeurigheid te laten kiezen. Dit is logisch want anders kunnen we niks berekenen… we beginnen met het eerste stapje…
Stap 1: de ComboBox Om de gebruiker te laten kiezen uit enkele opties is een ComboBox het ideale object. Visual Basic
door ir. C.Daniels
48
Comboboxes kun je op drie manieren gebruiken. Men noemt deze eigenschap de style van de ComboBox. Wij gebruiken style = 2. Dit geeft de gebruiker enkele keuzemogelijkheden, door ons opgelegd. Ø Zoek op in de help wat de kenmerken zijn van Style 0, 1 en 2.
Een ComboBox ziet er zo uit (style =2):
En als u op de pijl klikt (als het programma runt!) moet er dit komen:
Ø Maak een nieuw project aan, met de
naam Serie. Plaats een combobox op het formulier en enkele labels, zodat het voorlopig ontwerp er als hiernaast uitziet: (Om alles beter te kunnen oplijnen heb ik het raster op 40 twips gezet in Tools à Option à General)
Ø Zet de eigenschappen van de
ComboBox als volgt: Name: comNauwkeurigheid Style: 2- Dropdown List
Nu moeten we de items aan de Combobox toevoegen.Vermits we die onmiddellijk nodig hebben, zetten we deze code in het event Form_Load, dat bij de start van het programma wordt uitgevoerd. Hiervoor hebben we onderstaande eigenschappen van de ComboBox nodig: AddItem: Deze eigenschap laat toen een keuze in de ComboBox bij te voegen. Text: de tekst van het gekozen item. ListIndex: het volgnummer van het gekozen item. Het eerste item krijgt het nummer 0, het tweede 1, enz. Ø Plaats de onderstaan de code in uw programma:
Option Explicit Private Sub comNauwkeurigheid_Click() ' voor testdoeleinden Visual Basic
door ir. C.Daniels
49
Debug.Print comNauwkeurigheid.Text, comNauwkeurigheid.ListIndex End Sub Private Sub Form_Load() ' voeg items toe aan de ComboBox comNauwkeurigheid.AddItem ("0.001") comNauwkeurigheid.AddItem ("0.000001") comNauwkeurigheid.AddItem ("0.000000001") End Sub
Ø Laat het programma runnen. Als u selecties maakt moeten deze verschijnen in het
Immediate window:
Ok, dit gedeelte van het programma werkt al (hopelijk!). Indien het niet lukt, moet u de fout gaan opzoeken. Doe door tot het werkt! Vermits we met die nauwkeurigheid moeten gaan rekenen, declareren we een variabele van het type Double, die de numerieke waarde zal bevatten. Ø Pas de programmacode als volgt aan: Option Explicit Private dblNauwkeurigheid As Double Private Sub comNauwkeurigheid_Click() ' voor testdoeleinden 'Debug.Print comNauwkeurigheid.Text, comNauwkeurigheid.ListIndex 'zet de waarde in de variabele dblNauwkeurigheid = Val(comNauwkeurigheid.Text) Debug.Print dblNauwkeurigheid 'test uit of het goed is!! End Sub Private Sub Form_Load() comNauwkeurigheid.AddItem ("0.001") comNauwkeurigheid.AddItem ("0.000001") comNauwkeurigheid.AddItem ("0.000000001") End Sub
Visual Basic
door ir. C.Daniels
50
Nu moet u de waarden van dblNauwkeurigheid in het Immediate window zien verschijnen als u het programma runt. We zijn nu klaar voor de volgende stap.
Stap 2: de x-waarde ingeven We hebben een veldje nodig om de x-waarde in te tikken, een knop om de berekening te starten, en een label om het resultaat te tonen. Vul daarom het project aan met de volgende objecten, zoals hieronder te zien in de ontwerpfase:
label
txtXwaarde
cmdBerekenen
lblResultaat Ø Vul de code aan als volgt:
Option Explicit Private dblNauwkeurigheid As Double Private dblXwaarde,dblResultaat As Double Private Sub cmdBerekenen_Click() ' Geef een waarschuwing als de nauwkeurigheid niet ingesteld is If (dblNauwkeurigheid = 0) Then MsgBox "Je moet eerst de nauwkeurigheid instellen!" Exit Sub ' Stop ermee… End If ' Wel goed, dus gaan we verder lblResultaat.Visible = True 'Maak dit terug zichtbaar dblXwaarde = Val(txtXwaarde.Text) ' Hier moeten we later de berekening maken ' zet voorlopig het resultaat = x-waarde dblResultaat = dblXwaarde Visual Basic
door ir. C.Daniels
51
' En toon het in het label lblResultaat.Caption = Str(dblResultaat) End Sub Private Sub comNauwkeurigheid_Click() 'zet de waarde uit de ComboBox in de variabele dblNauwkeurigheid = Val(comNauwkeurigheid.Text) lblResultaat.Visible = False End Sub Private Sub Form_Load() comNauwkeurigheid.AddItem ("0.001") comNauwkeurigheid.AddItem ("0.000001") comNauwkeurigheid.AddItem ("0.000000001") lblResultaat.Visible = False End Sub Private Sub txtXwaarde_Change() lblResultaat.Visible = False End Sub Uitleg: - Het resultaat maken we onzichtbaar tot we de berekening maken met de code: lblResultaat.Visible = False -
We geven een foutmeldng als we willen berekenen en nog geen nauwkeurigheid gekozen hebben. We gebruiken een vereenvoudigde methode van de MsgBox: If (dblNauwkeurigheid = 0) Then MsgBox "Je moet eerst de nauwkeurigheid instellen!" Exit Sub ' Stop ermee… End If Ø Test het programma weer uit. Kijk of het resultaat onzichtbaar wordt als u iets verandert aan de nauwkeurigheid of de x-waarde. We zijn nu klaar voor de laatste stap: de eigenlijke berekening. Dit is de moeilijkste en de voornaamste.
Stap 3: berekenen De meesten vinden dit het moeilijkste. Hoe weten we bijvoorbeeld of we de gewenste nauwkeurigheid bereikt hebben? Oefening doet hier wonderen! In het begin vraagt u uzelf af hoe u eraan moet beginnen. Maar na wat oefening leert u vele technieken, die u helpen tot een oplossing te komen. De som moeten we berekenen door een aantal termen samen te tellen. Deze termen worden steeds kleiner en daardoor benaderen we steeds beter de gewenste waarde. Hoeveel termen moeten we samentellen? Dit beslissen we als volgt: we houden steeds de voorgaande waarde bij, en vergelijken deze met de nieuwe waarde als we een volgende term erbij tellen. Is dit verschil kleiner dan de gevraagde nauwkeurigheid dan stoppen we.
Visual Basic
door ir. C.Daniels
52
Vermits we niet weten hoeveel termen we moeten berekenen (en dus hoeveel maal we de lus moeten doorlopen) gebruiken we een While-lus. De termen berekenen gaat gemakkelijk als volgt: de n-de term is gelijk aan de voorgaande term*x/n. Zo kunnen we dus steeds de volgende waarde berekenen zonder dat we faculteiten moeten uitrekenen!
De code ziet er dan als volgt uit:
Private Sub cmdBerekenen_Click() Dim dblTerm, dblVorigResultaat, n As Double ' Geef een waarschuwing als de nauwkeurigheid niet ingesteld is If (dblNauwkeurigheid = 0) Then MsgBox "Je moet eerst de nauwkeurigheid instellen!" Exit Sub ' Stop ermee… End If ' Wel goed, dus gaan we verder lblResultaat.Visible = True 'Maak dit terug zichtbaar dblXwaarde = Val(txtXwaarde.Text) dblTerm = 1 ' de eerste term = 1 dblResultaat = 1 ' het resultaat voorlopig ook n = 1 Do ' hier begint de lus dblVorigResultaat = dblResultaat ' bewaar het vorige resultaat dblTerm = dblTerm * dblXwaarde / n ' bereken de volgende term dblResultaat = dblResultaat + dblTerm 'tel op n = n + 1 ' verhoog n Debug.Print dblResultaat ' alles controleren!!! Loop While Abs(dblVorigResultaat - dblResultaat) > dblNauwkeurigheid
' En toon het in het label lblResultaat.Caption = Str(dblResultaat) Debug.Print Exp(dblXwaarde) ' ter controle! End Sub Ø Bestudeer de code goed tot u precies weet hoe ze werkt! Alleen zo leert u bruikbare
programma’s schrijven!!! Test het programma uit. Ter controle laten we ook de juiste waarde in het Immediate window afdrukken met Debug.Print Exp(dblXwaarde) ' ter controle!
Dus hadden we die berekening niet nodig? Immers de functie Exp() berekent juist wat we zochten…. Alles energie voor niets? NEE! We leren programmeren, niet rekenen. We hebben weer een beter inzicht gekregen in hoe u de dingen moet aanpakken om een ingewikkelder project te realiseren! Visual Basic
door ir. C.Daniels
53
Ø Test alles grondig uit! Ø
Oefening: Vul zelf het programma aan, zodat het aantal termen (aantal iteraties in geleerde taal) dat we nodig hadden voor de berekening in het venster wordt getoond.
Als alles goed is ziet het resultaat er als volgt uit:
Uitleg: Als u het nog moeilijk hebt om te volgen wat er in de programmacode gebeurt, probeer eens te denken zoals de computer doet! Dat gaat ongeveer als volgt:
dblXwaarde = Val(txtXwaarde.Text) eerst halen we de waarde van x uit de tekstbox op, en stoppen die in een variabele in het ram-geheugen. Stel dat we x = 2 hebben ingegeven. dblTerm = 1 ' de eerste term = 1 zet de variabele dblTerm gelijk aan 1. De eerste term van de reeks is immers 1. dblResultaat = 1 ' het resultaat voorlopig ook zet de variabele dblResultaat ook gelijk aan 1. n = 1 n is de macht van x Do
' hier begint de lus
Visual Basic
door ir. C.Daniels
54
We beginnen nu een lus. We berekenen elke keer dat we de lus doorlopen de volgende term in de berekening en tellen die op bij het resultaat. dblVorigResultaat = dblResultaat ' bewaar het vorige resultaat Eerst slaan we natuurlijk de reeds bekomen waarde op in de variabele dblVorigResultaat, zodat we straks de oude en nieuwe waarde kunnen vergelijken. DblResultaat is dus nu ook 1 dblTerm = dblTerm * dblXwaarde / n ' bereken de volgende term x Bereken de waarde van de volgende term . Deze is nu 1*2/1 = 2 1 dblResultaat = dblResultaat + dblTerm 'tel op Tel deze op bij het resultaat: dblResultaat = 1 + 2 =3 n = n + 1 ' verhoog n n wordt dus nu 2.
Debug.Print dblResultaat ' alles controleren!!! Toont dit tussenresultaat in het Immediate venster ter controle Loop While Abs(dblVorigResultaat - dblResultaat) > dblNauwkeurigheid We vergelijken nu de nieuwe waarde met de oude. Als het verschil kleiner is dan de gewenste nauwkeurigheid (stel dat we deze als 0,001 hebben ingegeven), stoppen we: Abs(2 – 1) =1 is dus groter dan 0,001 en dus beginnen we de lus opnieuw: Do We beginnen de lus opnieuw dblVorigResultaat = dblResultaat ' bewaar het vorige resultaat DblResultaat is dus nu ook 2 dblTerm = dblTerm * dblXwaarde / n ' bereken de volgende term x2 Bereken de waarde van de volgende term =vorige*x/n=2*2/2 = 2! 2 dblResultaat = dblResultaat + dblTerm 'tel op Tel deze op bij het resultaat: dblResultaat = 3 + 2 =5 n = n + 1 ' verhoog n n wordt dus nu 3. Debug.Print dblResultaat ' alles controleren!!!
Visual Basic
door ir. C.Daniels
55
Toont dit tussenresultaat in het Immediate venster ter controle Loop While Abs(dblVorigResultaat - dblResultaat) > dblNauwkeurigheid We vergelijken nu opnieuw de nieuwe waarde met de oude. Als het verschil kleiner is dan de gewenste nauwkeurigheid (stel dat we deze als 0,001 hebben ingegeven), stoppen we: Abs(5 – 2) =3 is dus groter dan 0,001 en dus beginnen we de lus opnieuw… enz… totdat we de gewenste nauwkeurigheid bereikt hebben. (Vraag: waarvoor is die Abs nodig na de While?) De opeenvolgende waarden van de term zijn (voor x=2) : 1 2 2 1,333333 0,666667 0,266667 0,088889 0,025397 0,006349 0,001411 0,000282 5,13E-05 8,55E-06 1,32E-06 … en worden dus zeer snel heel klein. Waarschijnlijk zullen we dus na een tiental berekeningen de gewenste nauwkeurigheid bereiken. Het Immediate venster geeft de volgende waarden van het berekend resultaat: 3 5 6,33333333333333 7 7,26666666666667 7,35555555555556 7,38095238095238 7,38730158730159 7,38871252204585 7,38899470899471 juiste waarde: 7,38905609893065 de fout is dus kleiner dan 0,001 ' En toon het in het label lblResultaat.Caption = Str(dblResultaat) We tonen nu het resultaat in ons programmavenster
Tip: Deze methode “u in de plaats van de computer zetten” is dikwijls een goede methode om uit te vissen wat er misloopt, als een programma niet werkt zoals u wil. Deze denkfouten zijn dikwijls moeilijker te vinden als syntax-fouten. Ø Opgave:Pas het programma aan zodat alleen de cijfers van het resultaat waarvan u
zeker bent, worden weergegeven.Gebruik de instructie Format. Ø Opgave: Test eens uit welke de grootste waarde van x is, voor het programma een
runtime fout geeft. Het programma loopt vast vanaf x=… Ø Opgave: Probeer deze fout op te vangen in het programma zodat er een MsgBox komt
met de volgende ingegeven xVisual Basic
foutmelding “De waarde is te groot”. door ir. C.Daniels
56
Gebruik een On Error goto instructie. Test uit of het werkt!
Ø Opgave: Pas het aantal keuzeopties uit met een vierde mogelijkheid “Zo nauwkeurig
mogelijk”. Twee opeenvolgende benaderingen moeten dan volledig gelijk zijn. Maak gebruik van de eigenschap ListIndex van de Combobox om de keuze van de gebruiker te detecteren. Ø Opgave: Maak een programma waarmee u de sinus kunt berekenen, met behulp van
de reeksontwikkeling
x3 x5 sin( x) = x − + − ... 3! 5! Controleer of de berekende waarde correct is met behulp van de functie Sin()
Tip: U hoeft niet alles opnieuw te typen! Vertrek van het voorbeeld Serie. Maak een nieuwe map aan. Bewaar het project als Sinus.vbp in de nieuwe map met FileàSave as… en sla het formulier op als Sinus.frm. U moet dan alleen de berekening veranderen!
Ø Breid het programma uit met een ComboBox met de keuzemogelijkheden
- E tot de macht x - Sin(x) - Cos(x) Zodat de gebruiker kan kiezen welke waarde hij wil berekenen. De reeks voor cos(x) is:
x2 x4 cos( x) = 1 − + − ... 2! 4! Ø Probeer het getal pi = 3.141592653589793238462… zo
nauwkeurig mogelijk te berekenen met de volgende reeksontwikkeling
Visual Basic
door ir. C.Daniels
57
π
1 1.1 1.1.2 1.1.2.3 + + + + ... (methode van Euler) 2 1 1.3 1.3.5 1.3.5.7 =
(uit de website: http://miha.citeglobe.com/pi/pi.eng.htm)
Euler (1707 – 1783)
Probeer zelf de juiste code te vinden! Als u er echt niet uitgeraakt vind u hieronder de juiste code: Private Sub cmdBerekenen_Click() Dim dblTerm, dblVorigResultaat, m, n As Double Dim lngIteraties As Long Dim i As Integer lblResultaat.Visible = True 'Maak dit terug zichtbaar 'initialisatie dblTerm = 1 dblResultaat = 1 n = 1 ' in de teller m = 3 ' in de noemer lngIteraties = 0 'Bereken nu pi/2 Do dblVorigResultaat = dblResultaat dblTerm = dblTerm * n / m dblResultaat = dblResultaat + dblTerm n = n + 1 'verhoogt met 1 m = m + 2 'verhoogt telkens met 2 lngIteraties = lngIteraties + 1 ' Debug.Print dblTerm, dblResultaat Loop While Abs(dblVorigResultaat - dblResultaat) > 0 ' En toon het in het label lblResultaat.Caption = Str(2 * dblResultaat) lblIteraties.Caption = Str(lngIteraties) End Sub
Een nauwkeuriger waarde van pi vindt u op http://ic.net/~jnbohr/java/Machin.html
Visual Basic
door ir. C.Daniels
58
V. Lab 5 – Arrays – line A. Wat zijn arrays? Een array is een verzameling van variabelen. Ze hebben allen dezelfde naam en hetzelfde type. Men kan ze van elkaar onderscheiden door een volgnummer, index genoemd. Enkele voorbeeldjes maken dit duidelijk.
14)
Een array declareren
Stel dat u 15 tellers nodig heeft. Dat kunt u een array van tellers als volgt declareren: Dim Tellers(14) As Integer
' 15 elementen.
Tussen haakjes vermeldt u de grootte van het array. Maar vermits de laagste waarde steeds 0 is, heeft u dus één element meer.(2) Als u zoals hier 14 opgeeft voor de grootte, heb de beschikking over de variabelen Tellers(0), Teller(1),Tellers(2),…. Tot tellers(14). Dat zijn er dus 15! Elk van deze kunt u gebruiken als een integer getal. Andere voorbeelden: Dim Teksten(4) as String Dim Getallen(7) as Double
15)
' 5 elementen van het type string. ' 8 elementen van het type double.
Arrays gebruiken in het programma
In het programma kunt u deze tellers gebruiken door de index aan te geven. De index mag ook een variabele zijn van het type Integer of Long. Voorbeelden: Tellers(2) = 17 Teksten(3) = "En dit is het vierde!" Print Getallen(5) Of met een Integer variabele als index i = 3 Tellers(i)= 45 'Zet Tellers(3) = 45 Ø
Oefening: Maak een nieuw project aan met als naam bijvoorbeeld OefArr1. Zet het weer in een aparte map.
Ø Declareer de volgende arrays in het gedeelte (General) (Declarations)
Option Explicit 'Declaraties van de arrays Dim tellers(9) As Integer Dim getallen(6) As Double 2
'10 gehele getallen ' 7 double getallen
Met de instructie Option Base kun je de laagste waarde ook op één zetten, i.p.v. nul.
Visual Basic
door ir. C.Daniels
59
Dim teksten(3) As String Dim bool(4) As Boolean
' 4 strings ' 5 boolean
Ø Plaats de onderstaande code in de events Form_Click en Form_Load:
Private Sub Form_Click() Dim i As Integer ' teller voor de For-next 'integer array For i = 0 To 9 tellers(i) = 10 * i Print tellers(i); Next Print 'double array For i = 0 To 6 getallen(i) = 7.4589 * i Print getallen(i); Next Print 'string array teksten(0) = "Eerste" teksten(1) = "Tweede" teksten(2) = "Derde" teksten(3) = "En dit is het vierde!" Print teksten(0), teksten(1), teksten(2), teksten(3) 'boolean array For i = 0 To 4 bool(i) = i Print bool(i), Next End Sub Private Sub Form_Load() Form1.Caption = "Arrays" AutoRedraw = True End Sub Ø Laat het programma runnen, klik op het formulier en bekijk het resultaat.
Visual Basic
door ir. C.Daniels
60
Uit dit voorbeeld ziet u ook dat het type Boolean eigenlijk hetzelfde als een Integer is. Alleen de waarde 0 is False, alle andere waarden worden beschouwd als True.
Tip: Experimenteer zoveel mogelijk! Kent u bijvoorbeeld niet de betekenis van de losse Print-instructie in bovenstaand voorbeeld, of van de komma achteraan in de Print-instructie, laat die dan weg, en bekijk het resultaat! Of zoek het op in de Help van VB.
Ø
Oefening: sorteren met bubblesort
Getallen sorteren is en blijft een moeilijke klus voor computers. Er zijn talloze methoden uitgewerkt, en dikke boeken over geschreven. Een van de snelste methodes is de quicksort, maar is vrij ingewikkeld om te programmeren. De bubblesort is veel trager, maar wel vrij makkelijk te programmeren. We zullen eerst deze methode even uitleggen.
16)
Sorteren met bubblesort
Hoe werkt bubblesort? Om dit te illustreren het volgende voorbeeld. Stel dat we getallen 7 2 8 1 3 in gesorteerde volgorde van laag naar hoog willen verkrijgen. Daarom gaan we vooraan beginnen met telkens twee opeenvolgende getallen te vergelijken, staan ze verkeerd worden ze omgewisseld: 7
2
8
1
3
Vergelijk 7 en 2, staan verkeerd dus omwisselen
2
7
8
1
3
Vergelijk 7 en 8, staan goed, dus niets doen
2
7
8
1
3
Vergelijk 8 en 1,staan verkeerd dus omwisselen
2
7
1
8
3
Vergelijk 8 en 3, staan verkeerd dus omwisselen
7
1
3
8
Na één cyclus staat het grootste getal nu
2 achteraan
We herhalen deze cyclus nog eens, het laatste getal moeten we niet meer beschouwen, dat staat al juist. 2
7
1
3
8
Vergelijk 2 en 7, staan goed
2
7
1
3
8
Vergelijk 7 en 1, staan verkeerd dus omwisselen
2
1
7
3
8
Vergelijk 7 en 3, staan verkeerd dus omwisselen
2
1
3
7
8
Het laatste getal stond reeds juist
Visual Basic
door ir. C.Daniels
61
Ook het voorlaatste getal, de zeven, staat nu juist. We vervolgen deze werkwijze tot alle getallen juist staan. Als alle getallen juist staan, moeten we tijdens een ganse cyclus geen omwisselingen meer uitvoeren. Hieronder staat de volgende cyclus 2
1
3
7
8
1
2
3
7
8
Alleen de 2 en de 1 worden nog omgewisseld. Met de andere cijfers moet niets meer gebeuren. Als we nu nog een cyclus zouden uitvoeren, wordt er niets meer omgewisseld, dus is de sortering voltooit. Het aantal omwisselingen dat we nodig hebben, hangt af van de originele getallen. De reeks 1 2 4 7 8 staat reeds juist, dus geen omwisselingen nodig, maar om de reeks 8 7 4 2 1 juist te krijgen zijn er heel wat nodig! Laten we nu een programma schrijven, dat een eenvoudige sortering zoals hierboven uitvoert. Ø Maak een nieuw project aan met de naam Sorteren1. Geef het een weer eigen map met
dezelfde naam. Ø Plaats op het formulier twee knoppen, en geef deze objecten de volgende
eigenschappen
Visual Basic
door ir. C.Daniels
62
Object Formulier
Eigenschappen Name: Form1 Caption: Sorteren Font: Ms Sans Serif 10p Vet Heigth:6800 twips StartUpPosition:1-CenterOwner Width: 3000 twips
Button
Name:cmdNieuw Caption:Nieuw
Button
Name:cmdSorteren Caption:Sorteren
Het formulier Sorteren in de ontwerpfase
Ø Plaats in de declaratie-sectie de volgende code:
Option Explicit Const Aantal = 7 'Aantal te sorteren getallen Dim getallen(Aantal) As Integer 'Array met getallen
Ø Plaats in het event Form_Load de volgende code:
Private Sub Form_Load() AutoRedraw = True cmdSorteren.Enabled = False 'Knop sorteren uitzetten Randomize End Sub Ø Plaats in het event cmdNieuw_Click de volgende code:
Private Sub cmdNieuw_Click() Dim i As Integer ' hulpvariabele Cls ' Maak dit formulier schoon 'genereer de random getallen For i = 0 To Aantal - 1
Visual Basic
door ir. C.Daniels
63
Getallen(i) = Int(100 * Rnd) + 1 'random getal 1 tot 10 Print getallen(i); ' en druk ze af Next ' en druk ze af in het formulier Print: Print 'lege lijn cmdSorteren.Enabled = True ' zet de knop sorteren aan End Sub Ø Plaats in het event cmdSorteren_Click de volgende code:
Private Sub cmdSorteren_Click() Dim i, j As Integer ' hulpvariabelen Dim Gesorteerd As Boolean ' gesorteerd? ja of nee Dim dummy As Integer 'hulpvariabele Gesorteerd = False
'Begin met gesorteerd onwaar te zetten
'Hier begint de cyclus tot als Gesorteerd waar is Do While Not (Gesorteerd) Gesorteerd = True ' Eerst aan zetten For i = 0 To Aantal - 2' Het voorlaatste heeft als index Aantal-2 If getallen(i) > getallen(i + 1) Then 'Vergelijk… dummy = getallen(i) ' Omwisselen getallen(i) = getallen(i + 1) getallen(i + 1) = dummy For j = 0 To Aantal - 1 'en afdrukken Print getallen(j); Next Print Gesorteerd = False 'nog niet goed End If Next i ' streepje na één cyclus Print "----------------------------------" Loop 'herbegin de cyclus cmdSorteren.Enabled = False 'Zet de knop Sorteren uit End Sub
Ons programma is af! Test het uit met verschillende reeksen. Hoeveel maal moet u gemiddeld wisselen bij 10 testrondes?
Visual Basic
door ir. C.Daniels
64
Sorteren1 bij
Het programma Sorteren1 nadat op de knop Nieuw werd geklikt.
En na het klikken op de knop Sorteren. Tussen elke cyclus hebben we een lijntje getrokken. De laatste cyclus is leeg.
Ø Opgave: Verander de code in het programma zodat er van hoog naar laag wordt
gesorteerd. Ø Pas het programma aan in de For-lus zodat het element achteraan, wat reeds
gesorteerd is, niet meer in de lus wordt opgenomen. Kies een veranderlijke Laatste. Zet die eerst gelijk aan Aantal-2, en bij elke lus maakt u die één kleiner Ø Wat gebeurt er als u in de For-lus Aantal-2 vervangt door Aantal–1? Leg uit…
Als we grotere hoeveelheden gegevens gaan sorteren, is dat nog moeilijk te volgen. Grafisch kunnen we wat meer doen. Daarom hebben we de Line-instructie nodig. Hiermee kunt u lijnen, open rechthoeken, en opgevulde rechthoeken tekenen.
B. De Line-instructie Tekent een lijn, rechtboek, of opgevulde rechthoek (blok) in een formulier of PictureBox. Deze ziet er als volgt uit Line (x1,y1)-(x2,y2), kleur, optie
Visual Basic
door ir. C.Daniels
65
Uitleg over de parameters: - x1,y1 : x en y-coordinaat van het startpunt van de lijn of de linkerbovenhoek van de rechthoek - x2,y2 : x en y-coordinaat van het eindpunt van de lijn of de rechterbenedenhoek van de rechthoek - kleur: de kleur van de rand of van de opvulling (optioneel) - optie: B open rechthoek (van het engels: block) of BF opgevulde rechthoek (van het engels: block filled) (optioneel)
Laten we dit even toepassen in een eenvoudig voorbeeld Lijnen1. We kunnen hiermee willekeurige lijnen en rechthoeken laten tekenen.
Het project Lijnen1 in actie. Ø
Oefening: Lijnen1 Maak een nieuw project aan met als naam Lijnen1. Plaats het in een aparte map Lijnen1. Noem het project Lijnen1.vbp, en het formulier Lijnen1.frm.
Ø Plaats de volgende objecten op het formulier:
cmdLijnen
Visual Basic PictureBox
cmdRechthoeken
door ir. C.Daniels
cmdBlokken
66
Ø Geef de objecten de volgende eigenschappen:
Object Form
Button Button Button PictureBox
Eigenschap Name:Form1 Caption: Lijnen1 Heigth: 3600 twips Width:4800 twips Name: cmdLijnen Caption:Lijnen Name:cmdRechthoeken Caption: Rechthoeken Name:cmdBlokken Caption:Blokken Name: PictureBox1
Ø Plaats de volgende code in het event cmdBlokken_Click
Private Sub cmdBlokken_Click() Dim Breedte, Hoogte, x1, y1, x2, y2, i As Integer ' Bepaal de breedte en de hoogte van de PictureBox Breedte = Picture1.ScaleWidth Hoogte = Picture1.ScaleHeight 'teken 10 willekeurige blokken For i = 1 To 10 x1 = Int(Breedte * Rnd) y1 = Int(Hoogte * Rnd) x2 = Int(Breedte * Rnd) y2 = Int(Hoogte * Rnd) Picture1.Line (x1, y1)-(x2, y2), QBColor(Int(Rnd * 16)), BF Next End Sub Ø Plaats de volgende code in het event cmdLijnen_Click
Visual Basic
door ir. C.Daniels
67
Private Sub cmdLijnen_Click() Dim Breedte, Hoogte, x1, y1, x2, y2, i As Integer ' Bepaal de breedte en de hoogte van de PictureBox Breedte = Picture1.ScaleWidth Hoogte = Picture1.ScaleHeight 'teken 10 willekeurige lijnen For i = 1 To 10 x1 = Int(Breedte * Rnd) y1 = Int(Hoogte * Rnd) x2 = Int(Breedte * Rnd) y2 = Int(Hoogte * Rnd) Picture1.Line (x1, y1)-(x2, y2), QBColor(Int(Rnd * 16)) Next End Sub Ø Plaats de volgende code in het event cmdBlokken_Click
Private Sub cmdRechthoek_Click() Dim Breedte, Hoogte, x1, y1, x2, y2, i As Integer ' Bepaal de breedte en de hoogte van de PictureBox Breedte = Picture1.ScaleWidth Hoogte = Picture1.ScaleHeight 'teken 10 willekeurige rechthoeken For i = 1 To 10 x1 = Int(Breedte * Rnd) y1 = Int(Hoogte * Rnd) x2 = Int(Breedte * Rnd) y2 = Int(Hoogte * Rnd) Picture1.Line (x1, y1)-(x2, y2), QBColor(Int(Rnd * 16)), B Next End Sub Ø Plaats de volgende code in het event Form_Load
Private Sub Form_Load() AutoRedraw = True End Sub Ø Het programma is klaar! Test het uit!
Uitleg: ScaleWidth: geeft de breedte van de PictureBox in twips ScaleHeigth: geeft de hoogte van de PictureBox in twips Twip: Een twip is 1/20 van een punt van een printer (567 twips is gelijk aan één centimeter). Let er op dat de y-as haar nulpunt linksboven heeft, in grafische afbeeldingen:
Visual Basic
door ir. C.Daniels
68
QBColor(Nummer): kleureninstructie afkomstig uit een vroegere versie van basic: Quick Basic. Maar kan nog steeds gebruikt worden. Nummer kan de volgende waarden hebben Nummer
Kleur
Nummer
Kleur
0
Zwart
8
Grijs
1
Blauw
9
Licht Blauw
2
Groen
10
Licht Groen
3
Cyaan
11
Licht Cyaan
4
Rood
12
Licht Rood
5
Magenta
13
Licht Magenta
6
Geel
14
Licht Geel
7
Wit
15
Helder Wit
Met de instructie QBColor(Int(Rnd * 16)) de reeks: 0 <= Rnd 0 <= Rnd*16 0 <= Int(Rnd*16)
kiezen we dus een willekeurige kleur uit <= 0,99999…. <=15,9999…. <=15
Ø Oefening: Sorteren2 In deze oefening gaan we het sorteerproces grafisch voorstellen. Elk getal wordt voorgesteld door een horizontale lijn. De lengte komt overeen met de grootte van het getal. Het project ziet er bij uitvoering zo uit:
Visual Basic
door ir. C.Daniels
69
Ø Maak een nieuw project Sorteren2 aan in een nieuw map Sorteren2. Voeg
onderstaande objecten aan het project toe: cmdSorteren
cmdNieuw
cmdSluiten
PictureBox
Ø Geef de objecten de volgende eigenschappen:
Visual Basic
Object Form
Eigenschappen Name:Form1 Caption:Bubble sort Borderstyle: 1- Fixed Single Heigth: 4050 Width: 4700
Button
Name:cmdNieuw door ir. C.Daniels
70
Caption:Nieuw Button
Name:cmdSorteren Caption: Sorteren
Button
Name:cmdSluiten Caption: Sluiten
PictureBox
Name: Picture1 Heigth: 200 ScaleMode: 3 – Pixel Width: 305
Ø Hieronder volgt de volledige code. Zet ze in de juiste events.
Option Explicit Const Aantal = 200 'Aantal getallen Dim getallen(Aantal) As Integer
Private Sub cmdNieuw_Click() Dim i As Integer Dim Breedte As Integer Picture1.Cls 'Leeg maken Picture1.ForeColor = vbRed 'Kleur van de lijnen Breedte = Picture1.Width 'Maak de langste lijn zo breed als het beeld ' Getallen genereren For i = 0 To Aantal - 1 getallen(i) = Int(Breedte * Rnd) Picture1.Line (0, i)-(getallen(i), i) Next i cmdSorteren.Enabled = True 'Zet sorteerknop aan End Sub Private Sub cmdSluiten_Click() End End Sub Private Sub cmdSorteren_Click() Dim gesorteerd As Boolean Dim i, intHulp, Laatste As Integer gesorteerd = False Laatste = Aantal - 2 'En nu sorteren... While Not (gesorteerd) gesorteerd = True 'Begin een cyclus For i = 0 To Laatste If getallen(i) > getallen(i + 1) Then
Visual Basic
door ir. C.Daniels
71
gesorteerd = False ' een wisseling! dus sorteren niet gedaan 'beide lijnen wissen (= tekenen met achtergrondkleur) Picture1.ForeColor = vbWhite Picture1.Line (0, i)-(getallen(i), i) Picture1.Line (0, i + 1)-(getallen(i + 1), i + 1) 'verwisselen intHulp = getallen(i) getallen(i) = getallen(i + 1) getallen(i + 1) = intHulp 'lijnen tekenen in rood Picture1.ForeColor = vbRed Picture1.Line (0, i)-(getallen(i), i) Picture1.Line (0, i + 1)-(getallen(i + 1), i + 1) End If Next i Laatste = Laatste – 1 'elke cyclus waarde Laatste 1 verminderen Wend cmdSorteren.Enabled = False 'Zet sorteerknop uit End Sub Private Sub Form_Load() AutoRedraw = True Randomize 'Voor random-getallen cmdSorteren.Enabled = False 'Zet sorteerknop uit End Sub Ø
Oefening: Quicksort-methode bijvoegen
Om de snelheid van sorteren te kunnen vergelijken gaan we ook sorteren volgens de veel snellere Quicksort-methode. Sla het project en het formulier eerst op in een nieuwe map met naam Quicksort, zodat de oude versie ongemoeid blijft. Ø Voeg een nieuwe knop toe met name = cmdQuickSort en Caption = Quicksort
Ø Voeg de volgende code toe aan het programma, bijvoorbeeld onder de sectie
(General) (Deckarations). Achteraan vindt u een korte beschrijving van de werking. Option Explicit Const Aantal = 200 'Aantal getallen Dim getallen(Aantal) As Integer Public Sub vbQuickSort(vArray As Variant, l As Integer, r As Integer)
Visual Basic
door ir. C.Daniels
72
Dim Dim Dim Dim Dim
i j X Y k
As As As As As
Integer Integer Integer Integer Long 'voor de vertraging
i = l j = r X = vArray((l + r) / 2) While (i <= j) While (vArray(i) < X And i < r) i = i + 1 Wend While (X < vArray(j) And j > l) j = j - 1 Wend If (i <= j) Then ' VERTRAGING 'For k = 0 To 500000 'Next 'lijnen wissen Picture1.ForeColor = vbWhite Picture1.Line (0, i)-(vArray(i), i) Picture1.Line (0, i + 1)-(vArray(i + 1), i + 1) Y = vArray(i) vArray(i) = vArray(j) vArray(j) = Y 'lijnen tekenen Picture1.ForeColor = vbRed Picture1.Line (0, i)-(vArray(i), i) Picture1.Line (0, i + 1)-(vArray(i + 1), i + 1) i = i + 1 j = j - 1 End If Wend If (l < j) Then vbQuickSort vArray, l, j If (i < r) Then vbQuickSort vArray, i, r End Sub Ø Voeg de volgende code toe aan het event cmdQuicksort_Click
Private Sub cmdQuicksort_Click() Visual Basic
door ir. C.Daniels
73
Dim i As Integer 'roep de quicksort-methode aan vbQuickSort getallen, 0, Aantal - 1 'toon de gesorteerde reeks
Picture1.Cls For i = 0 To Aantal - 1 Picture1.Line (0, i)-(getallen(i), i) Next i End Sub Ø Zorg er ook voor dat de knop cmdQuicksort pas toegankelijk wordt als er op Nieuw is
geklikt (eigenschap Enabled aan- en afzetten) Test de sorteermethode uit. Als een en ander te snel gaat, kunt u de vertraging inschakelen door de commentaar weg te laten in de code: (hoe hoger het getal, hoe langzamer) ' VERTRAGING For k = 0 To 500000 Next
Uitleg: De Quicksort is een van de snelste methodes om objecten te sorteren. De werking is kort gezegd als volgt. Men neemt ergens een middelste element uit de reeks. Dan worden de getallen aan weerszijden van dit element omgewisseld, alle getallen kleiner dan dit element komen naar voren, alle getallen groter dan dit element gaan naar de achterste helft. Als dit gebeurt is, zijn alle getallen in het gedeelte vooraan kleiner als dit middelste element, alle getallen achteraan groter dan dit element. Maar ze staan nog niet in de juiste volgorde. Dan wordt de quicksort-methode opnieuw los gelaten op het voorste deel, en daarna op het achterste deel. Telkens wordt elk gedeelte dus ongeveer in de helft gedeeld, totdat alle getallen zijn gesorteerd. We zien hier een voorbeeld van een procedure Public Sub vbQuickSort(vArray As Variant, l As Integer, r As Integer) … End Sub
Dit is een sub-functie die niet samengaat met een event, maar die aangeroepen wordt vanuit een ander gedeelte van het programma. Hoe dit werkt, zien we in het volgend hoofdstuk. Private Sub cmdQuicksort_Click() Dim i As Integer 'roep de quicksort-methode aan vbQuickSort getallen, 0, 199 … End Sub
Visual Basic
door ir. C.Daniels
74
VI. Lab 6 - Strings en string-functies A. Wat zijn strings? Strings zijn eigenlijk teksten. U kunt die bewaren in een stringvariabele. Een tekst bestaat uit karakters zoals letters, cijfers, leestekens,… Een karakter wordt door de computer inwendig voorgesteld door een getal van 8 bits (1 of 0), dit stelt getallen voor tussen 0 en 255. Zo stelt de binaire waarde 0100 0001 voor een computer het getal 65 voor, of als hij het als een karakter moet tonen een hoofdletter A. Deze overeenkomst wordt samengevat in een internationale norm: de ASCII-tabel (zie bijlage) Enkele karakters hierin kunnen niet afgedrukt worden maar dienen uitsluitend voor de besturing van monitors of printers, zoals het karakter met waarde 12, dat op een printer een nieuw blad inschuift, of op een monitor het scherm leegmaakt. De declaratie van een string-variabele is als volgt: Dim Tekst as String Stel dat u de inhoud van de variabele wilt gelijk zetten aan de tekst: Champions League, dan doet u dat in een programma als volgt: Tekst = "Champions League" B. String-functies van Visual Basic VB komt met een heel aantal methoden om deze strings aan te passen, of er bewerkingen mee uit te voeren. We zullen eerst met enkele functies kennis maken. Meer functies en uitleg vindt u in VBHelp. Gebruik voor de oefeningen het Immediate window.
17)
&
Voegt strings samen. (engels: concatenation) Ø Probeer uit in het Immediate venster:
?”ABC” & “123” ?”ABC” & 99 & “!”
18)
Left(string, n)
Geeft n karakters van de linker karakters van de string Ø Probeer uit in het Immediate venster:
? left(“Diepenbeek”,4) a = “Hasselt” ? left(a,3)
Visual Basic
door ir. C.Daniels
75
19)
Right(string,n)
Geeft n karakters vanaf de rechterkant van de string Ø Probeer uit in het Immediate venster:
? right(“Diepenbeek”,4) a = “Hasselt” ?Right(a,3)
20)
Mid (string, s, n)
Geeft n karakters te tellen vanaf karakter s in de string. Ø Probeer uit in het Immediate venster:
? Mid(“Diepenbeek”,4,3) a = “Hasselt” ?Mid(a,4,2) Kunt u dus ook gebruiken als u bijvoorbeeld één letter van een string nodig heeft: Zo heeft Mid(“Hasselt”,5,1) als resultaat de letter “e”.
21)
Asc(karakter)
Geeft de ASCII-waarde van een karakter. Ø Probeer uit in het Immediate venster:
?Asc(“A”) a = “0” ?Asc(a) ?Asc(“XYZ”)
22)
Chr(getal)
Omgekeerde van Asc. Geeft het karakter dat hoort bij de ASCII-waarde getal. Ø Probeer uit in het Immediate venster:
?Chr(65) a = 102 ?Chr(a)
23)
Str(getal)
Maakt van een getal een tekst. Als u dat probeert gebeurt er precies niets, maar toch is het getal omgevormd tot een string. Ø Probeer uit in het Immediate venster:
?Str(165) a =456 Visual Basic
door ir. C.Daniels
76
?Str(a) ?mid(str(123),3,1) geeft 2, terwijl u zoudt denken dat dit 3 moet geven… waarom zou dat zijn?? Als u het niet vindt, probeer dan eens ?”ABC”+str(123).
24)
Val(tekst)
Als tekst een getal bevat, wordt dit getal uit de tekst omgezet in een long variabele. Ø Probeer uit in het Immediate venster:
?Val(“123”) ?Val(“123ABC”) ?Val(“ABC123”)
25)
InStr([getal],string1,string2)
Deze functie zoekt de plaats van string2 in string1 te beginnen vanaf plaats getal. Als u getal weglaat, wordt gestart vanaf het eerste karakter. (Als u iets tussen rechte haken zet, betekent dit dat u het mag weglaten.) Ø Probeer uit in het Immediate venster:
?InStr(“ABCDEFG”,”DE”) ?InStr(“ABCDEFG”,”12”) ?InStr(5,”ABCDEFG”,”ABC”)
26)
StrComp(String1,String2)
Vergelijkt String1 met String2. - Als ze gelijk zijn wordt een nul teruggegeven. - Als String1 > String2 wordt 1 teruggegeven. - Als String1 < String2 wordt -1 teruggegeven. Ø Probeer uit in het Immediate venster:
?StrComp(“ABC”,”ABC”) ?StrComp(“678”,”123”) ?StrComp(“ABCDEFG”,”ABC”) ?StrComp(“ABC”,”ABCDEF”) ?StrComp(“ABC”,” ”) (staat een spatie tussen twee “”)
27)
Format
Drukt datums, getallen en strings volgens een bepaald formaat. Wordt best uitgelegd aan de hand van enkele voorbeelden. Ø Probeer uit in het Immediate venster en noteer het resultaat:
?Format(Date, "Long Date") ? Format(Time, "h:m:s") Tijd = #17:04:23# Datum = #January 27, 1993# ? Format(Tijd, "hh:mm:ss AMPM") ? Format(Datum, "dddd, mmm d yyyy") Visual Basic
door ir. C.Daniels
77
?Format(5459.4, "##,##0.00") ?Format(334.9, "###0.00") ?Format(5, "0.00%") ?Format("HALLO", "<") ?Format("Dat is het!", ">")
C. Procedures en functies Event-procedures zijn we al tegengekomen. Telkens u op een knop klikte werd het event Click aangeroepen van die knop. Maar we kunnen ook procedures schrijven die los staan van een event. Maar soms heb u een bepaald programmastukje dikwijls nodig. Dan maakt u daar best een apart subprogramma van. Er zijn twee soorten subprogramma’s: - Sub-procedures - Functie-procedures of kortweg Functies
1)
Sub-procedures
Een Sub-procedure ziet er uit als volgt: Public|Private Sub MijnProcedure (parameters) …. programmacode End Sub Op de betekenis van Private en Public komen we later terug. Vanuit het hoofdprogramma roept u deze procedure aan door de programmacode: Mijnprocedure parameters Een voorbeeld maakt dit duidelijker. Stel dat we een procedure willen schrijven die uw naam afdrukt op het formulier. Public DrukNaam(Naam as String) Print "Mijn naam is " & naam End Sub Stel dat deze code moet uitgevoerd worden als we op de Knop cmdButton1 klikken, dat ziet de event-code er zo uit: Private Sub cmdButton1_Click ' Roep de procedure Druknaam aan met parameter "Janssens" DrukNaam "Janssens" End Sub
Visual Basic
door ir. C.Daniels
78
Parameters moogt u meegeven, maar u kunt ook procedures schrijven zonder parameters, of met meerdere parameters.
Ø
Voorbeeld 1 van een Sub-procedure: het VisiteKaartje. Maak een nieuw project aan met de naam Visitekaartje. Sla het weer op in zijn eigen directory VisiteKaartje. De bedoeling is de nodige gegevens voor een adreskaartje in te tikken, en deze gegevens door het programma mooi te laten schikken:
Project Visitekaartje in werking Ø Plaats de volgende objecten op het formulier:
Labels
txtVoornaam txtNaam txtAdres txtPostnummer
cmdPreview
txtWoonplaats
cmdWissen
PictureBox1
Visual Basic
door ir. C.Daniels
79
Ø Geef de objecten de volgende eigenschappen mee:
Object Form
5 Labels
TextBox
TextBox
TextBox
TextBox
TextBox
CommandButton
CommandButton
Picturebox Visual Basic
Eigenschap Name: Form1 Caption: Visitekaartje Heigth: 4185 Width: 6240 Name: Label1 tot Label5 Caption: Type je voornaam: Type je familinaam: Adres: Woonplaats: Postnummer Name: txtVoornaam Multiline: False Text: (geen) TabIndex: 0 Tabstop: true Name: txtNaam Multiline: False Text: (geen) TabIndex: 1 Tabstop: true Name: txtAdres Multiline: False Text: (geen) TabIndex: 2 Tabstop: true Name: txtWoonplaats Multiline: False Text: (geen) TabIndex: 3 Tabstop: true Name: txtPostnummer Multiline: False Text: (geen) TabIndex: 4 Tabstop: true Name: cmdPreview Caption: Preview TabIndex: 5 Tabstop: True Name:cmdWissen Caption: Wissen TabIndex: 6 Tabstop: True Name: Picture1 door ir. C.Daniels
80
BackColor: &H00FFFFFF (wit)
In de event-procedure cmdPreview_Click komt volgende code: Private Sub cmdPreview_Click() Dim VoorNaam, Naam, Adres, Woonplaats, Postnummer As String 'Haal de nodige gegevens uit de tekstvelden VoorNaam = txtVoorNaam.Text Naam = txtNaam.Text Adres = lblAdres.Text Woonplaats = txtWoonplaats.Text Postnummer = txtPostnummer.Text 'Roep de sub-procedure Afdrukken aan Afdrukken VoorNaam, Naam, Adres, Woonplaats, Postnummer End Sub Met de lijn Afdrukken VoorNaam, Naam, Adres, Woonplaats, Postnummer Roepen wij de sub-procedure Afdrukken aan met als parameters de gegevens, nodig om het visitekaartje af te drukken. Deze sub-procedure moeten we zelf helemaal schrijven. Plaats ze onder het gedeelte (general)(declarations) als volgt:
Private Sub AfDrukken(nVoorn, nNaam, nAdres, _ nWoonplaats, nPostnummer As String) Dim tekst As String 'Maak de PictureBox leeg Picture1.Cls 'Zet de eigenschappen van het lettertype Picture1.Font = "Palace Script MT" 'lettertype Picture1.Font.Size = Picture1.ScaleHeight / 3 'lettergrootte Picture1.Font.Italic = True 'cursief 'Druk bovenaan voornaam en naam tekst = nVoorn & " " & nNaam Picture1.CurrentX = (Picture1.ScaleWidth / 2)– (Picture1.TextWidth(tekst)/2) Picture1.CurrentY = 0 Picture1.Font.Bold = True 'vetjes aan Picture1.Print tekst ' Adres tekst = nAdres Picture1.CurrentX = (Picture1.ScaleWidth / 2)–(Picture1.TextWidth(tekst)/2) Picture1.CurrentY = Picture1.TextHeight(tekst)
Visual Basic
door ir. C.Daniels
81
Picture1.Font.Bold = False 'vetjes uit Picture1.Print tekst 'Postnummer en woonplaats tekst = nPostnummer & nWoonplaats Picture1.CurrentX = (Picture1.ScaleWidth / 2)–(Picture1.TextWidth(tekst)/2) Picture1.CurrentY = 2 * Picture1.TextHeight(tekst) Picture1.Font.Bold = False 'vetjes uit Picture1.Print tekst 'Afdrukken in de Picturebox End Sub
Uitleg: De instructie Cls maakt het formulier of de PictureBox leeg. De instructie Print tekst druk de inhoud van tekst af in het formulier of de pictureBox. We moeten nog twee problemen oplossen: de juiste plaatsing van de tekst, en het lettertype. - De plaatsing van de tekst: We gebruiken hiervoor de eigenschappen CurrentX en CurrentY van een Picturebox. Ook in een formulier kunt u deze eigenschappen gebruiken. Geeft de plaats aan waar een tekst of een afbeelding in het object gaat plaatsen. Denk eraan dat de Y-coordinaat van boven naar beneden wijst!
CurrentY
CurrentX
Tekst
Om de tekst te horizontaal centreren moeten we dus de volgende berekening maken: Tekstlengte Marge
Te centreren tekst Breedte van de PictureBox
Uit de figuur blijkt dat:
Visual Basic
door ir. C.Daniels
82
Marge
=
( Breedte PictureBox ) (Tekstlengte) − 2 2
Of in VB-code: Picture1.CurrentX = (Picture1.ScaleWidth/2) – (Picture1.TextWidth(tekst)/2)
ScaleWidth: breedte van het object PictureBox of van een Form ScaleHeight: hoogte van het object PictureBox of van een Form - Het aanpassen van het lettertype en grootte De teksteigenschappen kunne we aanpassen door de eigenschappen van het font te veranderen: Het lettertype (Font) kiezen: Picture1.Font = "Palace Script MT" De tekstgrootte (Size) kiezen we gelijk aan 1/3 van de hoogte van de PictureBox Picture1.Font.Size = Picture1.ScaleHeight / 3 De tekst cursief maken: Picture1.Font.Italic = True De tekst vetjes maken: Picture1.Font.Bold = True Ø Met de knop cmdWissen worden alle velden en de pictureBox leeggemaakt. Schrijf zelf
die code. Ø Experimenteer met andere lettertypes, en font-eigenschappen! Zoek ze op in de Help!
Hoe kunt u zorgen voor een witte tekst op een blauwe achtergrond?
Ø Voorbeeld 2 van een Subprocedure: Conversie van Eenheden. De bedoeling van dit voorbeeld is een snelheid uitgedrukt in een bepaalde eenheid (meter/sec bijvoorbeeld) om te rekenen naar andere grootheden zoals Mijl/seconde of Knopen.
Het project Conversie in werking
Visual Basic
door ir. C.Daniels
83
Ø Maak een nieuw project Conversie aan, en geef het weer zijn eigen map.
Plaats de onderstaande objecten op het ontwerpformulier: Label
ListBox
TextBox
CommandButton Ø Eigenschappen van de objecten
Object Form
Label TextBox
CommandButton ListBox
Eigenschappen Name: Form1 Caption: Conversie van Snelheden Height:2040 Width:3400 Name:lblTekst Caption: Waarde: Name: txtWaarde Text: (geen) Multiline: false Name: cmdBereken Caption:Berekenen Name:listEenheden
Ø De nodige omrekeningsfactoren plaatsen we als constanten in het gedeelte bovenaan
(General)(Declarations)
Visual Basic
door ir. C.Daniels
84
Ø De resultaten van de berekening tonen we in een apart venster, form2. Om dat venster bij te voegen aan het project klikt u in het menu op Projectà Add Form. U krijgt dan
onderstaande dialoog. Kies voor Form in het tabblad New en klik op Openen.
Uw project bevat nu twee formulieren, Form1 en Form2.
Visual Basic
door ir. C.Daniels
85
Selecteer nu Form2
. Plaats een CommandButton op het formulier:
En geef deze objecten de volgende eigenschappen Object Form
Eigenschappen Name:Form2 Autoredraw: true BackgroundColor: Palette: wit Caption: (niets) ControlBox: False Font: Arial 10p Height: 2800 StartUpPosition: Manual Width: 4800 CommandButton Name:cmdOK Caption: OK Visual Basic
door ir. C.Daniels
86
Zorg dat de twee formulieren Form1 en Form2 zichtbaar zijn, dan kunt u met de muis in het Form Layout Window de juiste plaats van de beide formulieren bij het openen aangeven:
Klik op de OK-knop en plaats volgende code in de eventprocedure cmdOK_Click van Form2:
Ø Selecteer nu terug Form1. Het event Form_Load van Form1 vullen we als volgt aan:
Private Sub Form_Load() ' De keuzemogelijkheden aan de ListBox toevoegen listEenheden.AddItem ("Km/sec") listEenheden.AddItem ("Km/uur") listEenheden.AddItem ("Meter/sec") listEenheden.AddItem ("Meter/min") listEenheden.AddItem ("Mijl/uur") listEenheden.AddItem ("Mijl/sec") listEenheden.AddItem ("Voet/sec") listEenheden.AddItem ("Knoop") listEenheden.AddItem ("Lichtsnelheid") Visual Basic
door ir. C.Daniels
87
End Sub Met de eigenschap AddItem van de ListBox vullen we de keuzelijst in. Private Sub cmdBereken_Click() Dim Waarde, conv As Double If listEenheden.ListIndex = -1 Then 'Waarschuwing als u geen eenheid kiest MsgBox "Kies de eenheid!" ElseIf Not IsNumeric(txtWaarde.Text) Then 'Waarschuwing als u geen geldig getal invult MsgBox "De ingegeven waarde is niet geldig!" Else 'OK, nu kunnen we gaan berekenen 'de waarde uit de textbox halen Waarde = Val(txtWaarde.Text) 'kies de conversie factor naargelang de gekozen eenheid Select Case listEenheden.ListIndex Case 0 conv = Kilometer_per_seconde Case 1 conv = Kilometer_per_uur Case 2 conv = Meter_per_seconde Case 3 conv = Meter_per_minuut Case 4 conv = Mijl_per_uur Case 5 conv = Mijl_per_seconde Case 6 conv = Voet_per_seconde Case 7 conv = Knoop Case 8 conv = Lichtsnelheid End Select 'Bereken conv, Waarde Call Bereken(conv, Waarde) 'En toon het ingevulde formulier Form2.Show 1, Me End If End Sub
Uitleg:
Visual Basic
door ir. C.Daniels
88
-
De eigenschap ListIndex geeft het volgnummer van het gekozen item uit de ListBox. Als u geen item aanklikt wordt de waarde –1 teruggegeven. Met de aanroep Call Bereken(conv, Waarde) roepen we de procedure Bereken aan, met als parameters de omrekeningsfactor conv en de waarde uit de TextBox.
-
Met de instructie Form2.Show 1, Me openen we formulier 2 modaal. Een modaal formulier moet u eerst sluiten voor u kunt verder werken in het originele formulier form1. Dit wordt aangegeven met de waarde 1 achter de instructie Show.
Ø De Sub-procedure Bereken moeten we helemaal zelf intypen in het gedeelte
(General)(Declarations) van Form1: Sub Bereken(c, w) Form2.Cls Form2.Print Str(w Kilometer/sec" Form2.Print Str(w Form2.Print Str(w Form2.Print Str(w Form2.Print Str(w Form2.Print Str(w Form2.Print Str(w Form2.Print Str(w Form2.Print Str(w End Sub
* c / Kilometer_per_seconde) & " * * * * * * * *
c c c c c c c c
/ / / / / / / /
Kilometer_per_uur) & " Kilometer/uur" Meter_per_seconde) & " Meter/sec" Meter_per_minuut) & " Meter/min" Mijl_per_uur) & " Mijl/uur" Mijl_per_seconde) & " Mijl/sec" Voet_per_seconde) & " Voet/sec" Knoop) & " Knopen" Lichtsnelheid) & " Lichtsnelheid"
Uitleg: Met de instructie Cls maken we het formulier Form2 eerst schoon. Met de instructie Print kunnen we tekst afdrukken.
2)
Functie-procedures
Functie-procedures worden ook kortweg functies genoemd. Het grote verschil tussen een subprocedure en een functie is dat een functie een waarde (integer, string,…) teruggeeft aan het aanroepende hoofdprogramma. Voorbeeldje: Stel dat we regelmatig de halve som S van twee getallen A en B moeten berekenen. We kunnen dit als volgt programmeren: A=20.5 Visual Basic
door ir. C.Daniels
89
B=37.75 S = (A + b)/2 Print S Als dit regelmatig voorkomt in ons programma, kunnen we van die formule beter een functie maken, als volgt:
' de declaratie van de functie Private Function HalveSom(M as double,N as double) as Double HalveSom = (M + N)/2 End Sub
' In het hoofdprogramma: … A = 20.5 B= 37.75 Print HalveSom A B 'de syntax Print Halvesom(A,B) mag ook …
Let goed op de structuur van een functie: Zelf gekozen naam van de functie
Private of Public
Woordje Function
Datatype van de berekende waarde in de functie
Parameters, echter niet verplicht
Private|Public Function Functienaam(parameter1 as type,…) as type Programmacode… … Functienaam = waarde of variabele End Function
Teruggeven aan het hoofdprogramma
Vergelijk met het bovenstaande voorbeeld van de functie Halvesom. Belangrijk: Bij de aanroep van de functie moet u evenveel parameters meegeven als er bij de declaratie van de functie werden aangegeven. Ook het datatype van elke parameter moet overeenkomen!
Visual Basic
door ir. C.Daniels
90
Ø Een heel eenvoudig voorbeeld van een functieaanroep kunt u als volgt programmeren:
Maak een nieuw project Functie1 aan, en plaats de volgende code in het programmavenster: Option Explicit 'De functie Product Private Function Product(a As Double, b As Double) As String Product = Str(a * b) End Function 'De eventprocedure Private Sub Form_Load() AutoRedraw = True Print "Het product van 5 en 7 is" & Product(5, 7) End Sub Ø Probeer uit! Wat is het resultaat bij de uitvoering?
Uitleg: de functie aanroep Product(5,7) plaatst de waarde 5 in de parameter a van de functie, en de waarde 7 in de parameter b. De functie berekent het product en geeft het resultaat, omgevormd tot een string Str(a*b), terug aan het hoofdprogramma. Voorbeelden van ingewikkelder toepassingen met functies zien we in het volgende hoofdstuk.
3)
Private en Public
Wanneer gebruikt u nu de instructie Private en Public? Een programma (project) bestaat meestal uit verschillende modules. Zo is er voor elk formulier (window) dat u nodig heeft een module met de layout van dat venster (met extensie *.frm) en de bijbehorende programmacode voor de afhandeling van events, en andere sub-programmas. U kan ook aparte programma-modules maken met alleen maar programmacode bevatten (extensie *.bas). Als een procedure Private wordt gedeclareerd, kan zij alleen maar aangeroepen worden vanuit deze module. Als zij Public wordt gedeclareerd is zij te gebruiken overal in het ganse project. Men noemt dat de scope van een procedure. Programma project MijnProject Module 1
Module 2
Module 3
Private Sub ProcX …. End Sub
Private Sub ProcY …. End Sub
Public Sub ProcZ …. End Sub
Andere procedures en functies van module 1 …. Aanroep: Visual BasicProcX() ‘ OK ProcY()‘ verboden ProcZ() ‘ OK
Andere procedures en functies van module 2 ….. Aanroep: door ir. C.Daniels ProcX() ‘ verboden ProcY() ‘ OK ProcZ() ‘ OK
Andere procedures en functies van module 3 ….. Aanroep: ProcX() ‘ verboden ProcY() ‘ verboden ProcZ() ‘ OK
91
Bovenstaand programma bestaat uit drie modules. De procedure X is alleen te gebruiken in Module 1. De procudure Y is alleen te gebruiken in Module 2. Terwijl de procedure Z te gebruiken is in de drie modules.
Visual Basic
door ir. C.Daniels
92
VII.
Lab 7 - Functie-procedures
Functieprocedures geven een waarde terug aan het hoofdprogramma. Laten we dat even uitproberen in het volgend voorbeeld van de calculator.
We zullen daar twee functies in gebruiken: - Private Function IsOk(Code As Integer) As Boolean Krijgt de code van de ingedrukte toets mee als parameter en geeft True terug als de toets ok is, anders False. Alleen cijfers, het punt en een minteken zijn toegelaten. - Private Function Bereken(xx As Double, _ yy As Double, Actie As Integer) As Double Krijgt de x-waarde, de y-waarde en het nummer(index) van de bewerkingstoets van de bewerking mee om de berekening uit te voeren. Geeft het resultaat als een Double terug
A. Nieuw project: de calculator Ø Maak een nieuw project aan Calculator1, en zet alles in een aparte map.Plaats de volgende objecten op het formulier: Label1 txtX Label2 txtY cmdCls
Array van 4 knoppen voor de 4 hoofdbewerkingen
lblresultaat
Array van knoppen: We plaatsen in dit formulier een array van knoppen. Dat zijn knoppen die allemaal dezelfde naam hebben cmdActie. Om eze van elkaar te onderscheiden krijgen ze Visual Basic
door ir. C.Daniels
93
elke een nummer, een zogenaamde index. De plusknop krijgt indexnummer 0, de min-knop indexnummer 1, enz. In het programma kunt u de minknop gebruiken als cmdActie(1). Een array van knoppen aanmaken Dat array aanmaken, kunt u gewoon door vier knoppen aan te maken, ze dezelfde naam te geven en de index-waarde voor elke knop juist te zetten. Het gaat makkelijker als volgt: - Plaats de eerste knop, de plusknop. - Geef hem de naam cmdActie. - Selecteer de knop, en kopieer hem door door in het menu Bewerkenàcopiëren te kiezen, of door op Ctrl-C te duwen. - Plak nu de knop driemaal terug door in het menu Bewerken à Plakken te kiezen of Ctrl-V in te duwen. Beantwoordt de vraag “Do you want to create a control array?” met JA.
Als u nu de indexen van de vier knoppen nakijkt in het venster Properties, zult u zien dat ze automatisch goed genummerd werden. Ø Geef de objecten de volgende eigenschappen:
Form
Label Label TextBox
TextBox
CommandButton (Array)
CommandButton
Label
Visual Basic
Name:Form1 Caption: Calculator Height:3800 Width: 4600 Name:Label1 Caption: X Name:Label2 Caption: Y Name: txtX Text: (geen) Font: MS Sans Serif 12p Vetjes Name: txtY Text: (geen) Font: MS Sans Serif 12p Vetjes Name:cmdActie Caption: + - x / Index: van 0 tot 3 Font:Arial Black 12p Vet Name: cmdCls Caption: Cls Font:Arial Black 12p Vet Name:lblResultaat Caption: (geen) Font:Arial Black 12p Vet
door ir. C.Daniels
94
Trek er vier rode lijnen rond (Line) Ø Typ de twee volgende functies in onder Option Explicit: Option Explicit ' Check of de ingedrukte toets een cijfer, een punt of minteken is Private Function IsOk(Code As Integer) As Boolean Select Case Code Case Asc("."), Asc("0") To Asc("9"), Asc("-") IsOk = True Case Else IsOk = False End Select End Function
' het resultaat berekenen Private Function Bereken(xx As Double, _ yy As Double, Actie As Integer) As Double Select Case Actie Case 0 Bereken = Case 1 Bereken = Case 2 Bereken = Case 3 Bereken = End Select End Function
xx + yy xx - yy xx * yy xx / yy
Uitleg: In de functie IsOk bevat de parameter Code de ascii-code van de ingedrukte toets Bij de functie Bereken, worden de parameters X, Y, en Actie meegegeven. Actie is de index van de gekozen bewerkingstoets. Ø Vul het event cmdActie_Click als volgt in (de index van de toets komt automatisch mee
als parameter) Private Sub cmdActie_Click(Index As Integer) Dim x As Double, y As Double ' Kijk of het een geldig getal is If Not IsNumeric(txtX.Text) Then MsgBox "Het eerste getal is ongeldig", vbOKOnly Exit Sub ElseIf Not IsNumeric(txtY.Text) Then MsgBox "Het tweede getal is ongeldig", vbOKOnly Exit Sub End If ' Zet de waarden uit de textvelden in een variabele x = Val(txtX.Text) y = Val(txtY.Text)
Visual Basic
door ir. C.Daniels
95
' delen door nul kan niet If (Index = 3) And (y = 0) Then MsgBox "Deling door nul", vbOKOnly Exit Sub End If ' ok, maak de bewerking lblResultaat.Caption = Str(Bereken(x, y, Index)) End Sub
Ø We gaan ook de toetsaanslagen onderscheppen: als het geen geldig teken is (cijfer,
punt of minteken, vagen we de aanslag uit (=0) en laten een geluidje horen. Kies daartoe het event KeyPress van de textboxen txtX en txtY. De ascii-code van de ingedrukte toets zit dan in de parameter KeyAscii. Private Sub txtX_KeyPress(KeyAscii As Integer) If Not IsOk(KeyAscii) Then Beep KeyAscii = 0 End If End Sub Private Sub txtY_KeyPress(KeyAscii As Integer) If Not IsOk(KeyAscii) Then Beep KeyAscii = 0 End If End Sub Ø Bij het klikken op de knop Cls moeten alle velden uitgewist worden:
Private Sub cmdCls_Click(Index As Integer) txtX = "" txtY = "" lblResultaat.Caption = "" End Sub
Ø Het programma is klaar! Test het uit! Ø Opdracht: voeg een knop bij om X
Y
te berekenen. Daarmee kunt u ook worteltrekken want dat is verheffen tot de macht 0.5, of derdemachtswortel…
Visual Basic
door ir. C.Daniels
96
Ø Breidt de voorgaande calculator uit met een array van vier knoppen met naam
cmdFunctie (indexen 0 tot 3) waarmee de wiskundige functies sin, cos,tg en ln (natuurlijk logaritme grondtal e=2.71852…) kunnen berekend worden van de waarde in veld X.
Ln(2.71852) berekenen
Bij een foutieve ingave
Ø Hieronder de code van het event cmdFunctie_Click. Schrijf zelf de code van de functie
BerekenFunctie() Private Sub cmdFunctie_Click(Index As Integer) Dim Waarde As Double ' controleer eerst of de x-waarde wel numeriek is If Not IsNumeric(txtX.Text) Then MsgBox "X-waarde is niet numerisch",vbOkOnly Exit Sub End If ' ok, maak de bewerking Waarde = Val(txtX.Text) lblResultaat.Caption = Str(BerekenFunctie(Waarde, Index)) End Sub Ø Opgave: Welke wiskundige functies bestaan in VB? En hoe kunt u bijvoorbeeld de
Briggse logaritme berekenen (basis grondtal 10) ?Zoek op in de Help.
Een meer geavanceerde calculator vindt u in het hoofdstuk Projecten achteraan. Visual Basic
door ir. C.Daniels
97
B. ByVal en ByRef Parameters kunt u op twee manieren doorgeven aan een functie: - als waarde (by value) - als referentie (by reference) By Value: alleen de waarde van de variabele wordt doorgegeven aan de procedure. By Reference: hier wordt niet de waarde van de variabele doorgegeven, maar wel de plaats van de variabele in het geheugen, ook het adres van de variabele genoemd. Dit heeft tot gevolg dat u een parameter niet van waarde kunt wijzigen in de functie als u hem als waarde doorgeeft, maar wel als u een referentie doorgeeft. Ø Probeer dit eens uit aan de hand van volgend voorbeeld. Maak een nieuw project aan
met naam ValRef, en plaats het in zijn eigen map met dezelfde naam. Ø Typ de volgende code in:
Option Explicit Private Sub Test(ByVal x As Integer, ByRef y As Variant, _ z As Integer) x = x + 1 y = y + 1 z = z + 1 Print "In de functie Test"; x; y; z End Sub Ø Plaats de volgende code in het event Form_Click
Private Sub Form_Click() Dim x, y, z As Integer x = 1: y = 1: z = 1 Cls Print "Voor de functie Test"; x; y; z Call Test(x, y, z) ' de schrijfwijze Test x,y,z mag ook Print "Na de functie Test"; x; y; z End Sub Ø Start het programma, en klik op het formulier. Wat gebeurt er met de waarde van x, y
en z?
Visual Basic
door ir. C.Daniels
98
De uitleg is vrij eenvoudig. Variabelen zijn op een bepaalde geheugenplaats opgeslagen. Deze geheugenplaatsen zijn genummerd. Dit nummer noemen we het adres van de variabele. Als we een parameter als waarde doorgeven, geven we alleen de waarde mee. Waar de echte variabele staat in het geheugen weet de functie niet, en kan de originele waarde van de variabele dus niet veranderen. Als we een parameter als referentie doorgeven, geven we het adres mee van de variabele. Nu kan de functie de waarde van de originele variabele wel veranderen. RAM-geheugen Adressen … 9101 à 9100 à 9099 à 9098 à 9097 à …
Inhoud / Waarde
1500
Variabele X
Als u de functie Test met een parameter X ByVal meegeeft, doet u in feite de volgende aanroep: Test(1500) Geeft u de parameter mee als referentie mee, dan doet u de volgende aanroep: Test(9100) In dit laatste geval wordt niet de waarde maar het adres meegegeven, vandaar dat in de functie de paramater dan moet aangegeven worden met het type Variant en niet als integer. Het adres is immers geen integer, maar een speciaal type. Een goed begrip hiervan is erg belangrijk als u goed wilt leren programmeren! Ø Wat is de default waarde, als u dus niets aangeeft bij de parameter, zoals bij de z in
voorgaand voorbeeld? Ø Wat gebeurt er als u in voorgaand voorbeeld de parameter y toch als integer
aangeeft?
Visual Basic
door ir. C.Daniels
99
VIII. Werken met Bestanden Al de informatie die u in het RAM-geheugen van een computer opslaat, verdwijnt als u het programma afsluit. Als u gegevens langer wil bewaren, moet u deze gegevens op een schijf (diskette of harde schijf) van uw pc opslaan. De computer slaat deze gegevens op in bestanden (Engels: files). Er bestaan twee essentieel verschillende soorten van bestanden: •
•
Sequentiële bestanden om tekst op te slaan. Kenmerken: - Uitsluitend voor tekstgegevens - Variabele lengte van een record. Elke lijn wordt afgesloten met de karakters CR en LF. - Kan alleen gelezen worden van voor naar achteren Random-access bestanden voor andere gegevens. Kenmerken: - Is in principe geschikt voor alle soorten van gegevens - Vaste recordlengte - Mogelijkheid om een willekeurige record op te halen.
In beide soorten is het mogelijk om gegevens te lezen (input) vanaf de diskette naar het RAM-geheugen, en te schrijven (output) vanuit het RAM-geheugen naar de diskette. Laten we deze twee types even wat nader bekijken en toepassen in Visual Basic.
A. Sequentiële bestanden Sequentiële bestanden kunnen alleen gebruikt worden voor het opslaan van tekst. Deze tekst moet opgedeeld zijn in lijnen, per lees- of schrijfoperatie wordt één enkele lijn gelezen. Elke lijn heet een record van het bestand. Het bestand kan ook maar alleen van voor naar achteren worden gelezen of geschreven. Om iets terug te vinden moet u door het ganse bestand lezen, totdat u aan de gevraagde passage aanbelandt. Zowel bij het lezen als het schrijven van bestanden zijn drie verschillende bewerkingen nodig: 1. Het openen van een bestand. Hier worden buffers in het geheugen vrijgemaakt om de gevraagde bewerkingen mogelijk te maken. 2. Een of meerdere lees- en/of schrijfbewerkingen 3. Het sluiten van het bestand. Omgekeerde van het openen. Om hierin wat meer kennis te vergaren, kunnen we enkele eenvoudige oefeningen maken.
Visual Basic
door ir. C.Daniels
100
4)
Een sequentieel bestand schrijven Ø Oefening:
Maak een nieuw project aan met naam Bestanden1. Zet het liefst in aparte map met dezelfde naam. Plaats een knop linksonder op het formulier, met de naam cmdOpslaan en de caption Opslaan. De bedoeling is enkele records te schrijven in een bestand text.txt op een diskette. Zorg dus dat er een diskette met voldoende ruimte in het diskettestation steekt. Type volgende code in het event cmdOpslaan_Click: Private Sub cmdOpslaan_Click() Print "Bestand wordt geopend" Open "a:\test.txt" For Output As #1 Print #1, "Record een" Print "Record 1 opgeslagen" Print #1, "Record twee" Print "Record 2 opgeslagen" Print #1, "Laatste record" Print "Record 3 opgeslagen" Close #1 Print "Bestand terug gesloten." End Sub
Uitleg: Open "a:\test.txt" For Output As #1 - Open “a:\test.txt”: met deze code wordt een bestand test.txt geopend in de root-map op de diskette a:\. Het bestand wordt aangemaakt, want het bestaat nog niet. Moest het bestaan wordt het oude overschreven! - For Output : betekent dat er informatie gaat geschreven worden. - As #1: elk bestand dat in een programma wordt gebruikt krijgt een nummer (filehandle genoemd), zodat we meerdere bestanden kunnen openen. Het nummer wordt gebruikt om aan te geven in welk bestand er gelezen of geschreven wordt. Dan worden er drie records (hier teksten) geschreven: Print #1, "Record een" Print #1 : schrijf in het bestand met file-handle 1, dus hier in a:\test.txt “Record een” De tekst die weggeschreven wordt. Close #1 Visual Basic
door ir. C.Daniels
101
Deze code sluit het bestand met file-handle 1 weer af.
Tip: Sluit aan het einde van een programma steeds de geopende bestanden af! Anders kan er informatie verloren gaan. De code Close (zonder nummer) sluit alle geopende bestanden af. Tussen elke bewerking hebben we een print-statement gezet, zodat we op het formulier kunnen volgen wat er gebeurt. Ø Klik op de knop “Opslaan”. Uw formulier ziet er dan zo uit:
Ons programma heeft een tekstbestand met de naam test.txt op de diskette geschreven. Als het niet lukt: kijk dan of de diskette wel goed is, geformatteerd is, niet beveiligd tegen schrijven en nog voldoende vrije ruimte heeft (enkele kByte is hier voldoende). We zullen straks het programma zelf laten controleren of alles goed verloopt!
Dit kun je controleren door even met het Kladblok dit bestand te openen:
U ziet dat er 3 records geschreven werden, met de inhoud zoals teksten in ons testprogramma.
Met het dos-proramma type kunnen we eveneens de tekst van het bestand afdrukken. A:\>type test.txt Record een Record twee Laatste record
Visual Basic
door ir. C.Daniels
102
Met het dos-programma debug, kunnen we precies zien, wat er nu eigenlijk op de diskette werd geschreven: hexadecimaal A:\>debug test.txt -d 1A27:0100 52 65 63 een..Reco 1A27:0110 72 64 20 twee..Laatste 1A27:0120 20 72 65 ....u 1A27:0130 59 80 7C Y.|.:uS.....,A.. 1A27:0140 3C 1A 77 <.wF.........@t. 1A27:0150 E8 5B 00 .[.r.r......t..W 1A27:0160 01 EB F2 ....}..t..E..?t. 1A27:0170 85 55 02 .U.t............ -q A:\>
Stuurkarakters
Dezelfde tekst leesbaar
6F 72 64 20 65-65 6E 0D 0A 52 65 63 6F
Record
74 77 65 65 0D-0A 4C 61 61 74 73 74 65
rd
63 6F 72 64 0D-0A 74 20 83 7F 05 02 75
record..t
01 3A 75 53 8A-04 E8 1C EC 2C 41 FE C0 46 A2 91 D3 B0-04 EB C8 F6 05 40 74 09 72 CE 72 2E EB-BA F6 05 80 74 1F E8 57 83 7D 02 FF 74-0C F7 45 02 FF 3F 74 12 74 0D B0 01 89-16 91 D3 EB 96 B8 01 00
Links staan de geheugenadressen waarop de data werden ingelezen. We gaan hier niet verder op in. In het midden vindt u de hexadecimale ascii-codes van de geschreven karakters: 5216 = 5x16 + 2 = 8210 = “R” = karakter nr.82 uit de asciicode 6516 = 6x16 + 5 = 10110 = “e” = karakter nr.101 uit de asciicode 6316 = 6x16 + 3 = 9910 = “c” = karakter nr.99 uit de asciicode enz…
Uiterst rechts staan de afdrukbare tekens in leesbare vorm. Tussen elke record vindt u de code 0D (= 1310) 0A (= 1010). Dit zijn de codes voor de ascii-stuurkarakters Carriage Return (naar begin van de lijn), en Line Feed (nieuwe lijn). Deze worden niet afgedrukt op het scherm of de printer, maar laten de cursor naar het begin van de lijn terugspringen en dan naar de volgende lijn. Dit is een voornaam kenmerk van sequentiële bestanden. Waarom dit belangrijk is zien we later. U ziet dat er achteraan ook enkele onleesbare gedeelten zijn (niet meer vetjes afgedrukt), voorbij het einde van het bestand. De lengte van het bestand wordt ook ergens opgeslagen op de diskette, zodat de computer weet welke tekens nog zinvol zijn en tot het bestand behoren en welke niet meer. Dit zijn resten van informatie die vroeger op de diskette werd geschreven.
Visual Basic
door ir. C.Daniels
103
5)
Een sequentieel bestand lezen
Laten we nu de code bekijken die het zojuist aangemaakte bestand leest en deze tekst op het scherm afdrukt. Ø Voeg een tweede knop toe aan bestand met de naam cmdLezen, en de caption Lezen.
Plaats de volgende code in het event cmdLezen_Click: Private Sub cmdLezen_Click() Dim Lijn As String Print "Bestand wordt geopend om te lezen" Open "a:\test.txt" For Input As #1 While Not EOF(1) Input #1, Lijn Print Lijn Wend Close #1 Print "Bestand is terug gesloten." End Sub
Als u op de knop Lezen klikt krijgt u volgend resultaat:
Uitleg: Dim Lijn As String We declareren een variabele Lijn als een string. Hierin slaan we telkens een lijn op van ons bestand. Open "a:\test.txt" For Input As #1 Het bestand test.txt op de diskette wordt geopend om te lezen met file-handle 1. While Not EOF(1) Input #1, Lijn Print Lijn Visual Basic
door ir. C.Daniels
104
Wend Een while-lusinstructie. De lus werkt zolang het einde van het bestand niet is bereikt. Als we alles gelezen hebben, wordt de functie EOF(1) WAAR, en stopt de lus. EOF staat voor End Of File. De parameter (1) slaat op de file-handle van het geopende bestand. De instructie Input #1,Lijn leest één record en plaatst de inhoud ervan in de stringvariabele Lijn. De instructie Print Lijn drukt de inhoud van Lijn af op het formulier. Close #1 Het bestand wordt terug gesloten.
6)
Fouten opvangen
Als het bestand test.txt niet op de diskette staat krijgt u volgende foutmelding:
Klik op End om het programma te stoppen. In Visual Basic kunnen we dergelijke fouten opvangen met de On error goto instructie. Pas de code van het inlezen als volgt aan: Private Sub cmdLezen_Click() Dim Lijn As String Print "Bestand wordt geopend om te lezen" On Error GoTo Fout Open "a:\test.txt" For Input As #1 While Not EOF(1) Input #1, Lijn Print Lijn Wend Close #1 Print "Bestand is terug gesloten." Exit Sub Fout: MsgBox "Fout nr. " + Str(Err.Number) + " opgetreden!" + _ Chr(13) + Chr(10) + Err.Description End Sub
Visual Basic
door ir. C.Daniels
105
Dezelfde fout geeft nu het volgende pop-upscherm:
Uitleg: On error goto naam: Als er na deze instructie een fout optreedt, springt het programma naar de plaats waar de naam: staat. Fout : MsgBox "Fout nr. " + Str(Err.Number) + " opgetreden!" + _ Chr(13) + Chr(10) + Err.Description Een fout schept steeds een fout-object met de naam Err. Een eigenschap is het foutnummer (aangeduid met Err.number) en de beschrijving van de fout (aangeduid met Err.description) Beide worden afgedrukt in de popup als er een fout optreedt. De karakters 13 en 10 kenden we al. Let op de dubbele punt achter het label Fout: Op dezelfde manier kunnen we ook het opslaan van het bestand beveiligen. We kunnen zelfs eerst testen of het bestand al bestaat, door het eerst proberen te openen voor input. Als het blijkt dat we dat kunnen, bestaat het reeds, en kunnen we vragen of de gebruiker het bestaande bestand wil afvegen. Ø De test kunnen we in een functie-procedure onderbrengen als volgt:
Private Function BestandBestaat() As Boolean BestandBestaat = False On Error GoTo BestaatNiet: Open "a:\test.txt" For Input As #1 BestandBestaat = True Close #1 Exit Function BestaatNiet: BestandBestaat = False End Function
De redenering is als volgt: als het bestand kan geopend worden bestaat het: BestandBestaat = True In het andere geval bestaat het bestand niet (of is er een andere fout opgetreden)
Visual Basic
door ir. C.Daniels
106
Plaats deze code ergens bovenaan in uw programma. De procedure Opslaan wordt nu als volgt aangepast: Private Sub cmdOpslaan_Click() Dim Ant As Integer Ant = vbYes If BestandBestaat Then Ant = MsgBox("Bestand bestaat al! Overschrijven?", vbYesNo, "Opgelet!") End If If Ant = vbYes Then Cls Print "Bestand wordt geopend" On Error GoTo Fout Open "a:\test.txt" For Output As #1 Print #1, "Record een" Print "Record 1 opgeslagen" Print #1, "Record twee" Print "Record 2 opgeslagen" Print #1, "Laatste record" Print "Record 3 opgeslagen" Close #1 Print "Bestand terug gesloten." Exit Sub Else Cls Print "Bestand werd niet overschreven." End If Exit Sub Fout: MsgBox "Fout nr. " + Str(Err.Number) + " opgetreden!" + _ Chr(13) + Chr(10) + Err.Description End Sub
Als het bestand reeds bestaat, krijgt u nu volgende messagebox bij het opslaan:
Visual Basic
door ir. C.Daniels
107
Ø Test het aangepaste programma uit! Simuleer enkele fouten, zoals het weglaten van de
diskette uit de drive.
7)
De Append-optie
Er is nog een derde manier beschikbaar om een bestand te openen: Append. Hiermee kun je achteraan tekst toevoegen aan het bestand. Laten we dit even uitproberen. We gebruiken hierbij een Inputbox om extra tekst te kunnen ingeven. Dit kunt u vergelijken met een messagebox, met de extra mogelijkheid om wat data in te tikken. Ø Voeg een nieuwe knop toe aan uw programma met de naam cmdAppend, en de
caption Append. In het event cmdAppend_Click plaatst u volgende code: Private Sub cmdAppend_Click() Dim strNieuweTekst As String strNieuweTekst = InputBox("Type een tekst:", "Tekst bijvoegen") If strNieuweTekst <> "" Then Print "Bestand wordt geopend voor append" On Error GoTo Fout Open "a:\test.txt" For Append As #1 Print #1, strNieuweTekst Close #1 Print "Bestand is terug gesloten." Exit Sub Fout: MsgBox "Fout nr. " + Str(Err.Number) + " opgetreden!" + Chr(13) + Chr(10) + _ Err.Description End If End Sub
Als u de knop Append aanklikt krijgt u dan onderstaande InputBox waarin u tekst kunt typen die u aan het bestand wil toevoegen:
Als u dan terug op Lezen klikt, krijgt u het aangevulde bestand te zien:
Visual Basic
door ir. C.Daniels
108
Ingevoegde tekstlijn
Ø Oefening 1: Vraag met een inputbox naar het nummer van een record, en
laat dan de tekst van deze record af, als hij bestaat. Als het nummer groter is dan het aantal records in het bestand moet er een messagebox met een foutmelding worden weergegeven. Voorbeeld: u geeft het nummer 3 in, dan moet de tekst “Laatste record” uit het bestand op het formulier verschijnen. Tip: gebruik een teller en lees de records vanaf het begin van het bestand. Voor elke gelezen record telt u één op bij de teller. Tot u de gevraagde record bereikt.
Ø
Oefening 2: schrijf een programma dat het bestand test.txt opent om te lezen, en een tweede bestand test2.txt om te schrijven. Schrijf de inhoud van bestand test.txt over naar bestand test2.txt en verander daarbij alle letters in hoofdletters. Zet de benodigde code hiervoor bijvoorbeeld achter een extra knop met caption Hoofdletters in het voorgaande programma.
Tip: Gebruik de functie Ucase, om tekst om te zetten in hoofdletters. Gebruik filehandle 1 voor test.txt en file-handle2 voor test2.txt. Lees telkens een regel in test1.txt, verander deze in hoofdletters, en schrijf deze regel weg naar bestand test2.txt.
Ø
Oefening 3: Pas het programma zodanig aan dat u met een een inputbox naar de naam van het bestand vraagt, zodat u een willekeurig bestand kunt inlezen.
Tip: declareer een variabele strBestandsnaam om de naam uit de inputbox op te slaan. Met de code Open strBestandsnaam For Input As #1 kunt u dan proberen het bestand te openen. Voorzie ook de nodige foutafhandeling, bijvoorbeeld als het gevraagde bestand niet bestaat!
Ø Oefening:
Visual Basic
door ir. C.Daniels
109
Schrijf een VB-programma dat een tekstbestand inleest, alle tekst naar hoofdletters converteert, en wegschrijft in een nieuw bestand. Vraag de naam van het in te lezen tekstbestand, en de naam van het uitvoerbestand op in twee textboxen. Tips: maak gebruik van de VB-functie Ucase() om de tekst te converteren (probeer eerst uit in het Immediate Window!). Open het invoerbestand bijvoorbeeld For Input as #1, en het te schrijven bestand For Output as #2. Lees telkens één lijn in het invoerbestand, converteer naar hoofdletters, en schrijf die lijn weg naar het uitvoerbestand. B. Random access bestanden In het volgende project maken we een programma dat adresgegevens opslaat in een random access bestand met de naam Adres.dat. Het grote voordeel is dat we onmiddellijk elke record kunnen terugvinden (lezen en schrijven) aan de hand van zijn volgnummer, zonder het ganse bestand te moeten doorlopen. Om met dit type van bestanden te kunnen werken heb je een recordstructuur nodig. Stel dat we naam, woonplaats en geboortedatum van een aantal personen in een dergelijk bestand willen opslaan. We gaan hiervoor een record-type aanmaken: Type Adres Naam As String * 14 Woonplaats As String * 30 Geboortedatum As Long End Type In ons programma kunnen we nu een nieuwe variabele Kennis declareren van het type Adres als volgt: Private Kennis as Adres De naam van een adres bereiken we door de uitdrukking: Kennis.Naam Men noemt dit de punt-operator. Deze wordt courant gebruikt in object georiënteerd programmeren. Kennis is eigenlijk een object met de eigenschappen Naam, Woonplaats en Geboortedatum. Visual Basic is eigenlijk een object georiënteerde taal. Zo is ook elk formulier, knop of tekstveld een object met eigenschappen (Caption, Font,…) en met methodes (Load, Click,…). Voor verdere informatie over Object Georiënteerd Programmeren (OOP = Object Oriented Programming) verwijzen we naar gepaste handboeken.
Visual Basic
door ir. C.Daniels
110
8)
Een random access bestand beheren
Dit gebeurt met het commando: Open "bestandsnaam" For Random As #filehandle Len = RecordLengte Elke record heeft nu een vaste recordlengte afhankelijk van de gegevens. Een record wegschrijven gaat met de put-instructie: Put #filehandle, recordnummer, RecordData Een record inlezen gebeurt met de get-instructie: Get #filehandle, recordnummer, RecordData Het bestand sluiten gaat weer met close: Close #filehandle
Ø Oefening: maak een nieuw project aan met de naam RandomAccess. Geef het weer een plaatsje in een aparte map op je diskette, of HD. Plaats de volgende objecten op je formulier:
lblInfo
Geef de objecten de volgende eigenschappen: Object Eigenschap Formulier Form1 Caption: Demo Random Access Knop Nieuw Name: cmdNieuw Caption: Nieuw Knop Invoeren Name: cmdInvoeren Caption: Invoeren Knop Annuleren Name: cmdAnnuleren Caption: Annuleren Knop Eerste Record Name: cmdEerste Caption: Eerste Record Knop Volgende Name: cmdVolgende Caption: Volgende Visual Basic
door ir. C.Daniels
111
Knop Vorige Knop Laatste Record Label Naam Label Woonplaats Label Geboortedatum Textbox Naam Textbox Woonplaats Textbox Geboortedatum Label Info
Name: cmdVorige Caption: Volgende Name: cmdLaatste Caption: Laatste Record Name: lblNaam Caption: Naam: Name: lblWoonplaats Caption: Woonplaats Name:lblGeboortedatum Caption: Gebortedatum Name: txtNaam Text: (leeg) Name: txtWoonplaats Text: (leeg) Name:txtGeboortedatum Text: (leeg) Name: lblInfo Caption: (leeg) BackColor: kies een aangepaste kleur
Ø Plaats de structuur van de record in een aparte bas-module: Kies Project à Add Module:
Ø Kies Openen.
In deze module plaatst u volgende code:
Visual Basic
door ir. C.Daniels
112
Een bas-module bevat code die in het ganse programma nuttig is. Het is niet verbonden aan een formulier. Modules kunt u ook inlassen in andere programma’s, zodat de code niet opnieuw moet worden geschreven. Na het invoeren van deze module moet het project-venster er als hiernaast uitzien: Ø Laten we nu de verschillende events programmeren, eerst het openen van het
formulier: Private Sub Form_Load() Dim i As Integer RecordLengte = Len(Kennis) ' Vang eventuele fouten op On Error GoTo Foutmelding 'Open het bestand op de diskette Open "a:\Adres.dat" For Random As #1 Len = RecordLengte 'Niet nodig, ter info in het Immediate Window Debug.Print "Bestand wordt geopend" Debug.Print "Lengte van het bestand in bytes: " + Str(LOF(1)) Debug.Print "Recordlengte: " + Str(RecordLengte) ' Bereken het aantal records in het bestand AantalRecords = LOF(1) / RecordLengte ' kijk of het misschien nog leeg is If AantalRecords = 0 Then lblInfo = "Het bestand is leeg. Klik op nieuw." cmdEerste.Enabled = False cmdLaatste.Enabled = False cmdVolgende.Enabled = False cmdVorige.Enabled = False cmdNieuw.Enabled = True cmdInvoeren.Visible = False cmdAnnuleren.Visible = False Else lblInfo = "Er zijn " + Str(AantalRecords) + " records aanwezig" cmdEerste.Enabled = True cmdLaatste.Enabled = True cmdVolgende.Enabled = True cmdVorige.Enabled = True cmdNieuw.Enabled = True cmdInvoeren.Visible = False cmdAnnuleren.Visible = False HuidigeRecord = 1 ToonRecord (1) End If Exit Sub Foutmelding: MsgBox "Fout nr. " + Str(Err.Number) + " opgetreden!" + _ Chr(13) + Chr(10) + Err.Description End Sub
Visual Basic
door ir. C.Daniels
113
Uitleg: Dim i As Integer
Wordt alleen gebruikt voor de msgBox RecordLengte = Len(Kennis)
Met de VB-functie len() bepalen we het aantal bytes nodig voor één record On Error GoTo Foutmelding
Vang eventuele fouten op Open "a:\Adres.dat" For Random As #1 Len = RecordLengte
Open het bestand op de diskette , en we zetten de recordlengte gelijk aan de berekende lengte. Debug.Print "Bestand wordt geopend" Debug.Print "Lengte van het bestand in bytes: " + Str(LOF(1)) Debug.Print "Recordlengte: " + Str(RecordLengte)
Deze lijnen zijn niet nodig maar in een testfase geven ze interessante info over het bestand in het Immediate-window. Als het programma naar behoren werkt, kunt u ze verwijderen. AantalRecords = LOF(1) / RecordLengte
Bereken het aantal records in het bestand. De functie LOF(filehandle) geeft de lengte van het geopende bestand in bytes. If AantalRecords = 0 Then lblInfo = "Het bestand is leeg. Klik op nieuw." cmdEerste.Enabled = False cmdLaatste.Enabled = False cmdVolgende.Enabled = False cmdVorige.Enabled = False cmdNieuw.Enabled = True cmdInvoeren.Visible = False cmdAnnuleren.Visible = False Else lblInfo = "Er zijn " + Str(AantalRecords) + " records aanwezig" cmdEerste.Enabled = True cmdLaatste.Enabled = True cmdVolgende.Enabled = True cmdVorige.Enabled = True cmdNieuw.Enabled = True cmdInvoeren.Visible = False cmdAnnuleren.Visible = False HuidigeRecord = 1 ToonRecord (1) End If Exit Sub
Visual Basic
door ir. C.Daniels
114
In deze code wordt getest of het bestand nog leeg is ( AantalRecords = 0). Dan wordt alleen de knop Nieuw toegankelijk gemaakt, om een nieuwe record in te voeren. Ook de knoppen Invoeren en Annuleren worden zichtbaar. Als er al records aanwezig zijn, worden de knoppen Invoeren en Annuleren onzichtbaar gemaakt, en wordt het aantal aanwezige records getoond in het label Info. Foutmelding: MsgBox "Fout nr. " + Str(Err.Number) + " opgetreden!" + _ Chr(13) + Chr(10) + Err.Description
De foutafhandeling vermeld het foutnummer en de omschrijving van de opgetreden fout. ToonRecord (1)
Deze code roept een subprocedure aan, die de record vermeld tussen haakjes (hier 1) toont in de textboxen. Ø Plaats de volgende code hiervoor vooraan in je programma. Dimensioneer ook de
nodige variabelen zoals hieronder: Option Explicit Private Kennis As Adres ' bevat de data van één record Private RecordLengte As Integer ' de lengte van de record Private HuidigeRecord As Integer ' het nummer van de huidige record Private AantalRecords As Integer 'het aantal records in het bestand 'Toon record #n op het scherm Private Sub ToonRecord(n As Integer) Get #1, n, Kennis txtNaam = Kennis.Naam txtWoonplaats = Kennis.Woonplaats txtGeboortedatum = Format(Kennis.Geboortedatum, "dddd, d/mm/yyyy") lblInfo.Caption = "Record #" + Str(n) End Sub
Ø Het event Nieuwe record invoeren: cmdNieuw_Click
Private Sub cmdNieuw_Click() txtNaam.Text = "" txtWoonplaats = "" txtGeboortedatum = "" cmdEerste.Enabled = False cmdLaatste.Enabled = False cmdVolgende.Enabled = False cmdVorige.Enabled = False cmdNieuw.Enabled = False cmdInvoeren.Visible = True cmdAnnuleren.Visible = True End Sub
Visual Basic
door ir. C.Daniels
115
Uitleg: Als we de knop Nieuw aanklikken worden de tekstvelden leeggemaakt, zodat we nieuwe gegevens kunnen invullen. Tevens worden de knoppen Invoeren (om de gegevens in het bestand te schrijven) en Annuleren (om de bewerking te schrappen) zichtbaar gemaakt. Ø Het event Invoeren: de gegevens wegschrijven in het bestand:
Private Sub cmdInvoeren_Click() Dim i As Integer Kennis.Naam = txtNaam.Text Kennis.Woonplaats = txtWoonplaats.Text If Not (IsDate(txtGeboortedatum.Text)) Then MsgBox txtGeboortedatum.Text & " is geen geldige datum." Exit Sub Else Kennis.Geboortedatum = CDate(txtGeboortedatum.Text) End If If Trim(Kennis.Naam) = "" Or Trim(Kennis.Woonplaats) = "" Then i = MsgBox("U moet de 3 velden juist invullen", vbExclamation, "Foutieve Ingave") Exit Sub Else AantalRecords = AantalRecords + 1 On Error GoTo Foutmelding Put #1, AantalRecords, Kennis lblInfo = "Er zijn " + Str(AantalRecords) + " records aanwezig" cmdEerste.Enabled = True cmdLaatste.Enabled = True cmdVolgende.Enabled = True cmdVorige.Enabled = True cmdNieuw.Enabled = True cmdInvoeren.Visible = False cmdAnnuleren.Visible = False End If Exit Sub Foutmelding: MsgBox "Fout nr. " + Str(Err.Number) + " opgetreden!" + _ Chr(13) + Chr(10) + Err.Description End Sub
Visual Basic
door ir. C.Daniels
116
Uitleg: Kennis.Naam = txtNaam.Text Kennis.Woonplaats = txtWoonplaats.Text
Plaats de teksten uit de velden Naam en Woonplaats in de record. If Not (IsDate(txtGeboortedatum.Text)) Then MsgBox txtGeboortedatum.Text & " is geen geldige datum." Exit Sub Else Kennis.Geboortedatum = CDate(txtGeboortedatum.Text) End If
Test of de ingevoerde datum correct is met de functie IsDate(). Deze geeft true voor een geldige datum, en false voor een foutieve datum. Bij een foutieve datum wordt de bewerking afgebroken met Exit Sub. If Trim(Kennis.Naam) = "" Or Trim(Kennis.Woonplaats) = "" Then i = MsgBox("U moet de 3 velden juist invullen", vbExclamation, "Foutieve Ingave") Exit Sub Else
Test of de velden naam en woonplaats ingevuld zijn. De functie Trim() verwijdert onnodige spaties. AantalRecords = AantalRecords + 1 On Error GoTo Foutmelding Put #1, AantalRecords, Kennis lblInfo = "Er zijn " + Str(AantalRecords) + " records aanwezig" cmdEerste.Enabled = True cmdLaatste.Enabled = True cmdVolgende.Enabled = True cmdVorige.Enabled = True cmdNieuw.Enabled = True cmdInvoeren.Visible = False cmdAnnuleren.Visible = False
Alles is goed ingevuld, het aantalRecords wordt dus met één verhoogd, en we kunnen de record wegschrijven met het put-commando. De knoppen Invoeren en Annuleren worden weer onzichtbaar gemaakt. Ø Het event Annuleren (nieuwe gegevens invoeren annuleren):
Private Sub cmdAnnuleren_Click() lblInfo = "Er zijn " + Str(AantalRecords) + " records aanwezig" cmdEerste.Enabled = True cmdLaatste.Enabled = True cmdVolgende.Enabled = True cmdVorige.Enabled = True cmdNieuw.Enabled = True cmdInvoeren.Visible = False cmdAnnuleren.Visible = False End Sub
Visual Basic
door ir. C.Daniels
117
Ø Het event Eerste Record (toont de eerste record van het bestand):
Private Sub cmdEerste_Click() If AantalRecords = 0 Then MsgBox ("Het bestand is nog leeg! Voer gegevens in!") Else HuidigeRecord = 1 ToonRecord (HuidigeRecord) End If End Sub Ø Het event Volgende Record:
Private Sub cmdVolgende_Click() If HuidigeRecord >= AantalRecords Then MsgBox ("Einde van het bestand bereikt!") Else HuidigeRecord = HuidigeRecord + 1 ToonRecord (HuidigeRecord) End If End Sub
Ø Het event Vorige Record:
Private Sub cmdVorige_Click() If HuidigeRecord <= 1 Then MsgBox ("Begin van het bestand bereikt!") Else HuidigeRecord = HuidigeRecord - 1 ToonRecord (HuidigeRecord) End If End Sub Ø Het event Laatste Record:
Private Sub cmdLaatste_Click() If AantalRecords = 0 Then MsgBox ("Het bestand is nog leeg! Voer gegevens in!") Else HuidigeRecord = AantalRecords ToonRecord (HuidigeRecord) End If End Sub
Ø Het programma is klaar!
Test het grondig uit! Test ook de foutafhandeling door de bijvoorbeeld de schrijfbeveiliging van uw diskette in te schakelen.
Visual Basic
door ir. C.Daniels
118
Ø
Oefening: Voeg een nieuwe knop “Lijst” in. Deze toont in een apart formulier een volledige lijst van de ingevoerde data. Tip:Plaats daarvoor een tekstveld in dit formulier, bijna zo groot als het formulier, en schrijf daarin alle records. Zet de eigenschappen van het tekstveld op Multiline en schakel de Scrollbars in.
Ø
Oefening: Voeg een knop “Wijzigen” in, waarmee gegevens van een record kunnen gewijzigd worden.
Enkele screenshots van het programma: Er werd ook reeds een knop “Lijst” bijgevoegd zoals in de oefening. Tevens werd de mogelijkheid voorzien een bestaande record te wijzigen met de knop “Wijzigen”.
Het programma bij het opstarten als het bestand nog leeg is.
Het programma toont record 3.
Visual Basic
door ir. C.Daniels
119
Een nieuwe record bij het invoeren met een verkeerde datum
Het formulier met het overzicht van de data. En zo ziet de data eruit, gezien door het programma Debug. Merk op dat de records niet gescheiden zijn door Cr Lf. Ook tussen de velden van één record is er geen scheidingsteken. De datum wordt opgeslagen als een long getal van 4 bytes op het einde van iedere record. 1A27:0100 1A27:0110 1A27:0120 1A27:0130 1A27:0140 1A27:0150 1A27:0160 1A27:0170 1A27:0180
4A 73 20 4B 6E 20 41 6E 20
61 73 20 61 6B 20 6E 68 20
6E 65 20 72 20 20 6E 6F 20
20 6C 20 65 20 20 65 76 20
56 74 20 6C 20 20 20 65 20
65 20 20 20 20 20 57 6E 20
72 20 20 4F 20 20 69 20 20
73-74 20-20 20-20 76-65 20-20 20-20 6C-6C 20-20 20-20
72 20 20 72 20 20 65 20 20
61 20 20 6D 20 20 6D 20 20
74 20 20 61 20 20 73 20 20
6E 20 6F 74 20 5C 20 20 7F
48 20 00 47 20 00 5A 20 00
61 20 00 65 20 00 6F 20 00
Jan VerstratenHa sselt .o.. Karel OvermaetGe nk .\.. Anne Willems Zo nhoven ....
Datum in long-formaat
De data van één record
Visual Basic
65 20 CE 65 20 86 20 20 01
door ir. C.Daniels
120
I.
LAB 1 - INLEIDING EN KENNISMAKING MET VB .............................................2 A. B. C. D. E. F. G.
WAAROM VISUAL BASIC?............................................................................................2 HOE WERKT WINDOWS? ...............................................................................................2 DE PROGRAMMEEROMGEVING VAN VISUAL BASIC: ONS EERSTE PROGRAMMA...............3 DE EIGENSCHAPPEN VAN EEN OBJECT VERANDEREN......................................................6 REAGEREN OP EEN EVENT ............................................................................................7 EEN POPUP-SCHERM.....................................................................................................9 WAT IS EEN VARIABELE?............................................................................................11 1. Option Explicit......................................................................................................12 2. Datatypes..............................................................................................................13 3. Declareren van variabelen....................................................................................14 H. OEFENINGEN .............................................................................................................14 1)..................................................................................................................................14 2) Oefening 1 ............................................................................................................14
II.
LAB 2 - VOORWAARDELIJKE PROGRAMMA-UITVOERING ...................16
A. A.
IF THEN ELSE – INSTRUCTIE ........................................................................................16 EEN EENVOUDIG SPELLETJE: RAADSPELLETJE.............................................................20 3) De opdracht..........................................................................................................20 4) Een random getal genereren .................................................................................21 5) Randomize ............................................................................................................22 6) Het event Load van een formulier .........................................................................22 7) De Or-operator.....................................................................................................24 B. HET PROGRAMMA RAADSPELLETJE AFWERKEN...........................................................24 8) Elseif ....................................................................................................................26 III.
LAB 3 – CONTAINERS – SELECT - MENU.......................................................27
A.
CONTAINERS .............................................................................................................27 9) Frame en Option Button........................................................................................27 10) Str-functie .........................................................................................................29 B. DE SELECT CASE INTRUCTIE ......................................................................................31 C. EEN MENU .................................................................................................................34 D. EEN NIEUW FORMULIER TOEVOEGEN ..........................................................................37 IV.
LAB 4 – LUSINTSRUCTIES – FOUTAFHANDELING - COMBOBOX ...........39
A.
LUSINSTRUCTIES .......................................................................................................39 11) For…Next .........................................................................................................39 12) While…Wend ....................................................................................................42 13) Do…Loop .........................................................................................................43 B. FOUTAFHANDELING: ON ERROR ................................................................................45 C. DE COMBOBOX .........................................................................................................48 V.
LAB 5 – ARRAYS – LINE .........................................................................................59 A.
WAT ZIJN ARRAYS?....................................................................................................59 14) Een array declareren ........................................................................................59 15) Arrays gebruiken in het programma..................................................................59 16) Sorteren met bubblesort ....................................................................................61 B. DE LINE-INSTRUCTIE .................................................................................................65
Visual Basic
door ir. C.Daniels
121
VI.
LAB 6 - STRINGS EN STRING-FUNCTIES .......................................................75
A. B.
WAT ZIJN STRINGS? ...................................................................................................75 STRING-FUNCTIES VAN VISUAL BASIC ........................................................................75 17) & ......................................................................................................................75 18) Left(string, n) ....................................................................................................75 19) Right(string,n)...................................................................................................76 20) Mid (string, s, n) ...............................................................................................76 21) Asc(karakter) ....................................................................................................76 22) Chr(getal) .........................................................................................................76 23) Str(getal)...........................................................................................................76 24) Val(tekst) ..........................................................................................................77 25) InStr([getal],string1,string2).............................................................................77 26) StrComp(String1,String2)..................................................................................77 27) Format..............................................................................................................77 C. PROCEDURES EN FUNCTIES .........................................................................................78 1) Sub-procedures.....................................................................................................78 2) Functie-procedures ...............................................................................................89 3) Private en Public .................................................................................................91 VII.
LAB 7 - FUNCTIE-PROCEDURES ......................................................................93
A.
NIEUW PROJECT: DE CALCULATOR .................................................................93
B.
BYVAL EN BYREF .....................................................................................................98
VIII.
WERKEN MET BESTANDEN........................................................................ 100
A.
SEQUENTIËLE BESTANDEN ....................................................................................... 100 Een sequentieel bestand schrijven ....................................................................... 101 Een sequentieel bestand lezen ............................................................................. 104 Fouten opvangen ................................................................................................ 105 De Append-optie ................................................................................................. 108 B. RANDOM ACCESS BESTANDEN .................................................................................. 110 8) Een random access bestand beheren ................................................................... 111 4) 5) 6) 7)
Visual Basic
door ir. C.Daniels
122