A very powerful feature of TAS Professional is the ability to refer to a field indirectly through the use of pointers.
A pointer is a value that literally 'points to' the field. In TAS Professional there are two different types of pointers. One points to the field specification within the field list in a program; the other points to the actual location of the field value. This second pointer is more typical of that used in languages such as C. In fact, we have set up this type of pointer ('P' pointer) so that you can pass it to non-TAS programs and access your TAS data directly!
To set the value of a pointer (either F or P) use the pointer command:
pointer_fld -> field_name
The command automatically determines which type of pointer you are using and returns the correct value. To refer to a field through the use of the pointer precede the pointer name with the redirector symbol ('&'). In all cases where you need a field name in a you can use this method of referring to it. For example, your code may look like:
fptr_fld -> test
x = &fptr_fld
This is the same as:
x = test
You can set a pointer to an element in an array by specifying the array field and the element, i.e.:
pptr_fld -> test[cntr] //where cntr is the array element number
The array element number can be either a constant or a variable. The pointer field can also be an array, i.e:
fptr_fld[x] -> test[cntr]
y = &fptr_fld[x]
In this example the xth element of the F type pointer array fptr_fld now points to the element in test as determined by the value of cntr. The field names used in this example are arbitrary. You don't have to name P type pointer pptr or F type pointer fptr; however, in the documentation we refer to them in that manner. The array specifier [x] in this case means the xth element in fptr_fld.
NOTE: The above applies only to Btrieve and Defined fields. If you are referencing a field from a CodeBase file you must point to the field only (even if it's an array). You will still be able to refer to the field as shown below.
You can also refer to an array element in a field being pointed to through the use of the array pointer redirector. For example:
fptr_fld -> test
x = @fptr_fld
y = @fptr_fld
z = @fptr_fld
where test is a 10 element array. TAS Professional uses the array element specifier to determine the correct element in the array field being pointed to and not the pointer field. In the example above, each equal command will apply to the appropriate element in the field test. You need not use a constant as an array specifier; it is used here only as an example.
Through the use of this facility in TAS Professional you have the power to access data without ever knowing what the data is you're going to work with when you write the program.
There is also a specialized case where you use the & indirect reference character. This is in connection with A type (alpha) fields or the result of the COMPILE_EXPR() function. In the first instance, the alpha field is treated like an expression and is compiled first. The the result is evaluated the same as a standard expression. In the second case, the compilation process is skipped since it has already been accomplished with the function and just the evaluation process is done. So, for example, if you allow the user to enter an expression into the field UserExpr you might use something like the following:
define x type a size 100
x = &UserExpr
If the user enters "A"+"B"+"C" the result in the MSG will be: ABC. You could have just as well used:
x = &'"A"+"B"+"C"'
and have received the same results.
The downside to this method is that each time you execute the command with the & space is used up in memory. So, if you are going to execute the compilation process hundreds, or thousands of times, such as in a FOR option in a SCAN command, you might want to use the COMPILE_EXPR instead, and then evaluate the result of that. In this case, the space is only used once. This also allows you to create multiple pre-compiled expressions that can be used again and again. For example, say the user is entering a filter value to be used in searching for records in a file. Then you might use something like this:
define Filter type f
Filter = compile_expr(UserExpr)
scan @file_hndl key @key_num for &filter
As long as the UserExpr evaluates to True or False this will control which records are used in the SCAN loop. For example, in a customer file the user might enter BKAR.CUSTZIP>='98000' .and. BKAR.CUSTZIP<'99000'. This would limit records with a zip code from 98000 up to 99000. Notice that the expression is exactly the same as you would use it in your code directly. The only difference is that you're going to evaluate it at runtime and allow the user to change it as desired.
A good example of this is in Maintain Database. If you press the CTL_F keys once the file has been displayed, you can enter the filter value.