Home

TOTVS Technology

Child pages
  • Array (Matrix)
Skip to end of metadata
Go to start of metadata

An array is defined as a set of related data, called elements, stored with the same name, identified and accessed through a numeric index. In each of these elements, any type of data is stored, excepting memo fields. An array element can also keep a reference to another array or block of code.

Each of the array elements is identified by a name, written between square brackets and by index. For example, consider a table made by 5 rows and 8 columns as follows:

 

Array Table

1,1

1,2

1,3

1,4

1,5

1,6

1,7

1,8

2,1

2,2

2,3

2,4

2,5

2,6

2,7

2,8

3,1

3,2

3,3

3,4

3,5

3,6

3,7

3,8

4,1

4,2

4,3

4,4

4,5

4,6

4,7

4,8

5,1

5,2

5,3

5,4

5,5

5,6

5,7

5,8

 

Table is classified as a matrix of two dimensions 5 x 8 made by five rows and eight columns. In the scheme, indexes are presented and they identify each of the elements. For example, the element in the third row of the fifth column is identified by 3,5 index. The element in the second row of the eighth column is identified by index 2,8, and so on. Indexes are always integer numbers.

In AdvPL, an array is accessed through a reference, it means, a memory address, where the array is placed and can be accessed. When an array is created, a name is assigned to this reference, which identifies the array.

 

Multidimensional Matrix

Multidimensional matrix is implemented in AdvPL through a set of intercalary two dimensional sub matrices. Each element of a matrix can keep data or a reference to another matrix. Check the example below:

aFuncion:= { "Marcos", 42, .T. }      
// One-dimensional array with the following information: 
// Employee's name, age and indication if he is a CLT employee

 

However, one of the elements can be the information related to the employee's dependents. In this case, the array structure is:

aFuncion:= { "Marcos", 42, .T., aDepend }

 

Where the array structure aDepend is the Dependent's name, kinship, age and gender:

aDepend:= 	{ { "Cláudia", 1, 35, "F" };
		{ "Rian", 2, 7, "M" } }

 

This AdvPL structure enables asymmetric multidimensional matrices. It happens when one of the intercalary matrices has a different number of elements, from other matrices, of the same level or matrix in which is part of. Suppose a CPF is entered in the dependent's array:

aDepend:= 	{ { "Cláudia", 1, 35, "F", "27847307849" };
		{ "Rian", 2, 7, "M", "16668978119" } }

 

In the example, the array aFuncion has four elements in the structure, while aDepend has five elements.

Instead of referring to another array, the dependent's information can also be saved in the array aFuncion directly, as one of the elements:

aFuncion:= 	{ "Marcos", 42, .T., { { "Cláudia", 1, 35, "F", "27847307849" },;
		{ "Rian", 2, 7, "M", "16668978119" }    } }

 

Arrays Creation

 

An array declaration is made by the same variable commands of other types of data: PRIVATE, PUBLIC, LOCAL and STATIC.

An array is created with or without a defined sized. If an array is not created using a defined size, the dimensions will be defined during program execution. Check the example below:

aExemp1:= { 10, 20, 30, 40, 50 }
aExemp2:= { "Clipper", aExemp1[3] + aExemp1[5], SQRT(a[1]), 1 + aExemp1[2] }

 

The example below is the same as the previous one: 

LOCAL    aExemp1[5]
LOCAL    aExemp2[4]


aExemp1[1]:= 10
aExemp1[2]:= 20
aExemp1[3]:= 30
aExemp1[4]:= 40
aExemp1[5]:= 50
aExemp2[1]:= "Clipper"
aExemp2[2]:= aExemp1[3] + aExemp1[5]
aExemp2[3]:= SQRT(aExemp1[1])
aExemp2[4]:= 1 + aExemp1[2]

 

An array is used in any point of the program, also as another array element. This way, you can detail a multidimensional array:

aExemp3:= { { 1, 2, 3 }, { "A", "B", "C" }, { .F., DATE(), .F. } }

 

If the array elements were displayed to the user on the screen, we would have the following results:

MSGALERT(aExamp3[1, 1])     
// Result: 1


MSGALERT(aExamp3[2, 1])     
// Result: "A"


MSGALERT(aExamp3[3, 3])     
// Result: .F.


 

Function ARRAY() is used to create arrays with specific dimensions. Array dimensions to be created are detailed as arguments of the function ARRAY(). Example:

LOCAL    aTabela:= ARRAY(5, 10)

 

In this example, an array was created with 5 rows and 10 columns.

An empty array is defined as a matrix with no elements. In order to create an empty array, the following instruction is used:

LOCAL    aTabela:= { }

 


Empty arrays are useful when we do not know, at first, the number of elements they will have. Later, function AADD() and ASIZE() can be used to change the structure, adding the necessary number of elements to run the routine.

In order to test whether an array exists or was created, function VALTYPE() is used, which will present "A" as an argument for an array. For example:

LOCAL    aTabela:= { }
IF VALTYPE(aTabela) == "A"
	MSGALERT("It is an array")
ENDIF

 

In order to test whether an array is empty, it means, with no elements, function EMPTY() is used according to example below:

IF EMPTY(aTabela)
	MSGALERT("The array is empty")
ENDIF

 

The array element number is defined by function LEN():

LOCAL  aTabela[5, 8]


MSGALERT(LEN(aTabela))

 

The above message displays the array aTabela has 5 elements.

Pay attention that function LEN() only assigns a number of elements of the first dimension of the array aTabela. The reason is, in AdvPL, multidimensional matrices are made by intercalary one-dimensional sub matrices and these are found or made as reference in a main matrix. It means we understand that the array aTabela has one-dimension with five elements, each of them makes reference to a sub matrix of eight elements, becoming a matrix of two dimensions 5 x 8. For this reason, function LEN(), when applied to array aTabela, has only five elements as result.

In order to determine the number of sub matrices, it means, the array aTabela second dimension, function LEN() must be used in the first element of the main matrix, which has the first sub matrix, according to example below:

MSGALERT(LEN(aTable[1]))

 

In this case, a message displays the first element with 8 columns. If the evaluated matrix is empty, function LEN() will display a nil value.


Arrays Elements

In order to access an array element, this must be identified by the array name, then, between square brackets and indexes. For example:

PRIVATE    aTabela[5,8]     // Creates matrix aTabela.

 

When an array is created with no defined values, each of the elements has a NIL value assigned. This value is used up to the elements are changed into other values. The example below, displays the use of different data in some elements of array aTabela.

aTabela[1,1]	:= 100      // Equals to aTabela[1][1] := 100 
aTabela[2][3]	:= "AdvPL"
aTabela[5,4]	:= DATE()
aTabela[2][2]	:= .T.
aTabela[3,3]	:= aTabela[1,1] * 2 
aTabela[4,4]	:= SQRT(aTabela[1,1])

 

Indexes that identify the array elements are always integer numbers and begin by number 1. Indexes assigned to array elements must be compatible with their own dimensions and number of elements of each dimension. If it does not happen, an error will be displayed during the program execution. For example:

aTabela[6,1]:= 1

 

The above situation causes an error, as the array aTabela has only 5 rows.

AdvPL also enables the creation and beginning of an array based on a data table structure and the information of a file folder in server. The respective commands (DBSTRUCT and DIRECTORY) are described in Function topic. 

Function AFILL() is used to start array elements of a single dimension with specific data. For example:

LOCAL aVetor[20]

AFILL(aVetor, SPACE(10), 1, 10)     
// Begins the first 10 one-dimension array elements aVetor with ten in blank places.


AFILL(aVetor, 0, 11, 20)     
// Begins the last 10 one-dimension array elements aVetor with nil value.

 

Array elements are started by the result of any valid AdvPL expression, also including block of codes and references to other arrays. Once started, the array elements are used as if they were variables.

As in AdvPL, you can assign an array reference to an element from other array, the array structure already existent can be changed dynamically during program execution. For example:

PRIVATE aTabela[5,5]     
// The array was created with 5 rows and 5 columns.

aTabela[1, 1]:= { 10, 20, 30, 50, 80 }
      
// The array structure was changed during running time. 
//If the element content aTabela[1, 1, 5] was displayed, the content 80 would be shown.

 

However, if the content of the elements below was displayed, an error would occur, as these elements do not exist in the array structure:

aTabela[1, 2, 1]


aTabela[2, 1, 1]

 

Analyzing this example, the three dimensions are only valid for element aTabela[1, 1], as it holds a reference to another array with one-dimension. This powerful AdvPL resource enables you to explore amazing programming resources. However, as the array structure may change dynamically, you must be careful about its use, as there is a risk of losing the application fully control, becoming confuse and susceptible to errors.

 

Use of arrays as routine parameters

Arrays can be passed to functions as arguments. When a passing is made through function syntax, arrays are, by definition, passed as value. It means that a reference copy to the array is passed to the parameters that will be received by the function invoked. In this situation, any change made in array elements, by the function invoked, will be reflected in the original array. For example:

LOCAL aLista[20]     
// The array is created and all elements receive a NIL value. 
 
AFILL(aLista, 1, 1, 10)    
// Provides value 1 to the 10 first elements.


AFILL(aLista, 2, 11, 20)     
// Provides value 2 to the last 10 elements.


MSGALERT(aLista[1])     // Displays value 1.
MSGALERT(aLista[11])    // Displays value 2.
Dobro(aLista)   	// Runs function Dobro().
MSGALERT(aLista[1])     // Displays value 2.
MSGALERT(aLista[11])    // Displays value 4.


// Function Dobro()
FUNCTION Dobro(aMat)


LOCAL nElem:= 0


FOR nElem:= 1 TO LEN(aMat)
	aMat[nElem]:= aMat[nElem] * 2
NEXT nElem

RETURN NIL

 

In this example, when function Dobro() is run, a reference copy to the array aLista is passed to parameter aMat. Function Dobro() multiplies all the elements of array aLista by two. When function Dobro() is ended, reference aMat is deleted, but changes made in the element values of array aLista are kept.

An array can also be assigned as a function result. This resource enables a function, which usually uses a single value as a result, to provide multiple values through array elements and by RETURN command. For example: 

aTabela:= CreatesTb(5, 10, SPACE(10))

// Function CreatesTB and feeds the array according to the number of rows, columns and content.
FUNCTION Creates Tb(nLinhas, nColunas, cConteudo)
	LOCAL aTab[nLinhas, nColunas]

	FOR nElem1:= 1TO nLinhas
		FOR nElem2:= 1 TO nColunas
			aTab[nElem1, nElem2]:= cConteudo
		NEXT nElem2
	NEXT nElem1

	RETURN aTab

 

Special Functions for  Arrays Manipulation

The double equal sign operator ( == ) is used to compare two arrays, checking whether they are equivalent. That is, if they have the same content. For example:

LOCAL aTabela1 	:= { 1, 2, 3 }
LOCAL aLista 	:= { 1, 2, 3 }
LOCAL aTabela2 	:= aTabela1


IF aTabela1 == aTabela2
          // Result: .T. (true)
          MSGALERT(“The arrays content aTabela1 and aTabela2 are equal”)
ENDIF


IF aTabela1 == aLista
          //Result: .F. (false)
          MSGALERT(“The arrays content aTabela1 and aLista are different”)
ENDIF

 

AdvPL has two functions to change a pre-existent array dimension:

1.ASIZE( <array>, <elementos> )

The function ASIZE() redefines an array ( <array> ) according to a new number of elements ( <elementos> ). In case the new number of elements is higher than the previous one, new elements are added, attributing the NIL value to them. In case the new number of elements is lower than the previous one, the elements above this number are deleted.

2.AADD( <array>, <expressão> )

The function AADD() adds a new element in the specified array ( <array> ), attributing to it the specified expression result ( <expressão> ). The new element is the array last one.

 

To insert or remove elements of a pre-existent array,  AdvPL has two functions. Different from functions AADD() e ASIZE(), these functions do not edit the array dimension, they just edit the content of its elements.

3.ADEL( <array>, <nº do elemento> )

The function ADEL() removes the array element ( <array> ) defined by the element number ( <nº do elemento> ). All the elements placed after the removed element are moved to left. The value NIL is attributed to the last element.

4.AINS( <array>, <nº do elemento> )

The function AINS() inserts an element in the array ( <array> ) in the position defined by the argument <nº do elemento>. The value NIL is attributed to the new element All the elements placed after the inserted element are moved to right and the array last element is destroyed.

To copy the arrays, AdvPL has two functions:

5.ACOPY()

This function copies a group or all the elements from a source array to a pre-existent target array. In case the source array has subarrays, the target array has just references to them and not real copies.

6.ACLONE()

This function doubles an entire source array to a new target array, copying the element values of the source array to the new array elements.

The array element order can be automatically performed by function ASORT(). It enables the order or classification of all elements of an array or a determined group of arrays. The order criterion can be specified through a code block.

To localized an array element with a determined value, use function ASCAN(). It searches array elements to localize the element that has a determined value specified through an expression or code block. This function searches all or just a determined group of array elements. In case the desired value is found, the function returns the corresponding index to the element. Otherwise, the returned value is zero.

  • No labels