How To Use Arrays In Reports
This powerful feature of the Report Writer is great for managerial reports and scanning large volumes
of data. Coding is kept to a minimum and data needs to be read only once. This simplifies writing
and speeds up execution.
What Is An Array?
An array is a variable that has multiple dimensions. These dimensions can have values stored in them.
The size of these dimensions can be specified. You can use arrays in reports. Instead of many lines
of code in the report writer, arrays provide a compact way to write reports, store data and print
it out.
An array created in Collect! can have unlimited dimensions or columns. To explain this, let's start
with a 2 dimensional array with room to store 5 records.
This is how you would define this array:
@varMyArray[5][2] = ""
// OR
@varMyArray[5][2] = 0
You must have an equals sign followed by a blank value. You do not need to specify a format
line string or number, yet. That will happen later.
When looking at an array, it helps to picture it. You can think of it as a spreadsheet. This array
would have 5 rows and 2 columns, as illustrated below.
[1][1] |
[1][2] |
[2][1] |
[2][2] |
[3][1] |
[3][2] |
[4][1] |
[4][2] |
[5][1] |
[5][2] |
We can assign values to these locations in the array. To put data in each row of the first column,
you would increment the value of the first dimension of the array while keeping the second dimension
as 1.
@varMyArray[1][1] = 1
@varMyArray[2][1] = 2
@varMyArray[3][1] = 3
@varMyArray[4][1] = 4
@varMyArray[5][1] = 5
This would produce the following results:
To specify values for the second column of the array, we would change the value of the second
dimension in the array to 2. This means the second column.
@varMyArray[1][2] = 5
@varMyArray[2][2] = 4
@varMyArray[3][2] = 3
@varMyArray[4][2] = 2
@varMyArray[5][2] = 1
Now the array will look like this:
Each location in the array can hold a different type of data. For instance, in our example, we
could specify that we want one column or dimension of the array to hold strings and the other
to hold numbers.
First, we define the array:
@varMyArray[5][2] = ""
Then, when we store the values, we use the symbols for variable types, for example,
# for integers, in our first column, and * for strings, in our
second column.
@varMyArray[1][1]# = 1
@varMyArray[2][1]# = 2
@varMyArray[3][1]# = 3
@varMyArray[4][1]# = 4
@varMyArray[5][1]# = 5
@varMyArray[1][2]* = Sam Jones
@varMyArray[2][2]* = Karen Smith
@varMyArray[3][2]* = Michael Black
@varMyArray[4][2]* = Thomas Moore
@varMyArray[5][2]* = Mary Allen
1 |
Sam Jones |
2 |
Karen Smith |
3 |
Michael Black |
4 |
Thomas Moore |
5 |
Mary Allen |
There are two ways we can print information from the array. The easiest is simply to call the array
in your report.
@varMyArray
This will print the entire array:
1 Sam Jones
2 Karen Smith
3 Michael Black
4 Thomas Moore
5 Mary Allen
To print a single value from the array, we would specify the exact location where that value is
stored in the array. For instance, to print Michael Black in our report, we would put the following
line in our report.
@varMyArray[3][2]
For example:
Cosigner: @varMyArray[3][2]
Would print out Cosigner: Michael Black, because Michael Black is the value stored
in the third row, second column of the our array.
Array Tutorial - Step 1
This step shows how an array is declared and how variables are assigned to cells in the array.
In order to use this tutorial you should print this report and then look at the output. Then review
the report source code to see how it's done.
Arrays are used to store analytical data such as totals used in reports, for instance the Monthly
Step/Spindown Report.
Declaring the Array
As shown above, declaring arrays is simple, as the first reference to a variable with square brackets
immediately after the variable name declares the array to the specified size. Array indexes are 1
based. Arrays can be multidimensional with no practical limit to the number of dimensions. You cannot
re-dimension an array after initial declaration.
The line below (varA[2][2]) initializes a 2 by 2 array. You would declare a multidimensional array
using the same syntax. For example varX[10][10][10] declares an array with 1000 cells.
@varA[2][2] = 0
@varI = 2
Next we assign values to each array element. See how you can use a variable to specify an index into
the array. We are assigning the value @varI< to a variable named varI and using that to address
individual elements in an array.
@varA[1][1] = 1
@varA[1][2] = 2
@varA[2][1] = 3
@varA[2][@varI] = 4
Printing the Entire Array
You can print the whole array with one command (varA). This is a key feature to minimize your report
code. We'll learn more about printing arrays in later examples. Notice how a one line command can
print more than one piece of information automatically.
@varA
Printing a Single Cell
If you want to access some cell in the array you can do so with the following syntax. Using the array
cell varA[2][1] will output just the contents of that cell.
@varA[2][1]
Cell Data Types
Here we declare an array varB[3][3] and we will make various fields different types.
@varB[3][3] = 0
And now we assign different values to each cell to show how we can use labels with the array.
@varB[1][1]* = Row 1
@varB[1][2]* = Col 1
@varB[1][3]* = Col 2
@varB[2][1]* = Row 2
@varB[2][@varI]$ = 123.45
@varB[2][3]$ = 3456.78
@varB[3][1]* = Row 3
@varB[3][2]% = 12.567
@varB[3][3]% = 17.657
Now print varB without any specific formatting information:
@varB
Print Formatting
And now I'll print varB telling it to format 10 characters wide, right justified. When using
formatting commands with an array the formatting applies to all elements of the array.
@varB>10>
Cell Data Type Reassignment
Using a different data type like whole number (#), you can change the type of a cell.
@varB[1][1]# = 0
@varB[1][2]# = 1995
@varB[1][3]# = 1996
@varB[2][1]# = 1995
@varB[3][1]# = 1996
@varB>10>
Array Tutorial - Step 2
This step shows how to use dates to obtain an array index.
The goal is to calculate the array index of an item based on the date. Date indexes are important
when using arrays to accumulate and report statistical data.
Here we use the date math parsers d, m and y.
Parsing Dates
This first example shows how you can get the numeric month, day and year of today's date, and how
we can get the same for listed date on 5 accounts. Notice how the standard date commands work with
the @d command.
First we'll break apart today's date: @d
@varD1a# = @d<MM>
@varD1b# = @d<dd>
@varD1c# = @d<yyyy>
Month: @varD1a
Day: @varD1b
Year: @varD1c
You might have considered parsing m or y date commands but if you think about it there are easier
ways of dealing with monthly and yearly dates.
Now we'll list 5 accounts with their listed dates. Notice how the special date parsers d, m and y
are used for the date field to isolate the day, month and year components.
Date Month Day Year
@de max = 5
@varD2a# = @de.li<m>
@varD2b# = @de.li<d>
@varD2c# = @de.li<y>
@de.li @varD2a @varD2b @varD2c
@de
Index by Year
This next example deals with creating an index based on years.
The sample code calculates a date index by year on the Listed Date field. Index is number of years
back from today's year.
Date Year Index
@varY# = 0
@varI# = 0
@de max = 10
@varY = @de.li<y>
@varI = @(varD1c-varY)
@de.li @varY @varI
@de
Index by Month
Now an example of index by month up to 24 months back.
The following loop scans accounts and produces an index number from 1 to 24 counting from this month
up to 24 months back.
Set the reference to today's date : @d
@varY# = 0
@varYo# = 0
@varT = @d<yyyy>
@varTo = @d<MM>
varT : @varT
varTo: @varTo
Year Month Years Months Offset Total Index
@de max = 10
@varY = @de.li<y>
@varYo = @de.li<m>
@varD = @(varT-varY)
@varS = @(varTo-varYo)
@varN = @(varD*12)
@varO = @(varN+varS)
@varP = 0
@varP = @varO if (@varO < 25)
@varY<10> @varYo<10> @varD @varN<10> @varS @varO<10> @varP<10>
@de
Index by Month - Minified
Here is the same loop in a minimal configuration that you would use in an actual report. Note how
we've eliminated intermediate variables to minimize number of lines parsed per loop iteration.
Year Month Months Index
@de max = 10
@varY = @de.li<y>
@varYo = @de.li<m>
@varO = @((varT-varY)*12+(varTo-varYo))
@varP = 0
@varP = @varO if (@varO < 25)
@varY<10> @varYo<10> @varO<10> @varP<10>
@de
Index by Month - Reversed
This month index code results in totals at the top right of the spindown grid. For historical
business analysis this index calculation is useful.
Year Month Months Index
@de max = 10
@varY = @de.li<y>
@varYo = @de.li<m>
@varO = @((varT-varY)*12+(varTo-varYo))
@varP = 0
@varP = @(24-varO) if (@varO < 26)
@varY<10> @varYo<10> @varO<10> @varP<10>
@de
Array Tutorial - Step 3
This step shows how to use the plus equals and related math operators in reports. This technique
is an efficient way of accumulating data in a report. This is often used with arrays in analytic
reports.
Plus equals |
+= |
Minus equals |
-= |
Multiply equals |
*= |
Divide equals |
/= |
A typical variable assignment using these operators would look like this:
@varA# = 1
@varA += 1
This command adds 1 to varA to result in 2. That's all there is to it. That beats typing
@varA = @(varA+1) and it helps the report system run faster as less command parsing is needed to
cause the desired result.
@varA *= 4
The command above multiplies varA by 4 which results in 8.
Next, we'll look at combining these operators with date index math and arrays to efficiently create
a monthly step/spindown report framework.
Array Tutorial - Step 4
This example prompts for a client number and then scans the debtors (up to 100 maximum) and their
transactions for the selected client. If the transaction is a payment type then the amount paid is
placed in the proper cell of the array based on the year of the charged date and the payment date.
Note how this is a 10 year spindown.
ANALYSIS BY YEAR
// declarations
// array for amounts
@varA[12][13] = 0
// indexing variables
@varY# = 0
@varI# = 0
@varJ# = 0
// and loop through the stuff
@cl where (@cl.cl = ?) max = 1
@cl.de max = 100
// get index by debtor's date
@varY = @de.ch<y>
@varI = 0
@varI = @(2024-varY) if (@varY = 2013 .. 2023)
@varI += 1
@de.tr
@varAmt$ = 0
@varAmt = @(tr.di+tr.tu) if (@tr.pa = X)
// get index by transaction date
@varY = @tr.pd<y>
@varJ = 0
@varJ = @(2024-varY) if (@varY = 2013 .. 2023)
@varJ += 1
// and accumulate the amount into the cell
@varA[@varI][@varJ] += @varAmt
@de.tr
@cl.de
@cl
Here we gather the dollar amounts and then print the array varA: @varA
Adding Titles and Some Totals
Now, let's modify the report a little to get headings for the rows and columns in the grid. We'll
also add the debtor principal amounts in column 2.
// declare the bigger array for amounts and headings
@varB[13][18] = 0
@varY# = 0
@varI# = 0
@varJ# = 0
@cl where (@cl.cl = ?) max = 1
@cl.de max = 100
@varY = @de.ch<y>
@varI = 2
@varI = @(2026-varY) if (@varY = 2013 .. 2023)
// put the date into the heading cell
@varB[@varI][1]# = @varY if (@varY > 1992)
@varB[@varI][2] += @de.pr
@de.tr
@varAmt$ = 0
@varAmt = @(tr.di+tr.tu) if (@tr.pa = X)
@varY = @tr.pd<y>
@varJ = 3
@varJ = @(2026-varY) if (@varY = 2013 .. 2023)
@varB[@varI][@varJ] += @varAmt
// put the date into the heading cell
@varB[1][@varJ]# = @varY
@de.tr
@cl.de
@cl
@varB>12>
Here we printed the array varB automatically. Notice how we used formatting control because the
dollar amount and date fields are different types and so the array wouldn't line up otherwise.
Reversing the Order
With a small manipulation of the indexing math we can display things in a different order. in this
example both indexes are reversed.
@varC[13][18] = 0
@varY# = 0
@varI# = 0
@varJ# = 0
@cl where (@cl.cl = @cl.cl) max = 1
@cl.de
@varY = @de.ch<y>
@varI = 2
@varI = @(varY-2010) if (@varY = 2013 .. 2023)
@varC[@varI][1]# = @varY if (@varY > 1992)
@varC[@varI][2] += @de.pr
@de.tr
@varAmt$ = 0
@varAmt = @(tr.di+tr.tu) if (@tr.pa = X)
@varY = @tr.pd<y>
@varJ = 3
@varJ = @(varY-2010) if (@varY = 2013 .. 2023)
@varC[@varI][@varJ] += @varAmt
@varC[1][@varJ]# = @varY
@de.tr
@cl.de
@cl
@varC>12>
Array Tutorial - Step 5
This example is a 12 month version of the code demonstrated in step 4. It prompts for a client
number and then scans the debtors (up to 100 maximum) and their transactions for the selected client.
If the transaction is a payment type then the amount paid is placed in the proper cell of the array
based on the year of the charged date and the payment date. Note how this is a 12 month spindown.
12 MONTH SPINDOWN
// declare the array for amounts and headings
@varC[15][15] = 0
// and get reference dates
@varT = @d<yyyy>
@varTo = @d<MM>
@varY# = 0
@varYo# = 0
@varI# = 0
@varJ# = 0
@cl where (@cl.cl = ?) max = 1
@cl.de max = 300
@varY = @de.ch<y>
@varYo = @de.ch<m>
@varO = @((varT-varY)*12+(varTo-varYo))
@varI = 2
@varI = @(16-varO) if (@varO < 14)
@varS* = @(varY*100+varYo)
@varC[@varI][1]# = @varS if (@varI > 2)
@varAmt# = @de.pr
@varC[@varI][2] += @varAmt if (@varI > 2)
@de.tr
@varY = @tr.pd<y>
@varYo = @tr.pd<m>
@varS* = @(varY*100+varYo)
@varO = @((varT-varY)*12+(varTo-varYo))
@varJ = 2
@varJ = @(16-varO) if (@varO < 14)
@varAmt# = 0
@varAmt = @(tr.di+tr.tu) if (@tr.pa = X)
@varAmt = 0 if (@varJ < 3)
@varC[@varI][@varJ] += @varAmt if (@varI > 2)
@varC[1][@varJ]* = @varS if (@varJ > 2)
@de.tr
@cl.de
@cl
@varC[1][1]* = Charged
@varC[1][2]* = Princ
@varC>8>
Array Tutorial - Step 6
This example is a 24 month version of the code demonstrated in step 5. It prompts for a client number
and then scans the debtors and their transactions for the selected client. If the transaction is a
payment type then the amount paid is placed in the proper cell of the array based on the year of the
charged date and the payment date. Note how this is a 24 month spindown.
24 MONTH SPINDOWN
// declare the bigger array for amounts and headings
@varD[32][33] = 0
@varT = @d<yyyy>
@varTo = @d<MM>
@varY# = 0
@varYo# = 0
@varI# = 0
@varJ# = 0
@cl where (@cl.cl = ?) max = 1
@cl.de
@varY = @de.ch<y>
@varYo = @de.ch<m>
@varO = @((varT-varY)*12+(varTo-varYo))
@varI = 2
@varI = @(33-varO) if (@varO < 32)
@varS* = @(varY*100+varYo)
@varD[@varI][1]# = @varS if (@varI > 2)
@varAmt# = 0
@varAmt = @de.pr if (@varI > 2)
@varD[@varI][2] += @varAmt
@de.tr
@varY = @tr.pd<y>
@varYo = @tr.pd<m>
@varS* = @(varY*100+varYo)
@varO = @((varT-varY)*12+(varTo-varYo))
@varJ = 2
@varJ = @(33-varO) if (@varO < 32)
@varAmt# = 0
@varAmt = @(tr.di+tr.tu) if (@tr.pa = X)
@varAmt = 0 if (@varI < 3)
@varD[@varI][@varJ] += @varAmt if (@varJ > 2)
@varD[1][@varJ]* = @varS if (@varJ > 2)
@de.tr
@cl.de
@cl
@varD[1][1]* = CHARGED
@varD[1][2]* = PRINC
@varD>8>
Dynamic Arrays
You can set the size of your array dynamically by simply counting the number of items you will be
outputting.
The following example counts the number of operators before declaring an array for calculating
operator totals.
// Count the number of operators so we can size
// the array properly.
@tvarArrSize = 3
@op no total
@tvarArrSize += 1
@op
// Now declare the array with the number of rows
// you just counted.
@varOpTotals[@tvarArraySize][2] = 0
WARNING: This requires your data to be processed twice, which would slow down more complex reports.
For more complex reports that only require 2 dimensions in the Array, please refer to
SQL Queries below.
SQL Queries In Arrays
Collect! can support SQL queries in the report writer. The query is sent to the server, then the
results are returns to an array.
SQL arrays do not require defining (hence [][]) as the result set from SQL server will
auto-define the dimensions. SQL arrays are 2 dimensional only. The number of SELECT fields
will determine the horizontal axis and the number of records will determine the vertical
axis. To obtain the dimension, please see the @COUNT command below.
Syntax: @varArray[][] = @SQL({query})
Example: @varArray[][] = @SQL(SELECT de_name,de_number from debtor where de_active = 'A')
If your SQL query is not inside a loop, you can place the query on multiple lines.
Examples:
@varArray[][] = @SQL(
SELECT de_name,de_number
FROM debtor
WHERE de_active = 'A'
)
@varArray[][] = @SQL(
SELECT SUM(de_principal),SUM(de_owing)
FROM debtor
WHERE de_active = 'A'
)
Once the array is returned, you can output the array as is or you can use a loop to parse the data.
Here is an example of outputting an array using a loop:
@varArrayCount# = @COUNT(@varArray)
@varArrayIndex# = 1
@while (@varArrayIndex <= @varArrayCount)
@varArray[@varArrayIndex][1]<40> @varArray[@varArrayIndex][2]<10>
@varArrayIndex += 1
@endwhile
@varArrayIndex is set to 1 before the loop in the event that @varArrayCount is 0;
otherwise 0=0 and the report would output a blank line. The @varArrayIndex is
incremented at the end of the loop, so the first line is not skipped.
SQL Queries Using Printable Information Codes
For ease of use, Collect! can translate printable information codes into the database forms and
fields so you don't have to learn the schema. The SQL printable codes are the same as the regular
codes, but start with an & instead.
Example: "&de" will translate to the table "debtor" and "&de.na" will translate to the field name
"de_name"
Record relationships like debtors and transactions must be linked with the SQL field names,
such as INNER JOIN &cl on cl_rowid = de_rowid_client
You can reference regular print codes and variables in the queries.
Example:
@varStatus* = ACT
@varArray[][] = @SQL(
SELECT &de.na,&de.fi
FROM &de
JOIN &tr ON tr_rowid_debtor = de_rowid
WHERE &de.mo
AND &de.sta = @varStatus
AND (&tr.pda BETWEEN @tsr.fr AND @tsf.to)
)
Counting The Number Of Rows And Columns In An Array
The @COUNT command returns the number of rows or columns in an array. By default, it returns the
size of the first dimension of the array, to specify the size of other dimensions, follow the name
with the dimension number separated by a comma. The dimension number is 0 based. This command is
not case sensitive.
Syntax: @COUNT(@varArray) returns the size of the first dimension, typically the
number of rows.
Syntax: @COUNT(@varArray,0) is equivalent to @count(@varArray) and returns the
size of the first dimension.
Syntax: @COUNT(@varArray,1) returns the count of the second dimension.
Example:
@varCount# = @count(@varArray)
|
Was this page helpful? Do you have any comments on this document? Can we make it better? If so how may we improve this page.
Please click this link to send us your comments: helpinfo@collect.org