If you are simply supplying goods to a customer, your till receipt will be the only document you need to give. But if you are supplying goods and services, you will need to issue estimates and numbered invoices.
The traditional way of issuing estimates is a standardised pad, customised with your business address, with a sheet of carbon for your own copies. The same applies to invoices. And by using your word-processor, you can naturally print out multiple copies of a customised letter-head for printed estimates and invoices. That said, it will save time, in the long run, to use BBC BASIC to print out the whole document in one, under your standardised letter-head.
This involves further print formatting, and here we have to distinguish between the screen mode and the printed sheet. The default screen mode of BBC BASIC for the PC is MODE 3, which is eighty characters wide. You may find that the default font of your printer similarly prints 80 characters to a page of A4 when printing out from BBC BASIC. (If not, you will have to consult your printer manual, as the procedures for creating a printer driver lie beyond the scope of this tutor.) A convenient way to verify the function of Mode 3 visibly is to make a ruler, which has ten characters per unit, as a measuring scale for the screen. Enter BBC BASIC and type the command PRINT, followed by nine hyphens and an asterisk, end to end, without spaces. Make sure the whole string of characters is in inverted commas. It should produce the following pattern: ---------* We will call this an inch in our ruler, which, despite metrication, is still commonly used in the jargon of printing. Now repeat the inch seven times, end to end, to produce a total of eight.
Imagine Granny came to stay with you at Christmas. If I were to ask you how long she stayed, you would answer: "For four days / for a week", etc. Note the use of the preposition FOR to measure the number of units (days/weeks) of her stay, because we also use it in BBC BASIC to measure how many times you want a given instruction to be repeated. Let's say you want the computer to print the word "HELLO" a given number of times - we'll call it X - and you give X a value of 10. Now X, as a measure of days, starts off as being 1, and ends up as being 10, through a process of nine successive increments of 1. The way we express this range of increments in BBC BASIC is by means of the statement:
FOR X= 1 TO 10
For those interested in the English grammar of this statement, it is an adverbial phrase of frequency, which governs the verb, in the imperative mood, in the command which we now supply:
When this has been done, we want the computer to go back in a loop and carry out the next execution of the increment. And logically enough, the command for this "next" execution is the word NEXT.
So our complete program, for learning how to produce a loop, reads as follows:
10 FOR X=1 TO 10
20 PRINT "HELLO"
Now RUN the program.
You may feel, after completing this, that it's all very well to produce a vertical list of repetitions of the word "HELLO" - and it's useful to know how to carry out a simple loop - but how does it help us with our "ruler" for formatting a printed document? The answer to this question lies in the use of the semicolon (i.e. ; ). This punctuation mark is an instruction to the computer to print the next item on the same line as the preceding item. So if we want to print "---------*" eight times in succession, on the same line, we write:
10 FOR X = 1 TO 8
20 PRINT "---------*";
Enter BBC BASIC and try it. Then SAVE the program as "RULER". Then try some variations of your own, until you are comfortably familiar with the routine. Once this stage has been reached, you can note that yet more labour can be saved, by taking an even shorter cut, in the form of the keyword STRING$, as follows:
PRINT STRING$(8, "---------*")
But not all loop operations can be reduced to such a simple formula, and the FOR...NEXT loop has to be mastered.
Eight times is not a lot - we have used it just as an illustration. But if, for example, your hobby is building replicas of ocean-going steamships, and you have to link to your computer a mechanical device which drives hundreds of rivets into the plates at set intervals for the length of the hull, then you will see in practice the way the loop is applied in manufacturing industry.
Remember that the screen and the printer are two different devices to which output from the keyboard can be sent. When you RUN the program, the 80 characters will cover the default width of the screen in BBC BASIC. However, printing out may be different, and obviously a Windows word-processor, linked to a post-Windows 95 printer, will work in a more streamlined fashion than printing out from BBC BASIC, and the experience of using the Windows set-up may lead to over-expectation when you first try printing out. The author uses an Epson inkjet, which reproduces the screen width of 80 characters, on a sheet of A4 with about one character's width at each side to spare, as the default. You may find that a pre-Windows dot matrix, for example, is more suitable for getting started than an up-to-date laser printer. At all events, the addition of a fully comprehensive routine for producing a printer driver is beyond the scope of a beginners' tutor in BBC BASIC, and you will have to consult your printer manual.
Assuming that you do have a compatible printer, then to print out, issue the command VDU2 (which means "Visual Display Unit, command 2") followed by RUN. When the sheet has been printed out, turn off the printer by means of the command VDU3. This will then show you how many characters fit laterally onto your sheet of paper. (Z88 users will also have to wait for a subsequent chapter, unfortunately, since the printing routine from BBC BASIC is a little more complex on the Z88 than on the PC.)
So let us now get down to the business of issuing an invoice. Suppose we want to centre the following text to head our stationery:
Tel: 0123 456 789
We have to count the number of characters in each line, and subtract each line total from 80. If you are in BBC BASIC, you simply type PRINT "Fred Chippy", then count the number of characters - in this case 11 - in the first line, subtract it from 80 and divide by 2 to give you the number of leading spaces in the printed line: ie. you type
That returns a figure of 34.5. And because we have not numbered the calculation as a line, it is a one-off and does not get included in the program. You then repeat the process to calculate the leading spaces for all the other lines. But we need to know how we then centre each line of text. For this we need to revise the keyword TAB, thus:
PRINT TAB(10) "Fred Chippy"
will indent "Fred Chippy" by ten spaces. So to centre-justify "Fred Chippy", we type:
PRINTTAB(34.5) "Fred Chippy"
In addition to leaving spaces in the left-hand margin, we need to leave line spaces from the top of the page. This is easily done by inserting a single inverted comma after the command PRINT, as follows:
PRINT ' "Fred Chippy".
You can type as many single inverted commas as you need, after the command PRINT, to insert line spaces. You can also omit the word PRINT in a PRINT...INPUT sequence, and use single inverted commas after INPUT to create the line spaces, thus: INPUT' ' 'name$
The whole program, therefore, to print out the letterhead for any document, will read as follows:
20 PRINT' ' ' '
30 PRINTTAB(34.5) "Fred Chippy"
40 PRINTTAB(25) "Qualified carpenter and joiner"
50 PRINTTAB(33) "22 Pine Street"
60 PRINTTAB(32.5) "Logtown LT1 2TL"
80 PRINTTAB(31.5) "Tel: 0123 456 789"
So now we have our letterhead, which can be prefaced to any kind of regular document. For the moment, we can SAVE it as "LTRHEAD". We can preface it to a written estimate by adding the header "ESTIMATE", or we can preface it to an invoice. Programming for yourself gives you this direct versatility.
Let us assume you want to give a written estimate for replacing a garden fence 20m long. It is in featheredge timber, 1.8m high, discounting the gravel board at the bottom. The featheredge timber is 10cm wide, and you intend an overlap of 2cm, making its effective width 8cm. You intend to erect it in panels, each 2.4m wide, between the timber posts, since (for the purposes of this program) that is the default length of the arris rails, onto which the featheredge is nailed, and the gravel board, on which they stand. At the time of writing, Wickes sell featheredge in 1.8m lengths @ GBP 5.39 per pack of ten (retail). We will put in a post at each end, and every 2.4m, in between the arris rails. These come in packs of 8 @ GBP17.96 per pack. The gravel board at the bottom costs GBP 3.73 per 2.4m length, or GBP 13.29 per pack of 5. Again, at the time of writing, the posts cost GBP 4.29 ea.
Now working out the total cost of all this in a single program is a matter of revising and consolidating the tasks done in shopping lists in Unit 1, and only you, the student, can do that! (There will be a key to the answers in Unit 3.) However, since you clearly don't want to have to spend a week on the calculations every time you issue an estimate, so you will need to standardise the cost of a "panel", as a composite sales unit, by means of a program using the arris rails and gravel board as macro measuring units, together with the number of lengths of featheredge which fit in between. The cost of any of the three items could vary at any time, so you have to devise your program in such a way that when you INPUT the cost of each, you relate them to each other arithmetically and come up with a total which is automatically updated by the INPUT of any one item. Do this now, and when it is completed, come back to the tutor for a short cut.
At the beginning of your program for fence estimates, you can therefore give a REM statement, as follows (note the distinction between string and numeric variables):
REM tim$(1)= tenpack featheredge; tim$(2)=arris rail; tim$(3)=gravelboard; tim$(4)=post; TIM(1)=cost of tim$(1), etc.
The next task is to set up dialogue boxes in which you INPUT the cost of each principal unit under the category of timber, then write a simple arithmetical formula, which works out the timber sub-total as the sum of all the timber units for the length of fencing in question. This can be done using the skills you have acquired already. If you then SAVE the program, it means that at a future date, if the price of one item of timber in the list changes, and you INPUT the new price in the program, leaving the old prices as they are, then the program will automatically update the total for timber for whatever job is in hand. If you have at any stage used a spreadsheet, you will see now how changes to single slots have a knock-on effect on other slots. BASIC is at work behind the backdrop of the spreadsheet that is visible to the audience.
The COLOUR commands in the manual only become effective when they are inserted into a listed program. And once you appreciate that the term "graphics mode" in the manual refers effectively to the style and size of characters on the screen, then the catalogue of colour options given becomes self-explanatory. Let us try an example, using our Fred Chippy letterhead as a working text.
Enter BBC BASIC. To LOAD and RUN the program "CHIPPY", we can use the short cut CHAIN. The syntax is
CHAIN "CHIPPY" (don't forget the inverted commas).
You will see the text of the letterhead. Now we want to look at the program again in full, so we give the instruction to list it - and logically enough, this is LIST. (At this point it can be noted that the abbreviated forms of CHAIN, LIST, and PRINT are, respectively: CH. L. P. Each letter must be followed by a full stop to form a command, although, to avoid confusion, the letters have been listed here without commas).
1 COLOUR 0
2 COLOUR 135
Why 0 and 135? Look down the list under COLOUR in the manual, until you get to the line "In text-only modes (3,6)." For the moment, ignore the business about "physical" and "logical" colours. We have chosen this section because the default screen mode of BBC BASIC 86 is MODE 3, in which we have written our program. Each listed colour has two numbers: the low number selects the colour for the text, and the high number selects it for the background. (The whole list gives you thirty-two options - but don't digress to try out the whole list yet, as there is work to be done! You can come back to the list later and try out a couple of options at a time in between spells of exerting the brain for programming.) In the particular case we are dealing with, COLOUR 0 sets the print to black and COLOUR 135 sets the background to white. RUN the program to try it. If you prefer it that way, issue the command RENUMBER , which will renumber the program lines in tens, then SAVE the program "CHIPPY" again.
Suppose you want to give your software a professional appearance and put a box round your program title - in this case "Invoice"? The key to understanding the graphics codes is to refer the very word graphics with its root word, graph. You will no doubt remember drawing graphs at school. If you missed it for any reason, you will need to revise it in order to handle graphics in BBC BASIC. However, assuming that you are familiar with the x and y co-ordinates in a graph, starting from zero in the bottom left hand corner, you will remember that the X co-ordinate measures the distance from 0 on the left-hand side, and the Y co-ordinate measures the distance from 0 upwards. The same applies to the screen in BBC BASIC graphics.
Let us begin by selecting Mode 8, which has a larger font than Mode 3. We will select our starting point as 200 pixels up from the bottom of the screen and 200 pixels in from the left hand edge, and we instruct the invisible cursor to move to that point by typing MOVE 200,200. In each of the DRAW commands which follow, the first figure measures the distance to cover along the X co-ordinate, and the second that on the Y - which, at 200 in the first command, remains static: DRAW 1000,200.
So the whole program to draw our box, move the print cursor ten lines down from the top and 34 spaces in from the left-hand side, then print the title INVOICE, reads as follows:
20 MODE 8
30 MOVE 200,200
50 DRAW 1000,200
60 DRAW 1000,600
70 DRAW 200,600
90 PRINTTAB(34) "INVOICE"
200 DRAW 200,200
More on graphics next time. The task of producing the final figures for the replacement fencing , by means of a program of your own devising, is your first Assignment for this Unit. Let us assume that it takes you a total of two eight-hour days to complete the job, and you charge GBP 20.00 per hour for labour. The arithmetical procedures of listing the jobs as string variables, and the unit costs as numeric variables, then performing calculations on the algebraic letters representing the numbers, were all covered in Unit 1 and here need consolidating, which is best done by you.
Once these figures have been worked out, we can now turn our attention to producing the written estimate for a job which turns out to have a lot of snags. Let's assume this is your text of the job description:
"To erecting a 20m garden fence in featheredge timber with timber posts and gravel boards, plus initial demolition of existing fence, removal of brambles and tree stumps, and subsequent site clearance:"
You need to CHAIN your program for the ruler, which you then use as a visual guide to length of your lines. This safeguards against inadvertently splitting words. If you allow a left-hand margin of ten characters, you will find that the command "PRINTTAB(10)" will effectively take up a "unit" of your ruler, so that you have an "invisible" unit to play with at the right hand edge, and the line typed into BASIC will scroll over into the next line of the screen, without scrolling over when it is printed out. If all goes well, your "wordprocessing" program should look something like this on screen:
10 PRINTTAB(10) "To erecting a 20m garden fence in featheredge timber with ti
mber" 20 PRINTTAB(10) "posts and gravel boards, plus initial demolition of existing
fence" 30 PRINTTAB(10) "removal of tree brambles and tree stumps, and subsequent sit
When printed out, each line should be comfortably within your sheet of A4, aligned left, with a margin of ten characters. The difference between your written estimate and your invoice at this point is firstly a matter of keeping the template for both, and inserting a header of "Estimate" for one and "Invoice" for the other, and secondly of numbering and filing the invoice for tax purposes.
The production of two copies is easy: you do a short loop, as follows:
a) before the VDU2 command, which prefaces your printout, you type:
FOR COP = 1 TO 2
then just before the VDU3 command at the end of the printout program, you type:
Both the FOR and NEXT lines should naturally be numbered.
But how do we number the invoices incrementally, each time round? For this we need a short program which files the invoice number away, recalls it for the next invoice, increments it by one, and then files the incremented number away again.
We will begin with the increment, for which we need a loop, but first we need a reminder about updating the value of a variable. Enter BBC BASIC and type the following:
20 PRINT A
40 PRINT A
When you RUN the program, you find that line 30 updates the value of A by an increment of 1, and line 40 prints it out. Now let us see what happens if we put this in a loop:
20 FOR J=1 TO 5
40 PRINT N
This increments the value of N, which starts at 0, by one, and prints out its value, every time the program passes through the loop. So this is going to help us increment the invoice number by one every time. But how do we file it away? Filing is actually allocating a physical space on the disk for your data, giving it an identification label, storing the data in it, and then closing the access to that space to keep it separate as one record. We will call the file "NUMBER", and we open it with the command:
Once this has been done, not only is the file open for output, but X is the variable which represents the file in the program. It's like an ambassador, standing for the file, and we do all our negotiating with it. Now assuming we have assigned a value of 1 to N, we store this value in X, as follows:
To clarify what is going on here, let's go back to the point in the last lesson where we looked at the different devices which could be chosen for the output of the PRINT command: the default device is the screen, so if you type PRINT "HELLO" in BASIC, you get HELLO on the screen. As we have also seen, the VDU2 command sends the output to the printer. However, this same PRINT command, followed by the hash sign, followed by the variable chosen to represent the disk file, re-routes the data and "PRINTS" it to the chosen "address" on disk. Once that is done, we must close the file by means of the command CLOSE#X, otherwise chaos ensues.
So the complete program to number our first invoice as 1, and file this number away to disk, is as follows:
Make sure that every detail of punctuation and lettering is copied exactly.
Since the number of the invoice has to be incremented by one every time round, for the second and subsequent invoices we have to retrieve the number from file, so as to be able to increment it. By the same token that X acts as an ambassador for the "external" number on file, we now choose Y to represent the receptionist for guiding the INPUT of external data into the program. The syntax for this runs in two stages: firstly, as with opening the named file to store data, it now has to be opened to retrieve it. So the first command is
Having opened the file for input into the program, and appointed Y as the "receptionist", we have to name the data which we want to be given to Y from file, as follows:
We now close the file, as follows: CLOSE#Y.
Now that Y has done its job, we don't involve it further in the program. If we want to check the value of NR that has been passed in, we type PRINT NR and the computer will return the figure 1. But for the second invoice, and the remaining invoices, we want to increment it by one. So we update it as follows: NR=1+NR , which means "new NR is one plus old NR".
Once this has been done, we summon ambassador X and ask him to file the newly incremented number away on the named file. Having initially numbered the first invoice as 1 and stored it to file, we now transfer the incremented number to the second invoice, store this incremented number to file, and print it out, as follows:
160 CLOSE X
180 PRINTTAB(10)"Invoice number:";NR
The syntax of this operation goes back to the BBC Micro, and was initially used for cassette files, but it has its drawbacks. I am grateful to Richard Russell for pointing out that if ESCape is pressed between the execution of lines 140 and 150, the old Invoice Number will be destroyed and lost. Your program will have effectively crashed. This is because the first thing the keyword OPENOUT does is to delete the old record before writing in the new one. There is an amateur and a professional way to deal with this. The amateur way is to check the hard copy of the last invoice you issued (let's say it was No. 55), to increment this number mentally by one, and then manually to type in the incremented number as a temporary replacement to line 130, as follows:
When you RUN the program it will print out the correct number on the invoice, and store the correct number on file. You do not have to "repair" the program after the manual override: when you then quit BBC BASIC, the override will be lost from RAM, but the correct record filed.
The upgraded program therefore reads as follows:
170 PRINT TAB(10)"Invoice number:";NR
If at this stage veterans of the BBC Micro are able to make more sense of the User Manual than they could as beginners, some errata need to be pointed out which were missed on publication.
If you have or had a Model B+, there is an error on p. 165 of the User Manual in the filing program, which originally appeared (correctly!) on p.192 in the Model B User Manual, as follows:
10 Y= OPENIN "DRINKS"
30 INPUT#Y, A$
40 PRINT A$
50 UNTIL EOF#Y
In the Model B+ User Manual, the hash sign in line 30 was omitted, and so the data retrieval program will not work. (EOF, by the way, means "end of file".) Here also we have another loop - the REPEAT...UNTIL loop. Whereas the FOR...NEXT loop is allocated a specific number of repetitions, the REPEAT...UNTIL loop carries on until a specific condition is met. In this program, the condition to be met is that the date pointer reaches the end of the file.
If you have or had a BBC Master, the Welcome Guide (Issue 2, March 1986) has line 60 missing from the bottom of p. 87 in the "names and telephone numbers" filing program. Line 60, by extrapolation, should read:
60 DIM friends$(100), numb$(100)
It has to be remembered that the User Manuals for these machines were intended both for first-time owners and professional programmers who needed them for reference. This meant that some of the technical jargon in the alphabetically listed keyword definitions was quite beyond the beginner. Despite the misprints and the jargon, however, these manuals provide an additional source of reference, alongside the online Manual of BBC BASIC 86, and the technical terms will be explained as far as possible as we go along.
The elementary filing techniques discussed above are obviously the first steps in creating a database. How far along this road the beginner in business should proceed is a matter of choice. The criterion may well be the size of your clientele: if their details will all fit into one card index box, with room to spare, you need to ask serious questions about whether an expensive database would truly save time, effort and money.
First we have to gather our data, using the INPUT command. Here is the outline of the program:
5 DIM adr$(5)
10 PRINT '' "CARD INDEX"
20 INPUT '' "Enter the surname" ,nam$
40 INPUT '' "Enter the forename",fnam$
60 FOR J=1 TO 5
70 PRINT "Address, line ",J
80 INPUT adr$(J)
Having gathered the data, which will be different for every card, we want to print the details out in a symmetrical two-column card, with capital letters for the headings in the left hand margin and then again in the centre. The only way to illustrate the method for this is to supply a specimen card and work backwards in order to establish the parameters for creating it, as follows:
|STREET(1)||1 Polar Mews||STREET(2)||Glacier Avenue|
Let's assume we are going to work within a text area 80 characters wide. You will have to check this out by experiment with whatever cards you buy. If we allow a left-hand margin of 5 characters, then every line will begin with the command PRINTTAB(5). Taking the first line first, the heading NAME takes up four characters, and therefore, together with the margin of five, leaves a remainder of 31 spaces when subtracted from the left-hand subtotal of 40 out of 80 characters. The command SPC, followed by a numeric variable, will print the number of spaces stated in the variable. Thus PRINT "NAME";SPC(5) "Claus" will print 5 spaces in between NAME and Claus. But we do not have to count the spaces every time: the keyword LEN counts the number of characters in a string, and when prefaced to a string in inverted commas, can be acted on numerically. Thus, since we have a space of ten characters between the left hand margin and the first item of data ("Claus"), the space between the first column and the second will be SPC(10-LEN "NAME"). To take a second example, the space after "TOWN" in the third line will be SPC(10-LEN "TOWN"), which will give six spaces before "Coolville".
The rest of the task must now be handed over to you. You may actually have business clients, or you may be cataloguing your CD collection. What needs to be stressed is that the index-card program can create a reliable manual database. It is worth the time and effort to set it up, if only to take the strategic decision of whether to invest in database software.
Your second assignment is to design an index card incorporating an address, of which the constituent parts are grouped as an array, and in which the spacing is regulated automatically by the use of the SPC and LEN keywords.
In both programs, seek to arrange a genuine dialogue box, so that you ask yourself - or another operator - to INPUT data, then clear the screen before printing out the results of calculations performed on the data. You can experiment with graphics to enhance the dialogue box.