home *** CD-ROM | disk | FTP | other *** search
- RECORDS - BRIEF INTRODUCTION
- by David Stidolph
-
- [Taken from COMAL TODAY #25 with permision]
-
- AmigaCOMAL not only implements Common COMAL, but
- extends it with many new features. This article
- focuses on one of those new features: RECORDS. A
- record is a set of data elements tied together
- under the same name. An example of this is a simple
- data base to keep track of a persons name, address
- and telephone number. In any other COMAL you might
- use the following variables:
-
- DIM last'name$ OF 20
- DIM first'name$ OF 15
- DIM inital$ OF 1
- DIM address$ OF 25
- DIM city$ OF 20
- DIM state$ OF 2
- DIM zip$ OF 5
- DIM phone'num$ OF 15
-
- This would work, but to pass a persons information
- to a procedure would require eight parameters -- a
- lot of typing at the very least. In AmigaCOMAL you
- could group all these variables into one record.
- For example:
-
- RECORD type'person@
- FIELD last'name$ OF 20
- FIELD first'name$ OF 15
- FIELD inital$ OF 1
- FIELD address$ OF 25
- FIELD city$ OF 20
- FIELD state$ OF 2
- FIELD zip$ OF 5
- FIELD phone'num$ OF 15
- ENDRECORD type'person@
-
- This may be a bit more typing initially, but let's
- suppose you need a procedure to enter information
- about a new person, but want to pass the variables
- as parameters because you want several different
- persons data in memory at once (the old person, the
- new person and matching data for comparisons).
- Under most COMAL's you would have a procedure
- declaration like this:
-
- PROC input'data(REF ln$,REF fn$,REF in$,REF
- ad$,REF ci$,REF st$,REF zip$,REF ph$) //wrap line
-
- Besides shortening the names so they would fit on
- a line, you would have to keep constant track of
- not only the names of the variables, but THE ORDER
- TO PASS THEM to the procedure. If you need several
- different versions of the same data, the names
- would start to get very long (like OLD'LAST'NAME$).
-
- With AmigaCOMAL you can group all the different
- variables (called FIELDS) into a RECORD structure
- and pass it to the procedure like this:
-
- PROC input'data(REF person@)
-
- Notice that you don't have to remember the order of
- parameters. To refer to any one of the variables
- kept in PERSON@ you use the following method:
-
- person@.last'name$
-
- PERSON@. as a prefix to the variable informs COMAL
- that this is a record variable, and specifys the
- specific record (PERSON@). After that comes the
- actual variable you want to access. In order to use
- PERSON@ you must first define it (like
- DIMmensioning a string):
-
- DIM person@ OF type'person@
-
- This tells COMAL that you want a variable record
- named PERSON@ and to look at the definition
- TYPE'PERSON@ for the different type of variables
- and their names. Another advantage is that you
- could create several different records based on
- TYPE'PERSON@ and make your program both shorter and
- more readable:
-
- DIM person@ OF type'person@
- DIM old'person@ OF type'person@
- DIM new'person@ OF type'person@
-
- All of these records have the same named variables
- within them, but each of those variables could hold
- a different value (PERSON@.LAST'NAME$ is different
- from OLD'PERSON@.LAST'NAME$).
-
- Besides making parameter passing easier, records
- can be assigned the values of other records if they
- are of the same type. For example, you may wish to
- make a new person the current one, but first change
- the current one to be the old'person:
-
- old'person@ := person@
- person@ := new'person@
-
- Records can really help your programming, and on
- the Amiga they are absolutely necessary.
-
- // by David Stidolph for AmigaCOMAL only
- RECORD type'person@
- FIELD valid!
- FIELD last'name$ OF 25
- FIELD first'name$ OF 10
- FIELD inital$ OF 1
- FIELD sex$ OF 6
- FIELD married
- FIELD num'of'children
- FIELD phone$ OF 15
- ENDRECORD type'person@
-
- DIM person@ OF type'person@
- DIM choice$ OF 1, match$ OF 80
- init'program
- REPEAT
- menu(choice$)
- do'menu(choice$)
- UNTIL choice$ IN "4qQ"
- quit
-
- PROC init'program
- max'records:=20
- TRAP
- OPEN FILE 1,"demo.rnd",RANDOM
- varsize(type'person@) //wrapline
- HANDLER
- CREATE "demo.rnd",max'records,
- varsize(type'person@) //wrapline
- OPEN FILE 1,"demo.rnd",RANDOM
- varsize(type'person@)//wrapline
- // Amiga COMAL automatically initializes
- // variables to null values, so we don't
- // have to.
- FOR record'num:=1 TO max'records DO
- WRITE FILE 1,record'num: person@
- ENDFOR record'num
- ENDTRAP
- ENDPROC init'program
-
- PROC menu(REF choice$) CLOSED
- DIM keystroke$ OF 1
- page
- PRINT "Main Menu"
- PRINT
- PRINT "1) Add person"
- PRINT "2) Delete person"
- PRINT "3) Find person"
- PRINT "4) Quit program"
- PRINT
- REPEAT
- PRINT "Your choice:";
- choice$:=inkey$
- UNTIL choice$ IN "1234adfqADFQ"
- PRINT
- PRINT
- ENDPROC menu
-
- PROC do'menu(choice$)
- CASE choice$ OF
- WHEN "1","a","A"
- input'person(person@)
- record'num:=next'free
- IF record'num=0 THEN
- PRINT "No more records available!"
- press'return
- ELSE
- person@.valid!:=true
- WRITE FILE 1,record'num: person@
- ENDIF
- WHEN "2","d","D"
- FOR record'num:=1 TO max'records DO
- READ FILE 1,record'num: person@
- IF person@.valid! THEN
- display'person(person@)
- IF wants'deleted THEN
- person@.valid!:=false
- WRITE FILE 1,record'num: person@
- ENDIF
- ENDIF
- ENDFOR record'num
- WHEN "3","f","F"
- INPUT "Enter characters to match: ": match$
- FOR record'num:=1 TO max'records DO
- READ FILE 1,record'num: person@
- IF person@.valid! THEN
- IF match$="*" OR match$ IN
- combine$(person@) THEN//wrap line
- display'person(person@)
- press'return
- ENDIF
- ENDIF
- ENDFOR record'num
- OTHERWISE
- NULL // ignored
- ENDCASE
- ENDPROC do'menu
-
- PROC quit
- CLOSE FILE 2
- page
- END "Done."
- ENDPROC quit
-
- PROC display'person(person@)
- page
- PRINT "Name: ";person@.last'name$,",";
- PRINT person@.first'name$;person@.inital$
- PRINT "Sex: ";person@.sex$,",";
- IF person@.married THEN
- PRINT "is married";
- ELSE
- PRINT "is not married";
- ENDIF
- PRINT "and has";
- PRINT person@.num'of'children;"children."
- PRINT "Can be reached at:";person@.phone$
- PRINT
- ENDPROC display'person
-
- FUNC combine$(person@) CLOSED
- RETURN person@.last'name$+person@.first'name$
- ENDFUNC combine$
-
- PROC input'person(REF person@)
- INPUT "Last name: ": person@.last'name$
- INPUT "First name: ": person@.first'name$
- INPUT "Middle inital: ": person@.inital$
- INPUT "Sex: ": person@.sex$
- REPEAT
- INPUT "Married (y/n): ": confirm$
- UNTIL confirm$ IN "yYnN"
- person@.married:=(confirm$ IN "yY")>0
- INPUT "Num of children: ":
- person@.num'of'children //wrapline
- INPUT "Phone number: ": person@.phone$
- ENDPROC input'person
-
- PROC press'return CLOSED
- PRINT
- PRINT "Press RETURN to continue"
- WHILE key$<>chr$(13) DO NULL
- ENDPROC press'return
-
- FUNC next'free CLOSED
- IMPORT type'person@,max'records
- DIM person@ OF type'person@
- FOR rec'num:=1 TO max'records DO
- READ FILE 1,rec'num: person@
- IF NOT person@.valid! THEN RETURN rec'num
- ENDFOR rec'num
- RETURN 0
- ENDFUNC next'free
-
- FUNC wants'deleted CLOSED
- DIM keystroke$ OF 1
- PRINT
- PRINT "Do you want to delete this entry? ";
- REPEAT
- keystroke$:=inkey$
- IF NOT keystroke$ IN "yYnN" THEN
- PRINT chr$(7),chr$(25),
- ENDIF
- UNTIL keystroke$ IN "yYnN"
- RETURN keystroke$ IN "yY"
- ENDFUNC wants'deleted
-
-