BestandenTutorialIndex InleidingEen simpel programma kan je maken en compileren en dan is het klaar om gebruikt te worden. Op een gegeven moment kom je misschien echter tot een punt waar het voor je programma handig zou zijn als je gegevens kon bewaren, zodat je die gegevens de volgende keer bij het opstarten weer kunt gebruiken. Het ideale middel hiervoor zijn bestanden!Deze tutorial zal het werken met bestanden in Visual Basic uitleggen, en de bijbehorende methoden behandelen. Ik heb gemerkt dat bij veel mensen niet (goed) bekend is hoe je gegevens kunt bewaren in bestanden, en hopelijk helpt deze tutorial. Overigens is er nu ook een [TekstBestandenTutorial], die met een paar voorbeelden je meteen op weg helpt als je zonder veel theorie alleen wat tekstbestanden wilt lezen en/of schrijven. Let op: je leert er veel minder van, dus eigenlijk moet je gewoon hier blijven doorlezen, maar het is wel makkelijker. LeeswijzerDe overeenkomst tussen bestanden is dat ze allemaal gegevens bevatten. Tegelijkertijd is het grote verschil de manier waarop die gegevens zijn opgeslagen, vormgegeven. Allereerst zullen de verschillende vormen van toegang worden besproken. Daarna wordt uitgelegd wat je moet doen voordat je kunt lezen of schrijven in een bestand. Dan komt het belangrijkste gedeelte, namelijk twee hoofdstukken over schrijven en het lezen. Uiteindelijk zullen nog een paar extra methoden worden besproken die (kunnen) worden gebruikt bij het werken in bestanden.1. Verschillende soorten manieren van lezen en schrijvenDe overeenkomst tussen bestanden is dat ze allemaal gegevens bevatten. Tegelijkertijd is het grote verschil de manier waarop die gegevens zijn opgeslagen, vormgegeven. Visual Basic heeft grofweg drie verschillende 'vormen' waarop gegevens opgeslagen kunnen worden opgeslagen, en dit vertaalt zich naar een verschil in benadering van een bestand. Deze benaderingen zijna. tekst-gebaseerde toegang, b. 'record'-gebaseerde toegang, en c. 'binaire' toegang. 1.1 Tekst-gebaseerde toegangBij de tekst-gebaseerde toegang, lees en schrijf je in principe kale tekst. Een goed voorbeeld zijn de tekstbestanden (.txt) die Kladblok genereert.Noot: In werkelijkheid is de tekst-gebaseerde toegang een vorm van de record-gebaseerde toegang. 1.2 Record-gebaseerde toegangBij de record-gebaseerde toegang, draait het - zoals de naam al zegt - om records, dat wil zeggen, om een verzameling van bij elkaar horende groepen gegevens. De gegevens van WMS Notes bijvoorbeeld, zouden goed als records opgeslagen kunnen worden. Voor elke notitie worden er namelijk de groep, de titel, de beschrijving en de tekst bijgehouden. Nu kunnen de records op twee verschillende manieren worden opgeslagen, namelijk als tekst of als gecodeerde gegevens (dus niet: versleuteld). De eerste vorm is met het oog goed te lezen, terwijl de tweede vorm niet te lezen is.1.3 Binaire toegangBij de binaire toegang, heb je de 'laagste' vorm van toegang tot een bestand. Dit is handig als je zelf helemaal byte-voor-byte wilt kunnen bepalen hoe de gegevens worden opgeslagen.2. Openen en bestandsnummersVoordat je iets met een bestand kunt doen, moet je hem altijd eerst openen[1]. Als je een nieuw bestand wilt maken, dan kan je gewoon doen alsof het nieuwe bestand al bestaat, en dan wordt het automatisch voor je gemaakt tijdens het openen[2]. Het openen van een bestand kan met de methode Open.Wanneer je klaar bent met het geopende bestand, moet je het weer vrijgeven met de methode Close. [1]: 'Openen' moet hier niet worden verward met de term die Windows gebruikt voor het 'openen van een document'. Openen betekent hier het proces van toegang en rechten verkrijgen voor het lezen en schrijven van en naar een bestand. [2]: Dit geldt alleen als de modus bij het openen Append, Binary, Output of Random is. 2.1 OpenenSyntax
Argumenten
Als Open is uitgevoerd, dan is het bestand geopend en dan kan er gelezen en geschreven worden (afhankelijk van wat er op is gegeven bij Open). 2.2 BestandsnummersIn Visual Basic worden alle geopende bestanden van elkaar onderscheid door middel van een bestandsnummer. Het is mogelijk om dit nummer in te programmeren, maar als het aantal geopende bestanden variëert, dan is het handig om hiervoor de methode FreeFile te gebruiken. Deze methode retouneert het eerste vrije bestandsnummer. Een bestandsnummer is minimaal 1 en maximaal 511 en het moet in de programmacode altijd voorafgegaan worden door een hekje[1].Geldige bestandsnummers zijn dus bijvoorbeeld #1, #15, #123, maar niet #1000. [1]: Er zijn een aantal methoden die geen hekje voor het bestandsnummer willen hebben staan. In de syntax van de functies zal altijd duidelijk te zien zijn of een hekje optioneel is of verplicht aanwezig of verplicht afwezig moet zijn. 2.3 VoorbeeldDit is een voorbeeld dat laat zien hoe je Open, Close en FreeFile gebruikt. Access en Lock worden vaak niet gebruikt.Code
Dim Bestandsnummer As Integer 'Bepaal het eerstvolgende ongebruikte bestandsnummer Bestandsnummer = FreeFile() Open "MijnGegevens.dat" For Output As #Bestandsnummer 'Schrijf hier gegevens naar het bestand... Close #Bestandsnummer 3. Tekst-gebaseerde toegangBij de tekst-gebaseerde toegang, lees en schrijf je in principe kale tekst. Een goed voorbeeld zijn de tekstbestanden (.txt) die Kladblok genereert.Dit is een voorbeeld van de inhoud van een regel uit een bestand:
Dit is een tekstbestand. Hierin sla ik al mijn notities op.
Hallo! 06-02-2002 21:17:43 12435235 Noot: In werkelijkheid is de tekst-gebaseerde toegang een vorm van de record-gebaseerde toegang. 3.1 OpenenDe modus die bij Open gebruikt moet worden voor de tekst-gebaseerde toegang is afhankelijk van het feit of je wilt lezen of schrijven in het bestand. Wil je lezen dan gebruik je Input, en wil je schrijven dan gebruik je Output.3.2 SchrijvenGegevens die worden gelezen met Line Input zijn normaal meestal geschreven met de methode Print (niet te verwarren met de methode Print van Form, die gebruikt kan om tekst op onder andere Forms te plaatsen).Syntax
Argumenten
Als je geen gegevens meegeeft om te schrijven, dan zal Print een lege regel schrijven. Zo schrijf je gegevens met behulp van Print:
Open "MijnGegevens.dat" For Output As #1 Print #1, "Hallo!" Print #1, Print #1, "Dit is een voorbeeld van tekst die is geschreven met Print." Close #1 De volgende code geeft overigens hetzelfde resultaat:
Open "MijnGegevens.dat" For Output As #1 Print #1, "Hallo!" & vbCrLf & vbCrLf & "Dit is een voorbeeld van tekst die is geschreven met Print." Close #1 3.3 LezenDe meeste gebruikte manier om te lezen bij de tekst-gebaseerde toegang is regel-voor-regel met behulp van Line Input. Regels moeten worden gescheiden door de constante vbCrLf[1] of vbCr. Let er wel op dat het scheidingsteken(s) zich niet in de geretourneerde gegevens bevindt. Als je de tekst weer wilt samenvoegen moet je er dus ook telkens vbCrLf tussenplaatsen.Syntax
Argumenten
De variabele die je meegeeft zal nadat Line Input klaar is de ingelezen waarde bevatten. Meestal zal je meer willen dan één regel inlezen en zal je het hele (tekst)bestand willen inlezen. Dit is een voorbeeld van hoe dat vaak gebeurt: Code
Dim Regel As String Dim Tekst As String Open "MijnBestand.txt" For Input As #1 Do Until EOF(1) 'Lees een nieuwe regel in. Line Input #1, Regel 'Voeg de regel toe aan de tekst. If Not (Tekst = "") Then Tekst = Tekst & vbCrLf Tekst = Tekst & Regel Loop Close #1 [1]: vbCrLf is een constante, die gelijk is aan de constantes vbCr & vbLf (= Chr(13) & Chr(10)). Dus Len(vbCrLf) = 2. In Windows wordt vbCrLf automatisch ingevoegd als je op Enter drukt. 4. Record-gebaseerde toegangBij de record-gebaseerde toegang, draait het - zoals de naam al zegt - om records, dat wil zeggen, om een verzameling van bij elkaar horende groepen gegevens. De gegevens van WMS Notes bijvoorbeeld, zouden goed als records opgeslagen kunnen worden. Voor elke notitie worden er namelijk de groep, de titel, de beschrijving en de tekst bijgehouden.4.1 VormenEr zijn twee verschillende vormen waarin de records kunnen worden opgeslagen.
4.2 OpenenDe modus die bij Open gebruikt moet worden voor de variabele vorm van de record-gebaseerde toegang is gelijk aan die van de tekst-gebaseerde toegang, dus Input voor het lezen en Output voor het schrijven van gegevens. Voor de vaste vorm vorm van de record-gebaseerde toegang is de modus altijd Random. Bij deze vorm is de parameter [Len=recordlengte] van Open ook van toepassing. De recordlengte bepaalt hoe ver alle beginpunten van de velden van elkaar af liggen.4.3 SchrijvenEerst zal het schrijven in de variabele vorm van de record-gebaseerde toegang worden behandeld, en daarna zal het schrijven in de vaste vorm van de record-gebaseerde toegang worden behandeld.4.3.1 Variabele vormSchrijven gebeurt in de variabele vorm van de record-gebaseerde toegang met behulp van Write.Syntax
Argumenten
Zo schrijf je gegevens met behulp van Write: Code
Dim strTekst1 As String Dim strTekst2 As String Dim lngGetal As Long Dim dteDatum As Date 'Initialiseer de waarden. strTekst1 = "Hallo! Leuk dat je dit leest!" strTekst2 = "Nog wat tekst..." lngGetal = 123456 dteDatum = Date 'Schrijf de waarden. Open "MijnGegevens.dat" For Output As #1 Write #1, strTekst1, strTekst2, lngGetal, dteDatum Close #1 De inhoud van MijnGegevens.dat zal er dan als volgt uitzien:
"Hallo! Leuk dat je dit leest!","Nog wat tekst...",123456,#2002-02-21#
Omdat dubbele aanhalingstekens niet uit Strings worden gefilterd, geeft de volgende code hetzelfde resultaat: Code
Dim lngGetal As Long Dim dteDatum As Date 'Initialiseer de waarden. lngGetal = 123456 dteDatum = Date 'Schrijf de waarden. Open "MijnGegevens.dat" For Output As #1 Write #1, "Hallo! Leuk dat je dit leest!"",""Nog wat tekst...", lngGetal, dteDatum Close #1 Dit kan dus gauw een bron van problemen zijn, en het wordt afgeraden om de bovenstaande 'truc' te gebruiken als normale manier gegevens op te slaan! 4.3.2 Vaste vormSchrijven gebeurt in de variabele vorm van de record-gebaseerde toegang met behulp van Put. Put wordt ook gebruikt bij de binaire toegang.Syntax
Argumenten
Zo schrijf je gegevens met behulp van Put: Code
Dim strTekst1 As String Dim strTekst2 As String Dim lngGetal As Long Dim dteDatum As Date 'Initialiseer de waarden. strTekst1 = "Hallo! Leuk dat je dit leest!" strTekst2 = "Nog wat tekst..." lngGetal = 123456 dteDatum = Date 'Schrijf de waarden. Open "MijnGegevens.dat" For Random As #1 Len = 40 Put #1, , strTekst1 Put #1, , strTekst2 Put #1, , lngGetal Put #1, , dteDatum Close #1 De inhoud van MijnGegevens.dat zal er dan als volgt uitzien (dit is één regel):
. Hallo! Leuk dat je dit leest! . Nog wat tekst... @â. 9â@
Let er nu op dat de beginpunten van de gegevens op 40 tekens afstand van elkaar staan, door Len = 40 mee te geven aan Open. (Het kan zijn dat het resultaat niet helemaal goed overkomt, maar waar nu een "." voor de tekst staat, zag je eerst het bekende 'lege vierkantje' (= niet geïmplementeerd teken).) 4.4 LezenEerst zal het lezen in de variabele vorm van de record-gebaseerde toegang worden behandeld, en daarna zal het lezen in de vaste vorm van de record-gebaseerde toegang worden behandeld.4.4.1 Variabele vormLezen gebeurt in de variabele vorm van de record-gebaseerde toegang met behulp van Input (let op het verschil met Line Input).Syntax
Argumenten
De variabele(n) die je meegeeft zal/zullen nadat Input klaar is de ingelezen waarde(n) bevatten. Zo lees je gegevens met behulp van Input, die in het bovenstaande voorbeeld met Write zijn geschreven: Code
Dim strTekst1 As String Dim strTekst2 As String Dim lngGetal As Long Dim dteDatum As Date 'Lees de waarden. Open "MijnGegevens.dat" For Input As #1 Input #1, strTekst1, strTekst2, lngGetal, dteDatum Close #1 De variabelen zullen nu de gegevens bevatten die uit het bestand zijn gelezen. Het is hier belangrijk dat de variabelen die je leest van hetzelfde type zijn als de gegevens die je met Write hebt geschreven. 4.4.2 Vaste vormLezen gebeurt in de variabele vorm van de record-gebaseerde toegang met behulp van Get. Get wordt ook gebruikt bij de binaire toegang.Syntax
Argumenten
De variabele die je meegeeft zal nadat Get klaar is de ingelezen waarde bevatten. Zo lees je gegevens met behulp van Get, die in het bovenstaande voorbeeld met Put zijn geschreven: Code
Dim strTekst1 As String Dim strTekst2 As String Dim lngGetal As Long Dim dteDatum As Date 'Lees de waarden. Open "MijnGegevens.dat" For Random As #1 Len = 40 Get #1, , strTekst1 Get #1, , strTekst2 Get #1, , lngGetal Get #1, , dteDatum Close #1 De variabelen zullen nu de gegevens bevatten die uit het bestand zijn gelezen. Let er op dat de recordlengte bij het lezen gelijk is aan de recordlengte die is gebruikt bij het schrijven! 5. Binaire toegangBij de binaire toegang, heb je de 'laagste' vorm van toegang tot een bestand. Dit is handig als je zelf helemaal byte-voor-byte wilt kunnen bepalen hoe de gegevens worden opgeslagen.5.1 OpenenDe modus die bij Open gebruikt moet worden voor de binaire toegang is altijd Binary.Als je bij de binaire toegang een bestaand bestand opent, dan moet je erop letten dat de bestaande informatie niet automatisch wordt verwijderd. Je kan dus middenin het bestand iets wijzigen, terwijl de rest van het bestand onveranderd blijft. 5.2 SchrijvenSchrijven gebeurt bij de binaire toegang met behulp van Put, net zoals bij de vaste vorm van de record-gebaseerde toegang. De syntax is bijna hetzelfde, dus het is niet nodig de syntax hier te herhalen. Het enige verschil is dat de positie waar er geschreven moet worden nu niet meer een record-nummer is, maar een positie (in bytes).Zo schrijf je gegevens met behulp van Put: Code
Dim strTekst As String Dim lngGetal As Long 'Initialiseer de waarden. strTekst = "Hallo!! Deze tekst is precies 45 tekens lang." lngGetal = 123456 'Schrijf de waarden. Open "MijnGegevens.dat" For Binary As #1 Put #1, , strTekst Put #1, , lngGetal Close #1 De inhoud van MijnGegevens.dat zal er dan als volgt uitzien:
Hallo!! Deze tekst is precies 45 tekens lang.@â.
5.3 LezenLezen gebeurt bij de binaire toegang met behulp van Get, net zoals bij de vaste vorm van de record-gebaseerde toegang. De syntax is bijna hetzelfde, dus het is niet nodig de syntax hier te herhalen. Het enige verschil is dat de positie waar er gelezen moet worden nu niet meer een record-nummer is, maar een positie (in bytes).Het voorbeeld dat wordt gegeven om bij de vaste vorm van de record-gebaseerde toegang te schrijven werkt goed, alleen bij het inlezen van de Strings kan er een probleem ontstaan. Omdat Put in de binaire toegang namelijk alleen de gegevens wegschrijft, weet je niet hoe lang een String is. Om toch Strings in te kunnen lezen moet je vooraf al weten hoe lang de tekst was. Het is geen probleem als de Strings altijd een vaste lengte zijn, maar als Strings vooraf geen bepaalde lengte hebben, dan kan je voor de String de lengte in het bestand plaatsen met behulp van de methode Len. Zo lees je gegevens met behulp van Get, die in het bovenstaande voorbeeld met Put zijn geschreven en er vanuit gaande dat je weet hoe lang de geschreven tekst was: Code
Dim strTekst As String Dim lngGetal As Long 'Initialiseer strTekst, want we weten dat de tekst 45 tekens lang is. 'Het maakt niet uit wat er in strTekst komt te staan, als hij maar groot genoeg is. strTekst = Space(45) 'Lees de waarden. Open "MijnGegevens.dat" For Binary As #1 Get #1, , strTekst Get #1, , lngGetal Close #1 De variabelen zullen nu de gegevens bevatten die uit het bestand zijn gelezen. Als je met behulp van Len eerst de lengte ervoor wilt plaatsen, dan kan je zo schrijven: Code
Dim lngLengte As Long Dim strTekst As String 'Initialiseer de waarden. strTekst = "Hallo!! Deze tekst is een bepaald aantal tekens lang." lngLengte = Len(strTekst) lngGetal = 123456 'Schrijf de waarden. Open "MijnGegevens.dat" For Binary As #1 Put #1, , lngLengte Put #1, , strTekst Close #1 En vervolgens zo lezen: Dim lngLengte As Long Dim strTekst As String 'Lees de waarden. Open "MijnGegevens.dat" For Binary As #1 'Bepaal de lengte van de volgende tekst. Get #1, , lngLengte 'Initialiseer strTekst. strTekst = Space(lngLengte) 'Lees de tekst. Get #1, , strTekst Close #1 De variabele lngLengte zal nu de lengte van strTekst bevatten. 6. Overige methodenNu alle lees- en schrijfmethoden besproken zijn die gebruikt worden bij de verschillende manieren om gegevens uit een bestand te lezen, zullen een aantal andere methoden worden besproken die gebruikt (kunnen) worden bij het lezen en schrijven in bestanden.6.1 Close en ResetVoor zover dat nog niet duidelijk was uit deze tutorial: een geopend bestand moet je altijd weer sluiten! Door een bestand weer te sluiten, geef je bronnen van je systeem vrij waardoor andere programma's die weer kunnen gebruiken. Als je bestanden niet sluit, dan bestaat de kans dat je systeem langzamer wordt.Meestal gebruik je Close om één bestand te sluiten, maar het is mogelijk om meer dan één bestand tegelijkertijd te sluiten. Als je zelfs niet aangeeft welk bestand je wilt sluiten, dan sluit Close alle bestanden en dit is gelijk ook de werking van de methode Reset. Syntax
Argumenten
6.2 FileLen en LOFDe methoden FileLen en LOF lijken heel erg op elkaar, omdat ze beide de grootte (lengte) van een bepaald bestand meten, in bytes. Het verschil tussen de twee functies is dat LOF gebruikt kan worden om de grootte te bepalen van een geopend bestand, en dat FileLen gebruikt kan worden om de grootte van een bestand te bepalen dat niet is geopend. Als je FileLen aanroept met de bestandsnaam van een bestand dat geopend is, dan zal de grootte worden gegeven die het bestand had vlak voor het openen ervan.Syntax
Argumenten
Zo bepaal je de grootte van een bestand met behulp van FileLen en LOF: Code
Dim Grootte As String 'FileLen Grootte = FileLen("MijnGegevens.dat") 'LOF Open "MijnGegevens.dat" For Binary As #1 'Lees of schrijf hier gegevens van of naar het bestand... 'LOF Grootte = LOF(1) Close #1 6.3 EOFDe methode EOF geeft aan of je het eind van een (geopend) bestand hebt bereikt als je aan het lezen bent. Deze functie is nodig, omdat Visual Basic een fout zal genereren wanneer je probeert gegevens te lezen terwijl het einde van het bestand is bereikt.Syntax
EOF bestandsnummer Argumenten
EOF zal een Boolean retourneren die aangeeft of het einde van het bestand is bereikt. Het leesvoorbeeld bij de tekst-gebaseerde toegang laat zien hoe je EOF kunt gebruiken. 6.4 Seek (de functie)Seek is er in twee vormen, namelijk als functie en als statement. Eerst zal de functie worden besproken.De functie Seek geeft aan wat in een (geopend) bestand op dat moment de lees/schrijfpositie is. Als de modus bij Open Random was, dan zal Seek een record-nummer geven, maar was de modus Binary, Output of Input, dan zal Seek een positie in bytes geven. De eerste byte is 1, de tweede 2, enzovoort. Syntax
Seek bestandsnummer Argumenten
6.5 Seek (het statement)Seek is er in twee vormen, namelijk als functie en als statement. Nu zal het statement worden besproken.Het statement Seek stelt de lees/schrijfpositie in van een (geopend) bestand. Hiermee kan je precies bepalen waar er in het bestand gelezen of geschreven moet gaan worden. Syntax
Argumenten
7 TenslotteVolgens mij heb ik nu zo'n beetje alle methoden besproken die met het lezen en schrijven in bestanden te maken hebben. Ik hoop dat met deze tutorial veel vragen worden opgelost en dat mensen hier echt iets aan hebben.Gerefereerd door:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||