Code op zich helpt natuurlijk niet altijd; het begrijpen er van is uiteraard veel belangrijker. Dus hier komt de uitleg!
1) Tellen doe je vanaf de beginwaarde die je opgeeft. Als je een numerieke variabele declareert, heeft die nog geen waarde. Hij heeft na het declareren dus de waarde 0. Wil je met een andere waarde beginnen, dan doe je dat door de variabele te vullen. Bijvoorbeeld door de startwaarde in een lus in te stellen. Dus als ik een lus maak als: For i = 12 To 20, begint de lus bij i=12. Daarnaast tel ik vaak in een lus op basis van een matrixvariabele, zoals sVelden(j) (ook en vraag van je). Deze variabele wordt gevuld op basis van wisselende gegevens, en je weet dus nooit hoeveel elementen er in zitten, of wat de startwaarde is. Dat herdefiniëren gebeurt hier:
Code:
ReDim Preserve sVelden(j)
sVelden(j) = .Fields(i).Name
j = j + 1
Bij matrixvariabelen heb je twee opties voor de startwaarde: 0 of 1. Dat hangt een beetje van je module declaraties af. Standaard begint een variabele met de waarde 0. Dus als je de eerste waarde toevoegt aan sVelden, dan wordt die dus in sVelden(0) gezet. Wil je met de waarde 1 beginnen, dan zet je bovenin de module de regel
Option Base 1. Dan zit de eerste waarde dus in sVelden(1). Soms is het een beetje onhandig dat de matrix bij 0 begint, zoals in jouw geval omdat jouw tekstvakken en labels met de waarde 1 beginnen. Als ik jouw module zou hebben gemaakt, dan was ik dus met Option Base 1 begonnen, zodat de posities van de variabelen overeenkomen met de namen van de tekstvelden: svelden(1) is dan identiek aan Me("V" & j). Nu moet je dus steeds een waarde optellen of aftrekken om de twee te matchen.
Het herdefiniëren van een matrix variabele doe je met de regel
ReDim Preserve sVelden(j). Dim heb je uiteraard regelmatig gebruikt; met Redim doe je eigenlijk hetzelfde: het opnieuw definiëren van een variabele. Dat hoeft uiteraard nooit bij een enkele variabele; die is namelijk al gedefinieerd. Zou je alleen
ReDim sVelden(j) doen, dan wordt de variabele ook opnieuw ingesteld, maar wordt hij ook helemaal geleegd. Dat is uiteraard niet de bedoeling; je wilt de eerder ingelezen waarden niet verwijderen. Vandaar de toevoeging van het woord
Preserve. Dit zorgt er voor dat de eerdere waarden blijven bestaan.
Code:
For i = LBound(sVelden) To UBound(sVelden)
Met LBound(sVelden) en UBound(sVelden) lees je de laagste en hoogste waarde van een matrix uit. Ongeacht dus of de laagste een 0 of een 1 is. Die wetenschap heb je dus wel nodig in sommige procedures om de gegevens juist uit te lezen. Overigens lees je met
i = .Fields.Count wel het juiste aantal velden uit, met is .Fields(0) dus het eerste veld; wil je de namen van alle velden uitlezen, dan heb je dit weer nodig:
For i = 3 To i - 1
Deze regel leest dus de veldnamen uit vanaf het vierde veld tot het laatste. In de lus gebruik je LBound om vanaf de eerste waarde te starten, en UBound om tot de laatste door te gaan. Die waarden zijn dus afhankelijk van de instelling Option Base 1, of het ontbreken daarvan.
De laatste code die je aanhaalt wordt gebruikt in de eerdere versie waarbij de kolommen die niet gebruikt worden ook niet worden getoond. Daarbij zie je alle gebruikte kolommen netjes naast elkaar. Wat mij persoonlijk dan mooi lijkt, is dat de Totaal kolom daar ook netjes op aansluit. Alleen: die staat helemaal rechts op het rapport. En die kun je natuurlijk niet zomaar op een willekeurige plek neerzetten. Vandaar deze code:
Code:
Me.Totaal.Left = Me("V" & i + 2).Left
Hierbij wordt na het vullen van de kolommen gekeken wat de laatst ingevulde kolom is (waarde i) en wordt van die kolom de horizontale positie op het rapport uitgelezen. De kolom V(i+1) laat ik dan open, en de kolom Totaal kan dan op de positie van V(i+2) worden neergezet. De horizontale positie van een kolom lees je dus uit met
Left.
Laatste vraag: Als je een recordset opent, dan wil je meestal die records uitlezen. Niet altijd; in het voorbeeld lees ik ook de veldnamen uit, en dat hoef je natuurlijk maar één keer te doen. Maar bij het uitlezen van gegevens, open je eerst een recordset en ga je naar het begin van die recordset: het eerste record. Dat doe je met
.MoveFirst. Daarna lees je het eerste record uit, vul je variabelen of formulier/rapport, en dan wil je natuurlijk naar het volgende record, om dat uit te lezen: en daar heb je het commando
.MoveNext voor nodig! En het laatste punt: je wilt de procedure uiteraard stoppen als je alle records hebt gehad. Vandaar dat je het uitlezen van een recordset doet met een eigen lus:
Do While Not .EOF. EOF staat voor: End Of File. Net zo als BOF staat voor: Begin Of File.