An array is a name that is given to a set of elements. In filePro, we can match an array to a list of real fields, dummy fields or lookup fields. We say that an array can be "overlaid" or "aliased" or "mapped to" the group of fields.
Arrays are used for repetitive operations to increase speed and to decrease the size of your processing table.
Arrays are created with the DIM command. They are given a specified number of elements (fields) and attributes (lengths and edit types) if required.
Arrays are mapped to a specific set of fields. Those fields must be contiguous.
The element number of an array is called a subscript, and fields within the array are referred to as array sub1, written array["1"], or array sub2, written array["2"].
The subscripts are a pointer to that fields place in the array. They are numeric and can be manipulated with math formulas. By adding or subtracting to the subscript you can move around inside the array. By using an integer type dummy field as the subscript for arrays you can manipulate the subscript very easily with simple math.
Remember not to use array["1"] and array[1] interchangeably. The first is correct, the second means array sub(contents of field 1), which may or may not make sense. If the contents of field 1is within the limits of the number of elements in the array it will work, otherwise it wont.
Dimensioning Arrays (defining them)
Version 6.0.00 dim array(); ' 0 size arrays are now allowed by filePro
Example 1
dim array[20] no alias
The elements in the array will take on attributes of whatever is put into them according to normal filePro rules.
Example 2
dim array[20]:13 alias begins at field 13
array[ " 1 " ] is equal to field 13
array[ " 2 " ] is equal to field 14
array[ " 20 " ] is equal to field 32
Example 3
dim array[30]:aa alias begins at dummy field AA
array["1"] is equal to field AA
array["2"] is equal to field AB
array["26"] is equal to field AZ
array["27"] is equal to field BA
array["30"] is equal to field BD
Example 4
dim array[20]:filename(13) alias begins at lookup field 13
array["1"] is equal to looked-up filename(13)
array["2"] is equal to looked-up filename(14)
array["20"] is equal to looked-up file(32)
Example 5
dim array[20](8,.2):13
array["1"] is equal to field 13
You can define the length and edit type for all members of the array
Example 6
dim array[5](8,.2)(10,*)(2,state)(1,yesno)(5,allup):13
array[ " 1 " ] is equal to field 13
You can define the length and type for each specific member
Example 7 - Performing Repetitive Calculations
If you have 12 sets of data to perform an identical operation upon, instead of handling each set individually, you can overlay an array and perform the calculation repeatedly until the program reaches the end of the array.
Then: n[2,.0]="1"
Then: dim price[12]:2; dim quant[12]:14; dim total[12]:26
Loop If: quant[n] ne ""
Then: total[n]=price[n]*quant[n]
If: n lt "12"
Then: n=n+ " 1 " ; goto loop
Then: end
Example 8 - Moving Data
Arrays can be used to move large amounts of data from one record to another. This is done by overlaying an array on the lookup file and overlaying an array on the record you are standing on, then running a loop which copies one array to the other field by field.
Then: dim here[20]:12
Then: lookup cust=mscust k=1 i=a -ex
Then: dim there[20]:cust(12)
Then: I(2,.0)="1"
Again
Then: here[i]=there[i]
If: i eq " 20 "
Then: end
Then: i=i+"1";goto again
Example 9 - Arrays and Columns
By overlaying an ARRAY over columns of fields, you can operate on related line items. Imagine an invoice with 10 quantity fields, 10 catalog items fields, 10 price fields and 10 extension fields. Lets say you wanted to find out the total amount of money collected for one particular catalog item even though it may have been sold on any one or all of the line items. You could overlay a 10 element array over the catalog item fields, and a 10 element array over the 10 extensions fields. Then you could test the catalog array to see if the catalog item you are looking for is on the invoice, if it is found, take the corresponding extension (from its array) and add it to your count.
Example:
If: s = ""
Then: input s(5,.0,g)"What stock number are you searching for?"
If:
Then: i(2,.0)="1" ; dim cat[10]:5 ; dim ext[10]:45
Again If: i gt "10"
Then: end
If: cat[i]=s
Then: ct(10,.2,g) = ct + ext[i];i=i+"1";goto again
If:
Then: end
SCREEN
Catalog # Extended Price
*5 *45
*6 *46
*14 *54
Arrays and Associated Fields
If you overlay an ARRAY over a group of associated fields you can do better magic. This is because of a system maintained field called @AF. It holds a number corresponding to the occurrence of the associated field within its group.
If you have 32 associated fields and you do a search of that group and find a match, the @AF field will contain the occurrence number. If it was the fifth one in the associated group, then @AF will be "5".
The applications are endless. Take the above example of finding total number of a particular catalog item sold. If your columnar fields are associated fields, then the arrays overlaid on top of them can be scanned with one command. Rather than testing each element of the catalog array you can just say if the associated field group holds the catalog number, then the extension you want is ext[@AF].
Example
Assume field 5 starts associated field A2
if: s=""
then: input s(6,.0,g) "Enter Stock Number: "
if:
then: dim cat[10]:5;dim ext[10]:45
if: A2 co s
then: ct(10,.2,g) = ct + ext[@AF]
Catalog # Extended Price
*5 A2) *45
*6 A2) *46
*14 A2) *54
This code is not very robust, what if you have more than one occurrence? However, it demonstrates the idea. @when leaving field is a good place to make use of arrays and @af combinations. Take a look at the following for concise easy code? It handles all ten lines of an invoice.
@wlfe0 if: unit[@af] ne ""
then: chg[@af]=qty[@af] * unit[@af]
if:
then: gosub scr1tot;display;end
Note: (Parenthesis are usually optional when referring to associated fields. e0 = e0)
IMPORTANT: Use brackets [ ] on arrays instead of parenthesis (), always! It is easier to tell them apart from lookups.
Totaling Months with Arrays
Often people have devised accounting systems in filePro that do the job at hand, but dont lend themselves to future expansion and needs. One such situation is where a record holds a series of payment fields and another series of fields to hold the dates of the individual payments. People usually pick a number of payments that they dont think will be exceeded. Lets talk about a system that has had 10 payment fields (and 10 dates) allocated per record. A typical screen might look like the following:
Account Code: *1
Company Name: !2
PAYMENT HISTORY
Date Amount
Payment 1: *78 *35
Payment 2: *79 *36
Payment 3: *80 *37
Payment 4: *81 *38
Payment 5: *82 *39
Payment 6: *83 *40
Payment 7: *84 *41
Payment 8: *85 *42
Payment 9: *86 *43
Payment 10: *87 *44
====
Total Receipts: 160
Payments and their receipt date are put into the next available pair of fields. Everything is fine and you can easily get a total of payments made by adding all the payment fields together. But what if YOU want to know how much money you received during the month of May, or how much was received on a particular day? It is possible that the specified range of payments fall into any of the 10 allotted fields...
You will need to build a processing table for a report that tests every single date field to see if it contains a date within the desired range, and if it does add its partner amount into the total. To do this conventionally with field numbers would require many lines of programming! This kind of hard coded programming is also inelegant. (As if you care! Its the massive amount of typing we all hate.)
The report can be built quickly (and elegantly) with arrays. We can overlay arrays over the fields and refer to the array name and an element number instead of the actual field numbers. It requires that the 10 (or however many payment fields you need) are contiguous in the Define Files Map, and the 10 date fields for these payments must also be contiguous.
You build an output report that says something in the Total Lines Area like:
THE TOTAL RECEIPTS FOR
*bd to *ed were *aa
Thats all. Then you build processing attached to this report which does the following. First it asks the operator for the date range required, (for May the beginning and ending dates of May are entered, for any particular day both the beginning date and ending date can be the same. The processing dimensions an array called date with 10 elements and overlays it on top of the 10 date fields. It does the same with an array called amount and overlays it on top of the 10 payment fields. In the example these fields start at 78 and 35 respectively. The syntax shown in line 6 makes the first element of these arrays start on the specified field and every subsequent element of the array is equal to every subsequent field, net date["2"] is equal to field 70 date["3"] is equal to field 80 amount[t1"] Is equal to filed 35, cat["5"] Is equal to field 39 and so forth.
The processing starts at the first element in the date array (because "i", the array index, starts out being set equal to "1") and if the first date falls within the requested date range, the associated payment, (also using a index of "i" or "1">is added into the total, field "aa". Then "i" is incremented tested to see if it exceeds 10 (the maximum number of elements in our arrays) and if it isnt, everything happens again, if it is greater than 10, the process Is done on this record and the report moves on to the next record and its data. Because the totaling field "aa" is global it will hold its value from record to record. At the end the report will print the total of all payments received within the specified date range.
To use this table on your own records that are structured like the above example, be sure to set the array sizes to the number of fields you have set aside for payments and dates. Overlay the arrays on top of the starting field in each group (line 67. Then be sure to set the boundary check on line 8 to the number of elements you have defined for the arrays.
You will find that if you understand the nature of how arrays are working in this example, you will be able to use their power and efficiency in many other applications. (HINT: Make me 10 date fields an associated Held group and the amount field another associated field group. Thus will here in many instances. As an example, if the dates are associated fields, you could scan for all payments in a particular date range. This would be a very complicated group of selection sets to write otherwise and selecting on a particular date would be extremely difficult to do.).
If: ad ne ""
Then: goto doit
sdate If:
Then: input sd(8,mdy/,g) "Enter beginning date?"
If: sd=""
Then: goto sdate
edate If:
Then: input ed(8,mdy/,g) "Enter ending date?"
If: ed = ""
Then: goto edate
doit If:
Then: dim date[10]:78 ; dim amount[10]:35
If:
Then: I(2,.0)="1"
Loop If: I gt "10"
Then: end
If: date[i] ge sd and date[i] le ed
Then: aa(7,.2,g)=aa+amount[i]
if:
Then: i=i+"1";goto loop