Home Programma's Analoge klok Muiscursor Acceptgiros Deskjet Fractals BASELECT RASelect Searcher Telefoon

Omhoog

Email me

700 Acceptgiro's bedrukken in PowerBASIC for DOS 3.2

Ook verschenen in de Nieuwsbrief van de HCC Basic Gebruikersgroep (HCC BasicGG)november 2000

Op een zondagmiddag moesten er nog even zevenhonderd acceptgiro's voor een plaatselijke vereniging worden afgedrukt. In eerste instantie pakte ik MS Access, maar stuitte na enige tijd toch op wat problemen die ik niet zelf in Access kon oplossen:

Op een acceptgiro moet er enige ruimte zijn tussen de gulden en centen om op juiste wijze de vakken te vullen
In het databestand zoals door mij gebruikt stonden soms geen bedragen ingevuld, maar een stel stippen
Access bleef na elke bladzijde printen een extra bladzijde doorvoeren, hetgeen erg lastig is

Aangezien mijn kennis van Access, zelfs na twee dagen cursus, niet voldoende was om daarin het probleem op te lossen, heb ik besloten even een stukje programma te maken om dit op te lossen. Aangezien er misschien voor een beginnend Basic programmeur een paar aardige stukjes code in voorkomen, stuur ik het maar in ter lering ende vermaack. Het is zeker geen schoolvoorbeeld van programmeerkunst, maar het 'does the job'. Dit is ook één van de redenen waarom er weinig tot geen foutafhandeling is gedaan: de situatie is een bekende situatie voor eens per jaar te gebruiken.

Er werd mij aangeleverd een dBase III export file met komma's als seperator, vermomd als ASCII bestand (vanwege de extensie), maar in werkelijkheid was het een WordPerfect 5.1 bestand. Eerst is dit bestand geconverteerd naar een echt ASCII bestand. Het bestand bevatte zo'n 700 regels met als inhoud:

voorletters,achternaam,straat met huisnummer,plaats,contributiebedrag

Uiteindelijk moest dit per plaats, en per plaats op straat en huisnummer worden gesorteerd. Hiervoor heb ik de ARRAY SORT functie van PowerBASIC (vanaf PB2.1): met één commando een complete array gesorteerd. Bovendien kan met de optie TAGARRAY een tweede array worden gekoppeld, zodat de relatie tussen de twee arrays blijft behouden. Maar nu hebben we een aantal arrays die bijeen horen: VOORL$(), NAAM$(), STRAAT$() en PLAATS$(). Hoe nu te handelen?

INDEXEREN IN PLAATS VAN SORTEREN!

In het verleden heb ik al eens een oplossing gevonden en wel een hele snelle: in plaats van alle arrays mee te sorteren copieer ik de sleutelarray (waarop moet worden gesorteerd) naar een tijdelijke stringarray TEMP$(), in dit geval de combinatie van PLAATS en STRAAT (scheelt een keer sorteren). Bovendien wordt een tweede array gevuld met de (nu nog oplopende) record nummers NUMMER(). Door nu de TEMP$() array te sorteren en NUMMER() als TAGARRAY mee te laten lopen, hebben we na sorteren in NUMMER() een index met de juiste volgorde staan. TEMP$() gebruiken we hierna niet meer, maar NUMMER() gebruiken we bij de volgende handeling (in volgorde printen) als index, in plaats van alleen de FOR variabele R:

for r=1 to aantal

    ............

    'print de NAW gegevens, middels een index lijst voor de juiste volgorde

    print #9,lm$+voorl$(nummer(r))+ space$(tab5)+naam$(nummer(r))

    print #9,lm$+straat$(nummer(r))

    print #9,lm$+plaats$(nummer(r))

        ........

next r

Als eerste record wordt nu het als eerste gesorteerde record genomen, door de nieuwe array NUMMER(R). Deze werkwijze scheelt veel programeerwerk (geen eigen sorteerroutine ontwerpen), tijd (testen) en snelheid. Dit omdat er minimaal met data wordt geschoven (om alle arrays mee te wijzigen). Bovendien kunnen er op deze wijze eenvoudig meerdere indexsleutels worden gemaakt voor bijvoorbeeld ADRES, NAAM of PLAATS.

EERST TESTEN (FORMULIEREN ZIJN SCHAARS)

In het begin moet er naast het bestaande invoerbestand een tijdelijk bestand worden gemaakt om de uitvoer resultaten te controleren tijdens het testen. Via de constructie van TEST wordt de uitvoer naar hetzij een bestand gevoerd of naar de printer. Dit is het grote voordeel van werken met PRINT #9,  : men behandelt de printerpoort eenvoudig als bestand en kan eenvoudig omschakelen: de aansturing van beide is gelijk.
Om een tijdelijk databestand af te leiden van het invoerbestand, zodat de namen en paden overeenkomen is al eens eerder door mij beschreven. De volgende routine regelt dit voor je:

'dit stukje is door mij vorig jaar al eens beschreven in de nieuwsbrief

while right$(a$,1)<>"." and len(a$)>1

a$=left$(a$,len(a$)-1)

wend

Strip de volledige bestandsnaam in A$ van alles na de laatste punt, door zolang de punt niet aan het eind staat A$ een character in te korten. In juni 1998 al eens beschreven om de naam van het uitgevoerde bestand (verkregen middels ExeName$) te strippen. In dit geval gaat het meestal goed, zolang het bestand in A$ een punt en extensie heeft. Evnetueel kan hiervoor verder nog worden beveiligd (maar voor mijn toepassing niet nodig). De gestripte combinatie pad+naam wordt in een later statement voorzien van de extensie TMP.

ELKE DERDE KEER IETS BIJZONDERS

Dan nog een andere constructie waar een paar medeprogrammeurs zich wel eens over verbaasden en wel het statement:

if r/3=int(r/3) then ......

Als je dit in een FOR NEXT loop gebruikt, waarbij R de loopvariabele is, kun je op deze wijze na elke derde keer iets extras laten doen. Alleen als R een drievoud is, wordt de routine uitgevoerd. Indien R een integer is, kan men beter gebruik maken van:

if r mod 3=0 then ......

Want als R een real getal is, kan soms door afrondingsfouten r wellicht eens 2,9999999999978 worden in plaats van exact 3, en dan gaat het kunstje niet meer op.

EXTRA RUIMTE TUSSEN GULDENS EN CENTEN

Nog een relatief weinig gebruikt, maar o zo handig statement is:

replace "." with space$(tab2) in a$

Hiermee wordt in één statement alle punten in A$ vervangen door een andere tekenreeks, in dit geval een rij spaties. Heel handig als ZOEK en VERVANG functie bij een eigen tekstverwerker, vervangen van TABs door spaties in code, of in dit geval creëren van ruimte tussen het gulden en het centen vak op de giro.

Nogmaals: zeker geen hoogstaand programa dat bol staat met truuks, maar misschien voor anderen handig, zeker als ze ook eens acceptgiro's moeten bedrukken. De sourcefile is te vinden op acceptgiro als Basic bestand (6k), of als HTML bladzijde of voor degenen zonder PowerBASIC compiler als executable hiero.

Het programma is geschreven in PowerBASIC 3.2 for DOS. Met kleine aanpassingen ook wel te draaien in PB/CC 2.0.

Succes,

Henk Broekhuizen

Bezoek het PB forum in het Nederlands en/of teken mijn gastenboek.

Datum laatste aanpassing:
29 december 2003 03:41:46

Email mij voor reacties,
aanvullingen en correcties