Checks if a variable contains data.
Description
You can use $DATA to test whether a variable contains data before attempting an operation on it. $DATA returns status information about the specified variable. The variable argument can be the name of any variable (local variable, process-private global, or global), and can include a subscripted array element. It can be a multidimensional object property; it cannot be a non-multidimensional object property.
The possible status values that may be returned are as follows:
Status Value |
Meaning |
0 |
The variable is undefined. Any reference would cause an <UNDEFINED> error. |
1 |
The variable exists and contains data, but has no descendants. Note that the null string ("") qualifies as data. |
10 |
The variable identifies an array element that has descendants (contains a downward pointer to another array element) but does not contain data. Any direct reference to such a variable will result in an <UNDEFINED> error. For example, if y(1) is defined, but y is not, $DATA(y) returns 10, set x=y will produce an <UNDEFINED> error. |
11 |
The variable identifies an array element that has descendants (contains a downward pointer to another array element) and contains data. Variables of this type can be referenced in expressions. |
You can use modulo 2 (#2) arithmetic to return a boolean value from $DATA: $DATA(var)#2 returns 0 for the undefined status codes (0 and 10), and returns 1 for the defined status codes (1 and 11).
Status values 1 and 11 indicate only the presence of data, not the type of data.
You can use the Undefined()Opens in a new tab method of the %SYSTEM.ProcessOpens in a new tab class to set behavior when encountering an undefined variable. For more information on <UNDEFINED> errors, refer to the $ZERROR special variable.
$DATA Tests Locks, Routines, Jobs, and Globals
-
$DATA(^$LOCK(lockname)) tests for the existence of a lock. Note that the return values are different: 0 = lock does not exist; 10 = lock exists. Lock descendants cannot be determined. Values 1 and 11 are never returned. Refer to ^$LOCK for further details.
-
$DATA(^$ROUTINE(routinename)) tests for the existence of the OBJ code version of a routine. Note that the return values are different: 0 = routine OBJ code does not exist; 1 = routine OBJ code exists. Values 10 and 11 are never returned. Refer to ^$ROUTINE for further details.
-
$DATA(^$JOB(jobnum)) tests for the existence of a job. Note that the return values are different: 0 = job does not exist; 1 = job exists. Values 10 and 11 are never returned. Refer to ^$JOB for further details.
-
$DATA(^$GLOBAL(globalname)) tests for the existence of a global. The return codes are the same as for variables: 0, 1, 10, and 11. Refer to ^$GLOBAL for further details.
Examples
This example writes a selected range of records from the ^client array, a sparse array consisting of three levels. The first level contains the client’s name, the second the client’s address, and the third the client’s accounts, account numbers, and balances. A client can have up to four separate accounts. Because ^client is a sparse array there may be undefined elements at any of the three levels. The contents for a typical record might appear as follows:
^client(5) John Jones
^client(5,1) 23 Bay Rd./Boston/MA 02049
^client(5,1,1) Checking/45673/1248.00
^client(5,1,2) Savings/27564/3270.00
^client(5,1,3) Reserve Credit/32456/125.00
^client(5,1,4) Loan/81263/460.00
The code below provides a separate subroutine to handle the output for each of the three array levels. It uses the $DATA function at the start of each subroutine to test the current array element.
The $DATA=0 test in Level1, Level2, and Level3 tests whether the current array element is undefined. If TRUE, it causes the code to QUIT and revert to the previous level.
The $DATA=10 test in Level1 and Level2 tests whether the current array element contains a pointer to a subordinate element, but no data. If TRUE, it causes the code to write out a “No Data” message. The code then skips to the FOR loop processing for the next lower level. There is no $DATA=10 test in Level3 because there are no elements subordinate to this level.
The WRITE commands in Level2 and Level3 use the $PIECE function to extract the appropriate information from the current array element.
Start Read !,"Output how many records: ",n
Read !,"Start with record number: ",s
For i=s:1:s+(n-1) {
If $Data(^client(i)) {
If $Data(^client(i))=10 {
Write !," Name: No Data"
}
Else {
Write !," Name: " ,^client(i)
}
If $Data(^client(i,1)) {
If $Data(^client(i,1))=10 {
Write !,"Address: No Data"
}
Else {
Write !,"Address: ",$Piece(^client(i,1),"/",1)
Write " , ",$Piece(^client(i,1),"/",2)
Write " , ",$Piece(^client(i,1),"/",3)
}
}
For j=1:1:4 {
If $Data(^client(i,1,j)) {
Write !,"Account: ",$Piece(^client(i,1,j),"/",1)
Write " #: ",$Piece(^client(i,1,j),"/",2)
Write " Balance: ",$Piece(^client(i,1,j),"/",3)
}
}
}
}
Write !,"Finished."
Quit
When executed, this code might produce output similar to the following:
Output how many records: 3
Start with record number: 10
Name: Jane Smith
Address: 74 Hilltop Dr., Beverly, MA 01965
Account: Checking #: 34218 Balance: 876.72
Account: Reserve Credit #: 47821 Balance: 1200.00
Name: Thomas Brown
Address: 46 Huron Ave., Medford, MA 02019
Account: Checking #: 59363 Balance: 205.45
Account: Savings #: 41792 Balance: 1560.80
Account: Reserve Credit #: 64218 Balance: 125.52
Name: Sarah Copley
Address: No Data
Account: Checking #: 30021 Balance: 762.28